mirror of https://github.com/abpframework/abp.git
committed by
GitHub
5 changed files with 580 additions and 0 deletions
@ -0,0 +1,24 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures; |
||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; |
||||
|
|
||||
|
[HtmlTargetElement("abp-dynamic-text", TagStructure = TagStructure.NormalOrSelfClosing)] |
||||
|
public class AbpDynamicTextTagHelper : AbpTagHelper<AbpDynamicTextTagHelper, AbpDynamicTextTagHelperService> |
||||
|
{ |
||||
|
[HtmlAttributeName("abp-model")] |
||||
|
public ModelExpression Model { get; set; } = default!; |
||||
|
|
||||
|
[HtmlAttributeName("column-size")] |
||||
|
public ColumnSize ColumnSize { get; set; } |
||||
|
|
||||
|
[HtmlAttributeName("label-width")] |
||||
|
public ColumnSize LabelWidth { get; set; } = ColumnSize._4; |
||||
|
|
||||
|
public AbpDynamicTextTagHelper(AbpDynamicTextTagHelperService tagHelperService) |
||||
|
: base(tagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,206 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Text.Encodings.Web; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Rendering; |
||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures; |
||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; |
||||
|
|
||||
|
public class AbpDynamicTextTagHelperService : AbpTagHelperService<AbpDynamicTextTagHelper> |
||||
|
{ |
||||
|
protected HtmlEncoder HtmlEncoder { get; } |
||||
|
protected IServiceProvider ServiceProvider { get; } |
||||
|
protected List<ModelExpression> Models = new(); |
||||
|
|
||||
|
public AbpDynamicTextTagHelperService( |
||||
|
HtmlEncoder htmlEncoder, |
||||
|
IServiceProvider serviceProvider |
||||
|
) |
||||
|
{ |
||||
|
HtmlEncoder = htmlEncoder; |
||||
|
ServiceProvider = serviceProvider; |
||||
|
} |
||||
|
|
||||
|
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
Models = GetModels(context, output); |
||||
|
NormalizeTagMode(context, output); |
||||
|
var childContent = await output.GetChildContentAsync(); |
||||
|
var html = await GetHtmlAsync(context, output); |
||||
|
SetContent(context, output, html, childContent); |
||||
|
SetAttributes(context, output); |
||||
|
} |
||||
|
|
||||
|
protected virtual void NormalizeTagMode(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
output.TagMode = TagMode.StartTagAndEndTag; |
||||
|
output.TagName = "div"; |
||||
|
} |
||||
|
|
||||
|
protected virtual void SetAttributes(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
output.Attributes.AddIfNotContains("class", "abp-dynamic-text"); |
||||
|
} |
||||
|
|
||||
|
protected virtual void SetContent(TagHelperContext context, TagHelperOutput output, string html, TagHelperContent childContent) |
||||
|
{ |
||||
|
var content = childContent.GetContent(); |
||||
|
|
||||
|
if (content.Contains(AbpFormContentPlaceHolder)) |
||||
|
{ |
||||
|
content = content.Replace(AbpFormContentPlaceHolder, html); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
content = html + content; |
||||
|
} |
||||
|
|
||||
|
output.Content.SetHtmlContent(content); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<string> GetHtmlAsync(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
var contentBuilder = new StringBuilder(); |
||||
|
|
||||
|
foreach (var model in Models) |
||||
|
{ |
||||
|
var textTagHelper = GetTextTagHelper(model); |
||||
|
var textHtml = await textTagHelper.RenderAsync(new TagHelperAttributeList(), context, HtmlEncoder, "div", TagMode.StartTagAndEndTag); |
||||
|
|
||||
|
if (TagHelper.ColumnSize > ColumnSize.Undefined) |
||||
|
{ |
||||
|
var columnSize = $"col-12 col-sm-{(int)TagHelper.ColumnSize}"; |
||||
|
var hidden = IsHidden(model.ModelExplorer) ? " d-none" : ""; |
||||
|
contentBuilder.AppendLine($"<div class=\"{columnSize}{hidden}\">{textHtml}</div>"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
contentBuilder.AppendLine(textHtml); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (TagHelper.ColumnSize > ColumnSize.Undefined) |
||||
|
{ |
||||
|
contentBuilder.Insert(0, "<div class=\"row\">"); |
||||
|
contentBuilder.AppendLine("</div>"); |
||||
|
} |
||||
|
|
||||
|
return contentBuilder.ToString(); |
||||
|
} |
||||
|
|
||||
|
protected virtual AbpTextTagHelper GetTextTagHelper(ModelExpression model) |
||||
|
{ |
||||
|
var textTagHelper = ServiceProvider.GetRequiredService<AbpTextTagHelper>(); |
||||
|
textTagHelper.AspFor = model; |
||||
|
textTagHelper.ViewContext = TagHelper.ViewContext; |
||||
|
|
||||
|
var textAttribute = model.ModelExplorer.GetAttribute<AbpText>(); |
||||
|
if (textAttribute == null) |
||||
|
{ |
||||
|
textTagHelper.LabelWidth = TagHelper.LabelWidth; |
||||
|
return textTagHelper; |
||||
|
} |
||||
|
|
||||
|
textTagHelper.Format = textAttribute.Format; |
||||
|
textTagHelper.LabelWidth = textAttribute.LabelWidth ?? TagHelper.LabelWidth; |
||||
|
textTagHelper.SuppressLabel = textAttribute.SuppressLabel; |
||||
|
|
||||
|
return textTagHelper; |
||||
|
} |
||||
|
|
||||
|
protected bool IsHidden(ModelExplorer model) |
||||
|
{ |
||||
|
return model.GetAttribute<HiddenInputAttribute>() != null; |
||||
|
} |
||||
|
|
||||
|
protected virtual List<ModelExpression> GetModels(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
return TagHelper.Model.ModelExplorer.Properties.Aggregate(new List<ModelExpression>(), ExploreModelsRecursively); |
||||
|
} |
||||
|
|
||||
|
protected virtual List<ModelExpression> ExploreModelsRecursively(List<ModelExpression> list, ModelExplorer model) |
||||
|
{ |
||||
|
if (model.GetAttribute<DynamicFormIgnore>() != null) |
||||
|
{ |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
if (IsCsharpClassOrPrimitive(model.ModelType) || IsListOfCsharpClassOrPrimitive(model.ModelType)) |
||||
|
{ |
||||
|
list.Add(ModelExplorerToModelExpressionConverter(model)); |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
if (IsListOfSelectItem(model.ModelType) || IsFile(model.ModelType)) |
||||
|
{ |
||||
|
list.Add(ModelExplorerToModelExpressionConverter(model)); |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
return model.Properties.Aggregate(list, ExploreModelsRecursively); |
||||
|
} |
||||
|
|
||||
|
protected virtual ModelExpression ModelExplorerToModelExpressionConverter(ModelExplorer explorer) |
||||
|
{ |
||||
|
var temp = explorer; |
||||
|
var propertyName = explorer.Metadata.PropertyName; |
||||
|
|
||||
|
while (temp?.Container?.Metadata?.PropertyName != null) |
||||
|
{ |
||||
|
temp = temp.Container; |
||||
|
propertyName = temp.Metadata.PropertyName + "." + propertyName; |
||||
|
} |
||||
|
|
||||
|
return new ModelExpression(propertyName ?? string.Empty, explorer); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsListOfCsharpClassOrPrimitive(Type type) |
||||
|
{ |
||||
|
var genericType = type.GenericTypeArguments.FirstOrDefault(); |
||||
|
|
||||
|
if (genericType == null || !IsCsharpClassOrPrimitive(genericType)) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return type.ToString().StartsWith("System.Collections.Generic.IEnumerable`") || |
||||
|
type.ToString().StartsWith("System.Collections.Generic.List`"); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsCsharpClassOrPrimitive(Type? type) |
||||
|
{ |
||||
|
if (type == null) return false; |
||||
|
|
||||
|
return type.IsPrimitive || |
||||
|
type.IsValueType || |
||||
|
type == typeof(string) || |
||||
|
type == typeof(Guid) || |
||||
|
type == typeof(DateTime) || |
||||
|
type == typeof(ValueType) || |
||||
|
type == typeof(TimeSpan) || |
||||
|
type == typeof(DateTimeOffset) || |
||||
|
type.IsEnum; |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsListOfSelectItem(Type type) |
||||
|
{ |
||||
|
return type == typeof(List<SelectListItem>) || |
||||
|
type == typeof(IEnumerable<SelectListItem>); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsFile(Type type) |
||||
|
{ |
||||
|
return typeof(IFormFile).IsAssignableFrom(type) || |
||||
|
typeof(IEnumerable<IFormFile>).IsAssignableFrom(type); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; |
||||
|
|
||||
|
[AttributeUsage(AttributeTargets.Property)] |
||||
|
public class AbpText : Attribute |
||||
|
{ |
||||
|
public ColumnSize? LabelWidth { get; set; } |
||||
|
|
||||
|
public bool SuppressLabel { get; set; } = false; |
||||
|
|
||||
|
public string? Format { get; set; } |
||||
|
|
||||
|
public AbpText() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures; |
||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; |
||||
|
|
||||
|
[HtmlTargetElement("abp-text", TagStructure = TagStructure.NormalOrSelfClosing)] |
||||
|
public class AbpTextTagHelper : AbpTagHelper<AbpTextTagHelper, AbpTextTagHelperService> |
||||
|
{ |
||||
|
[HtmlAttributeName("asp-for")] |
||||
|
public ModelExpression AspFor { get; set; } = default!; |
||||
|
|
||||
|
[HtmlAttributeName("label")] |
||||
|
public string? Label { get; set; } |
||||
|
|
||||
|
[HtmlAttributeName("label-width")] |
||||
|
public ColumnSize? LabelWidth { get; set; } |
||||
|
|
||||
|
[HtmlAttributeName("suppress-label")] |
||||
|
public bool SuppressLabel { get; set; } = false; |
||||
|
|
||||
|
[HtmlAttributeName("format")] |
||||
|
public string? Format { get; set; } |
||||
|
|
||||
|
public AbpTextTagHelper(AbpTextTagHelperService tagHelperService) |
||||
|
: base(tagHelperService) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,302 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
using System.Text.Encodings.Web; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Extensions; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid; |
||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; |
||||
|
|
||||
|
public class AbpTextTagHelperService : AbpTagHelperService<AbpTextTagHelper> |
||||
|
{ |
||||
|
protected HtmlEncoder HtmlEncoder { get; } |
||||
|
private readonly IAbpTagHelperLocalizer _tagHelperLocalizer; |
||||
|
protected readonly IAbpEnumLocalizer _abpEnumLocalizer; |
||||
|
protected readonly IStringLocalizerFactory _stringLocalizerFactory; |
||||
|
private readonly ColumnSize DefaultLabelWidth = ColumnSize._4; |
||||
|
|
||||
|
public AbpTextTagHelperService( |
||||
|
HtmlEncoder htmlEncoder, |
||||
|
IAbpTagHelperLocalizer tagHelperLocalizer, |
||||
|
IAbpEnumLocalizer abpEnumLocalizer, |
||||
|
IStringLocalizerFactory stringLocalizerFactory) |
||||
|
{ |
||||
|
HtmlEncoder = htmlEncoder; |
||||
|
_tagHelperLocalizer = tagHelperLocalizer; |
||||
|
_abpEnumLocalizer = abpEnumLocalizer; |
||||
|
_stringLocalizerFactory = stringLocalizerFactory; |
||||
|
} |
||||
|
|
||||
|
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
var childContent = await output.GetChildContentAsync(); |
||||
|
|
||||
|
NormalizeTagMode(context, output); |
||||
|
SetAttributes(context, output); |
||||
|
|
||||
|
var html = GetHtml(context, output); |
||||
|
SetContent(context, output, html, childContent); |
||||
|
} |
||||
|
|
||||
|
protected virtual void NormalizeTagMode(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
output.TagMode = TagMode.StartTagAndEndTag; |
||||
|
output.TagName = "div"; |
||||
|
} |
||||
|
|
||||
|
protected virtual void SetAttributes(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
var cssClass = "mb-3"; |
||||
|
output.Attributes.AddIfNotContains("class", cssClass); |
||||
|
} |
||||
|
|
||||
|
protected virtual void SetContent(TagHelperContext context, TagHelperOutput output, string html, TagHelperContent childContent) |
||||
|
{ |
||||
|
var content = childContent.GetContent(); |
||||
|
|
||||
|
if (!string.IsNullOrEmpty(content)) |
||||
|
{ |
||||
|
content = html + content; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
content = html; |
||||
|
} |
||||
|
|
||||
|
output.Content.SetHtmlContent(content); |
||||
|
} |
||||
|
|
||||
|
protected virtual string GetHtml(TagHelperContext context, TagHelperOutput output) |
||||
|
{ |
||||
|
var label = GetLabel(); |
||||
|
var text = GetText(); |
||||
|
var fieldId = GetFieldId(); |
||||
|
var value = TagHelper.AspFor.Model; |
||||
|
|
||||
|
var contentBuilder = new StringBuilder(); |
||||
|
var hidden = IsHidden() ? " d-none" : ""; |
||||
|
contentBuilder.AppendLine($"<div class=\"row{hidden}\">"); |
||||
|
|
||||
|
if (!TagHelper.SuppressLabel) |
||||
|
{ |
||||
|
var width = TagHelper.LabelWidth ?? |
||||
|
TagHelper.AspFor.ModelExplorer.GetAttribute<AbpText>()?.LabelWidth ?? |
||||
|
DefaultLabelWidth; |
||||
|
var labelWidth = $"col-{(int)width}"; |
||||
|
contentBuilder.AppendLine($"<div class=\"{labelWidth}\">"); |
||||
|
contentBuilder.AppendLine(label); |
||||
|
contentBuilder.AppendLine("</div>"); |
||||
|
} |
||||
|
|
||||
|
contentBuilder.AppendLine($"<div class=\"col\" id=\"{fieldId}\" data-value=\"{HtmlEncoder.Encode(value?.ToString() ?? string.Empty)}\">"); |
||||
|
contentBuilder.AppendLine(text); |
||||
|
contentBuilder.AppendLine("</div>"); |
||||
|
|
||||
|
contentBuilder.AppendLine("</div>"); |
||||
|
|
||||
|
return contentBuilder.ToString(); |
||||
|
} |
||||
|
|
||||
|
protected virtual string GetFieldId() |
||||
|
{ |
||||
|
return TagHelper.AspFor.Name |
||||
|
.Replace(".", "_") |
||||
|
.Replace("[", "_") |
||||
|
.Replace("]", "_"); |
||||
|
} |
||||
|
|
||||
|
protected virtual string GetLabel() |
||||
|
{ |
||||
|
var label = TagHelper.Label ?? |
||||
|
TagHelper.AspFor.Metadata.DisplayName ?? |
||||
|
TagHelper.AspFor.Metadata.PropertyName ?? |
||||
|
TagHelper.AspFor.Name; |
||||
|
|
||||
|
return $"<strong>{HtmlEncoder.Encode(label)}</strong>"; |
||||
|
} |
||||
|
|
||||
|
protected virtual string GetText() |
||||
|
{ |
||||
|
if (IsEnum()) |
||||
|
{ |
||||
|
return EnumText(); |
||||
|
} |
||||
|
if (IsDate()) |
||||
|
{ |
||||
|
return DateText(); |
||||
|
} |
||||
|
if (IsBoolean()) |
||||
|
{ |
||||
|
return BooleanText(); |
||||
|
} |
||||
|
if (IsFile()) |
||||
|
{ |
||||
|
return FileText(); |
||||
|
} |
||||
|
if (IsCollection()) |
||||
|
{ |
||||
|
return CollectionText(); |
||||
|
} |
||||
|
|
||||
|
return DefaultText(); |
||||
|
} |
||||
|
|
||||
|
protected virtual string DefaultText() |
||||
|
{ |
||||
|
var value = TagHelper.AspFor.Model; |
||||
|
if (value == null || string.IsNullOrWhiteSpace(value.ToString())) |
||||
|
{ |
||||
|
return "<span class=\"text-muted\">-</span>"; |
||||
|
} |
||||
|
return StringFormat(HtmlEncoder.Encode(value.ToString()!)); |
||||
|
} |
||||
|
|
||||
|
protected virtual string StringFormat(string? value) |
||||
|
{ |
||||
|
var format = GetFormatString(); |
||||
|
if (format.IsNullOrEmpty() || value.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
return value ?? string.Empty; |
||||
|
} |
||||
|
return string.Format(format, value); |
||||
|
} |
||||
|
|
||||
|
private string GetFormatString() |
||||
|
{ |
||||
|
return TagHelper.Format ?? TagHelper.AspFor.ModelExplorer.GetAttribute<AbpText>()?.Format ?? string.Empty; |
||||
|
} |
||||
|
|
||||
|
protected virtual string EnumText() |
||||
|
{ |
||||
|
var value = TagHelper.AspFor.Model; |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return DefaultText(); |
||||
|
} |
||||
|
|
||||
|
var modelType = value.GetType(); |
||||
|
var enumType = modelType.IsEnum ? modelType : Nullable.GetUnderlyingType(modelType); |
||||
|
var containerLocalizer = _tagHelperLocalizer.GetLocalizerOrNull(TagHelper.AspFor.ModelExplorer.Container.ModelType.Assembly); |
||||
|
var localizedMemberName = value == null ? "-" : _abpEnumLocalizer.GetString(enumType!, (int)value, |
||||
|
new[] |
||||
|
{ |
||||
|
containerLocalizer, |
||||
|
_stringLocalizerFactory.CreateDefaultOrNull() |
||||
|
}!); |
||||
|
return StringFormat(HtmlEncoder.Encode(localizedMemberName ?? string.Empty)); |
||||
|
} |
||||
|
|
||||
|
protected virtual string DateText() |
||||
|
{ |
||||
|
var value = TagHelper.AspFor.Model; |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return DefaultText(); |
||||
|
} |
||||
|
|
||||
|
var format = GetFormatString(); |
||||
|
if (value is DateTime dateTime) |
||||
|
{ |
||||
|
return dateTime.ToString(format); |
||||
|
} |
||||
|
|
||||
|
if (value is DateTimeOffset dateTimeOffset) |
||||
|
{ |
||||
|
return dateTimeOffset.ToString(format); |
||||
|
} |
||||
|
|
||||
|
return StringFormat(value.ToString()); |
||||
|
} |
||||
|
|
||||
|
protected virtual string BooleanText() |
||||
|
{ |
||||
|
var value = TagHelper.AspFor.Model; |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return DefaultText(); |
||||
|
} |
||||
|
|
||||
|
if (value is bool boolValue) |
||||
|
{ |
||||
|
return boolValue |
||||
|
? "<span class=\"fa fa-check\"></span>" |
||||
|
: "<span class=\"fa fa-times\"></span>"; |
||||
|
} |
||||
|
|
||||
|
return StringFormat(value.ToString()); |
||||
|
} |
||||
|
|
||||
|
protected virtual string FileText() |
||||
|
{ |
||||
|
return "<span class=\"text-info\"><i class=\"bi bi-file\"></i></span>"; |
||||
|
} |
||||
|
|
||||
|
protected virtual string CollectionText() |
||||
|
{ |
||||
|
var value = TagHelper.AspFor.Model; |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return DefaultText(); |
||||
|
} |
||||
|
|
||||
|
//todo Consider supporting collection render.
|
||||
|
if (value is System.Collections.IEnumerable enumerable) |
||||
|
{ |
||||
|
var count = 0; |
||||
|
foreach (var item in enumerable) |
||||
|
{ |
||||
|
count++; |
||||
|
} |
||||
|
|
||||
|
return count.ToString(); |
||||
|
} |
||||
|
|
||||
|
return StringFormat(value.ToString()); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsHidden() |
||||
|
{ |
||||
|
return TagHelper.AspFor.ModelExplorer.GetAttribute<HiddenInputAttribute>() != null; |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsEnum() |
||||
|
{ |
||||
|
return TagHelper.AspFor.ModelExplorer.Metadata.IsEnum; |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsDate() |
||||
|
{ |
||||
|
var modelType = TagHelper.AspFor.Metadata.ModelType; |
||||
|
return modelType == typeof(DateTime) || |
||||
|
modelType == typeof(DateTime?) || |
||||
|
modelType == typeof(DateTimeOffset) || |
||||
|
modelType == typeof(DateTimeOffset?); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsBoolean() |
||||
|
{ |
||||
|
var modelType = TagHelper.AspFor.Metadata.ModelType; |
||||
|
return modelType == typeof(bool) || modelType == typeof(bool?); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsFile() |
||||
|
{ |
||||
|
var modelType = TagHelper.AspFor.Metadata.ModelType; |
||||
|
return typeof(IFormFile).IsAssignableFrom(modelType) || |
||||
|
typeof(IEnumerable<IFormFile>).IsAssignableFrom(modelType); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsCollection() |
||||
|
{ |
||||
|
var modelType = TagHelper.AspFor.Metadata.ModelType; |
||||
|
return typeof(System.Collections.IEnumerable).IsAssignableFrom(modelType) && |
||||
|
modelType != typeof(string); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue