ServiceStack中是否有MVC [HiddenInput(DisplayValue = false)]的等效项?

我不希望在视图中显示特定的模型属性。
我创建了自己的HTML帮助程序扩展方法,以显示基于System.ComponentModel.DisplayNameAttribute的所有属性值,并希望使用属性来阻止其显示。

这是视图:

@inherits ViewPage<GetCustomersubscriptionsResponse>

@{
    ViewBag.Title = string.Format("History >  subscriptions > Customer {0}", Model.CustomerId);
    Layout = "CustomerOfficeUIFabric";
}
<div class="tableContainer">
    @if (Model.subscriptions != null && Model.subscriptions.Count > 0)
    {
        <table class="ms-Table" style="max-width:800px;">
            <thead>
                <tr>
                    @{
                        Type subscriptionType = Model.subscriptions.GetType().GetGenericArguments()[0];
                    }
                    @Html.GenerateHeadings(subscriptionType)
                </tr>
            </thead>
            <tbody>
                @foreach (var subscription in Model.subscriptions)
                {
                    @Html.GenerateRow(subscription)
                }
            </tbody>
        </table>
    }
    else
    {
        <div class="notFound ms-font-m-plus">No records found</div>
    }
</div>


这是扩展方法:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString GenerateRow(this HtmlHelper htmlHelper, object Subscription)
    {
        var sb = new StringBuilder();
        sb.Append("<tr>");
        Type SubscriptionType = Subscription.GetType();
        foreach (PropertyInfo propertyInfo in SubscriptionType.GetProperties())
        {
            object propertyValue = propertyInfo.GetValue(Subscription, null);
            sb.Append($"<td>{propertyValue}</td>");
        }
        sb.Append("</tr>");

        return new MvcHtmlString(sb.ToString());
    }

    public static MvcHtmlString GenerateHeadings(this HtmlHelper htmlHelper, Type modelType)
    {
        var sb = new StringBuilder();

        List<string> displayNames = GetDisplayNames(modelType);

        foreach (var displayName in displayNames)
        {
            sb.Append($"<th>{displayName}</th>");
        }

        return new MvcHtmlString(sb.ToString());
    }

    private static List<string> GetDisplayNames(Type modelType)
    {
        List<string> displayNames = new List<string>();

        PropertyInfo[] props = modelType.GetProperties();
        foreach (PropertyInfo prop in props)
        {
            string displayNameAttributeValue = GetDisplayNameAttributeValue(prop);
            string heading = !string.IsNullOrWhiteSpace(displayNameAttributeValue) ? displayNameAttributeValue : prop.Name;
            displayNames.Add(heading);
        }

        return displayNames;
    }

    private static string GetDisplayNameAttributeValue(PropertyInfo prop)
    {
        object[] attributes = prop.GetCustomAttributes(false);
        if (attributes.Any())
        {
            var displayNameAttributes = attributes.Where(x => x is DisplayNameAttribute);
            if (displayNameAttributes.Any())
            {
                var displayNameAttribute = displayNameAttributes.First() as DisplayNameAttribute;
                return displayNameAttribute.DisplayName;
            }
        }
        return null;
    }
}

最佳答案

这种逻辑要么需要在用于在视图内部呈现HTML表的库/功能内部,例如:

foreach (var propertyInfo in SubscriptionType.GetProperties())
{
    if (propertyInfo.HasAttribute<HiddenInputAttribute>()) continue;
    //...
}


您还可以使用一些Auto Mapping Utils从视图模型中删除不需要的属性。

public class ViewModel
{
    public string Public { get; set; }

    [HiddenInput]
    public string Private { get; set; }
}


您可以使用以下属性创建一个新的视图模型,该模型不包含包含[HiddenInput]属性的属性:

viewModel = new ViewModel().PopulateFromPropertiesWithoutAttribute(
    viewModel, typeof(HiddenInputAttribute));


或者,您可以使用ToObjectDictionary在非结构化字典中操作Model属性,例如:

var map = viewModel.ToObjectDictionary();
viewModel.GetType().GetProperties()
    .Where(x => x.HasAttribute<HiddenInputAttribute>())
    .Each(x => map.Remove(x.Name)); //remove all props with [HiddenInput]

viewModel = map.FromObjectDictionary<ViewModel>(); //new viewModel without removed props

10-06 14:17
查看更多