Una soluzione è quella di implementare il proprio metodo di estensione su HtmlHelper che fa qualcosa di diverso per il comportamento predefinito ValidationMessageFor. Il metodo @ Html.ValidationMessagesFor esempio riportato di seguito verrà concatenare più messaggi di errore che sono stati aggiunti alla ModelState durante lato server convalida (solo).
public static MvcHtmlString ValidationMessagesFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
var propertyName = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).PropertyName;
var modelState = htmlHelper.ViewData.ModelState;
// If we have multiple (server-side) validation errors, collect and present them.
if (modelState.ContainsKey(propertyName) && modelState[propertyName].Errors.Count > 1)
{
var msgs = new StringBuilder();
foreach (ModelError error in modelState[propertyName].Errors)
{
msgs.AppendLine(error.ErrorMessage);
}
// Return standard ValidationMessageFor, overriding the message with our concatenated list of messages.
return htmlHelper.ValidationMessageFor(expression, msgs.ToString(), htmlAttributes as IDictionary<string, object> ?? htmlAttributes);
}
// Revert to default behaviour.
return htmlHelper.ValidationMessageFor(expression, null, htmlAttributes as IDictionary<string, object> ?? htmlAttributes);
}
Questo è utile se si dispone di convalida business personalizzata si sta applicando in una raccolta che appartiene al modello (ad esempio, i totali dei controlli incrociati), o il controllo del modello nel suo complesso.
Un esempio di utilizzare questo, in cui una collezione di Order.LineItems vengono convalidati sul lato server:
@using MyHtmlHelperExtensions // namespace containing ValidationMessagesFor
@using (Html.BeginForm())
{
@Html.LabelFor(m => m.LineItems)
<ul>
@Html.EditorFor(m => m.LineItems)
</ul>
@Html.ValidationMessagesFor(m => m.LineItems)
}
fonte
2011-11-23 08:07:27
bella soluzione. Funziona con viste nidificate con viewmodels? ho dovuto aggiungere il seguente: 'var = relativePropertyName ExpressionHelper.GetExpressionText (espressione);' ' var propertyName = String.Format ("{0} {2} {1}", htmlHelper.ViewContext.ViewData.TemplateInfo. HtmlFieldPrefix, relativePropertyName, (String.IsNullOrWhiteSpace (relativePropertyName)? String.Empty: ".")); ' – Fiddles
Il modo più semplice per farlo funzionare con viste nidificate è: propertyName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName (propertyName –
Risposta eccellente, e funziona. Tranne che entrambi i miei errori sono sulla stessa linea. Ho bisogno che ogni messaggio di errore sia sulla propria linea. Con un tag
tra l'esempio – theB3RV