2010-06-04 1 views
3

У нас есть модель со свойствами, украшенными [Обязательным], который отлично подходит для проверки. Однако мы хотели бы отметить те обязательные поля в представлении со звездочкой (или другим стилем), чтобы обозначить, что они необходимы, прежде чем пользователь вводит какие-либо данные для проверки.Определить разметку для полей [Обязательные] в представлении в ASP.NET MVC 2.0

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

В конечном итоге мы пытаемся предотвратить необходимость изменения кода в двух местах, если впоследствии удалить свойство [Обязательно] из свойства модели.

Большое спасибо

ответ

4

Вы можете создать свое собственное расширение HtmlHelper для этого:

public static string RequiredMarkFor<TModel, TValue>(this HtmlHelper html, Expression<Func<TModel, TValue>> expression) 
{ 
    if(ModelMetadata.FromLambdaExpression(expression, html.ViewData).IsRequired) 
     return "*"; 
    else 
     return string.Empty; 
} 
+0

Я не могу получить это работать.выражение FromLambdaExpression дает ошибку о методе перегрузки ... – Stefanvds

+0

Можете ли вы опубликовать ошибки и свой код (возможно, начать новую тему)? – Gregoire

1

Если вы используете полную форму шаблонных хелперов EditorFor и Displayfor вам нужно настроить свою собственную версию Object.ascx.

Brad Wilson имеет удивительный пост в блоге, который обрисовывает в общих чертах это:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html

Что происходит это свойство требуется копаться на ModelMetadata будет истинным. Внутри Object.ascx:

<%=propertu.IsRequired ? "*" : ""%> 

Если вы не используете шаблонные помощник вам придется написать свой собственный HTML помощник. Как выглядят ваши взгляды?

2

Если вы получаете сообщение об ошибке «недопустимых аргументы» при использовании «ModelMetadata.FromLambdaExpression», убедитесь, что вы указали параметр универсального типа для HtmlHelper. Вот пересмотренный вариант решения Грегуара:

public static string RequiredMarkFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) 
    { 
     if (ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).IsRequired) 
      return "*"; 
     else 
      return string.Empty; 
    } 
3

Проблема с раствором, Грегуар и Faxanadu является то, что «*» отображается всегда, и тогда, когда поле проверяется с помощью обычной проверки, и вы используете «Html .ValidationMessageFor()».

Так что, если вы используете расширение HTML, как это:

@Html.EditorFor(model => model.Email) 
@Html.RequiredFieldFor(model => model.Email) 
@Html.ValidationMessageFor(model => model.Email) 

Вы увидите дублируют * в случае поле имеет ошибки проверки.


Я сделал это модифицированное расширение, основанное на this, которое также проверяет, было ли поле проверено.

private static Type[] RequiredTypes = new Type[] { typeof(CustomRequiredAttribute), typeof(RequiredAttribute) }; 

/// <summary> 
/// Generate a &lt;span class="field-validation-error"&gt;*&lt;&lt; element. 
/// 
/// See http://koenluyten.blogspot.com/2011/06/denote-required-fields-in-aspnet-mvc-3.html 
/// </summary> 
public static MvcHtmlString RequiredFieldFor<TModel, TValue>(this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression, string validationMessage = "*") 
{ 
    // Get the metadata for the model 
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 

    string fieldName = metadata.PropertyName; 

    // Check if the field is required 
    bool isRequired = metadata 
     .ContainerType.GetProperty(fieldName) 
     .GetCustomAttributes(false) 
     .Count(m => RequiredTypes.Contains(m.GetType())) > 0; 

    // Check if the field is validated 
    bool isValidated = html.ViewData.ModelState[fieldName] != null; 

    // If the field is required and not validated; generate span with an asterix 
    if (isRequired && !isValidated) 
    { 
     var span = new TagBuilder("span"); 
     span.AddCssClass("field-validation-error"); 
     span.SetInnerText(validationMessage); 

     return MvcHtmlString.Create(span.ToString(TagRenderMode.Normal)); 
    } 

    return null; 
} 
0

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

Моя цель состоит в том, чтобы все входы, отмеченные данными валин-обязательным атрибутом, а затем установить его метка elementes markeds с атрибутом для

Вот пример кода JQuery:

$('[data-val-required]').each(function() { 
    var $label = $('label[for=' + this.name + ']'); 

    //from here we can manipulate the label element 
    $label.css('font-weight', 'bold'); 
    $label.text($label.text() + ' *'); 
}); 
Смежные вопросы