Переопределение свойств базовой модели представления в ASP.NET MVC 3 - PullRequest
7 голосов
/ 12 января 2012

У меня есть модель представления, которая используется двумя разными страницами. Модели представлений довольно похожи, за исключением одного свойства: Адрес. Модель представления содержит поля имени и местоположения. Однако метка адреса представления клиента должна иметь вид: Адрес клиента и метка адреса представления сотрудника должна иметь вид: Адрес сотрудника. Они также будут отображать различные сообщения об ошибках.

Вот упрощенная версия того, что я пытаюсь выполнить:

public class BaseLocation
{
  [Display(Name="Your Name")]
  public string Name {get;set;}

  public virtual string Address {get;set;}
}

public class CustomerLocation : BaseLocation
{
  [Display(Name="Customer Address")]
  public override string Address {get;set;}
}

public class EmployeeLocation : BaseLocation
{
  [Display(Name="Employee Address")]
  public override string Address {get;set;}
}

Затем я создал партиал для базового местоположения, вот так:

@model BaseLocation
***ASP.NET MVC Helpers here: labels, text, validation, etc.

Наконец, на страницах «Клиент» и «Сотрудник» я бы назвал частичное и отправил ему подклассный тип.

Customer.cshtml
@model CustomerLocation
@Html.Render("_BaseLocation", Model)


Employee.cshtml
@model EmployeeLocation
@Html.Render("_BaseLocation", Model)

В результате я не вижу атрибутов данных для определенного типа. Так, например, на странице клиента я бы получил метку «Адрес» вместо «Адрес клиента».

Я бы предпочел не создавать два партиала с одинаковыми данными для каждого конкретного типа, просто потому, что одно свойство в модели общего представления должно иметь другую метку и сообщение об ошибке. Какой лучший способ пойти по этому поводу? Спасибо.

1 Ответ

1 голос
/ 12 января 2012

Из-за того, как работает наследование представлений и как определяется модель, параметр, передаваемый во что-то вроде LabelFor и TextBoxFor, использует тип модели, определенный в классе.В вашем случае он всегда будет BaseLocation, поэтому он не переопределяется.

Вам не обязательно создавать партиалы для вашего класса, но вам нужно будет создать два представления: одно для клиента, а другое для сотрудника.Поскольку у вас уже есть два вида, специфичных для каждого типа, вам просто нужно создать другой вид местоположения или объединить базовый вид с его родителем.

Customer.cshtml
@model CustomerLocation
@Html.Render("_CustomerBaseLocation", Model)


Employee.cshtml
@model EmployeeLocation
@Html.Render("_EmployeeBaseLocation", Model)

Я определенно понимаю вашу проблему, поскольку вы хотите изменить только одно представлениеи у вас может быть несколько подобных ситуаций уже с BaseLocation.

Вы могли бы сделать что-то подобное ...

public static IHtmlString LabelTextFor<TModel, TValue>(this HtmlHelper<TModel> html, object model, Expression<Func<TModel, TValue>> expression)
{
    MemberExpression memberExpression = (MemberExpression)expression.Body;
    var propertyName = memberExpression.Member is PropertyInfo ? memberExpression.Member.Name : null;

    //no property name
    if (string.IsNullOrWhiteSpace(propertyName)) return MvcHtmlString.Empty;

    //get display text
    string resolvedLabelText = null;
    var displayattrib = model.GetType().GetProperty(propertyName)
                .GetCustomAttributes(true)
                .SingleOrDefault(f => f is DisplayAttribute) 
                                      as DisplayAttribute;
    if (displayattrib != null) {
        resolvedLabelText = displayattrib.Name;
    }

    if (String.IsNullOrEmpty(resolvedLabelText)) {
        return MvcHtmlString.Empty;
    }

    TagBuilder tag = new TagBuilder("label");
    tag.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName("")));
    tag.SetInnerText(resolvedLabelText);
    return new HtmlString(tag.ToString());
}

Тогда в вашем _BaseLocation.cshtml вы могли бы сделать такой вызов:

@Html.LabelTextFor(Model, m => m.Address)

Написание собственного метода расширения для этого - все, что я могу придумать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...