Не отображать свойство в поле зрения - PullRequest
0 голосов
/ 14 декабря 2018

Есть ли эквивалент MVC [HiddenInput(DisplayValue = false)] в ServiceStack?

Я не хочу, чтобы конкретное свойство модели отображалось в виде.Я создал свой собственный метод расширения 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;
    }
}

1 Ответ

0 голосов
/ 15 декабря 2018

Эта логика должна быть либо внутри библиотеки / функции, которую вы используете для рендеринга HTML-таблицы внутри представления, например:

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

Есть также некоторые утилиты автоматического сопоставления вы можете использовать для удаления ненужные свойства из модели представления.

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
...