不在视图中显示 属性

Do not display property in view

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;
    }
}

此逻辑要么需要在 library/functionality 内,您使用它来在视图内呈现 HTML table,例如:

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 来操作非结构化字典中的模型属性,例如:

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