Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to get ModelState key / Model property names to match?
    primarykey
    data
    text
    <p>I have an MVC3 application, I'm using EF4.1 Code First and POCO Classes.</p> <p>My question involves getting rid of hard-coded "PropertyNames" in my POCO Class and also pre-fixing it with the proper values in ModelState so that the validation message appear properly.</p> <p>I have in my POCO class a method that looks like this. You will notice that I am also using the "DataAnnotations.Validator" code to re-use the Data Annotations validation.</p> <pre><code>public class TaxCode : ModelBusinessObjectBase { //... [Required] [DataType(DataType.Date)] [DisplayName("Effective Date")] public DateTime EffectiveDate { get { return _effectiveDate; } set { _effectiveDate = value; } } [Required] [DataType(DataType.Date)] [DisplayName("Expiry Date")] public DateTime ExpiryDate { get { return _expiryDate; } set { _expiryDate = value; } } //... public override IEnumerable&lt;ValidationResult&gt; GetValidationResults() { //---- data annotation validation ---- ValidationContext validationContext = new ValidationContext(this, null, null); IList&lt;ValidationResult&gt; dataAnnotationValidationResults = new List&lt;ValidationResult&gt;(); bool isValid = Validator.TryValidateObject(this, validationContext, dataAnnotationValidationResults, true); foreach (ValidationResult dataAnnotationValidationResult in dataAnnotationValidationResults) yield return new ValidationResult(dataAnnotationValidationResult.ErrorMessage, dataAnnotationValidationResult.MemberNames); //---- custom business rule validation ---- // expiry date must be greater than effective date if (ExpiryDate &lt;= EffectiveDate) { yield return new ValidationResult("Expiry Date must be after Effective Date", new [] {"EffectiveDate", "ExpiryDate"}); } yield break; } </code></pre> <p>In my service layer, I will eventually call something like this:</p> <pre><code> public bool TryValidate(TaxCode domainObject) { if (!domainObject.IsValid) { _validationDictionary.AddValidationResults(domainObject.GetValidationResults()); isValid = false; } return isValid; } </code></pre> <p>And using a "ModelStateWrapper", the code does this:</p> <pre><code> public virtual void AddValidationResults(IEnumerable&lt;ValidationResult&gt; validationResults) { foreach (ValidationResult validationResult in validationResults) { _modelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage); } } </code></pre> <p>My view model is this:</p> <pre><code>public class TaxCodeViewModel : IPersistantBusinessObjectViewModel&lt;TaxCode&gt; { public TaxCodeViewModel() { } public TaxCodeViewModel(TaxCode domainObj) { this.BusinessObject = domainObj; } } </code></pre> <p>And my View looks a bit like this:</p> <pre><code> &lt;%@ Control Language="C#" AutoEventWireup="true" Inherits="System.Web.Mvc.ViewUserControl&lt;TaxCodeViewModel&gt;" %&gt; //... &lt;% using (Html.BeginForm()) {%&gt; &lt;%:Html.ValidationSummary(false, "Unable to save. Please correct the errors and try again.")%&gt; //... &lt;div class="editor-label"&gt; &lt;%:Html.LabelFor(model =&gt; model.BusinessObject.EffectiveDate)%&gt; &lt;/div&gt; &lt;div class="editor-field"&gt; &lt;%: Html.EditorFor(model =&gt; model.BusinessObject.EffectiveDate)%&gt; &lt;%: Html.ValidationMessageFor(model =&gt; model.BusinessObject.EffectiveDate)%&gt; &lt;/div&gt; &lt;br /&gt; &lt;div class="editor-label"&gt; &lt;%: Html.LabelFor(model =&gt; model.BusinessObject.ExpiryDate)%&gt; &lt;/div&gt; &lt;div class="editor-field"&gt; &lt;%: Html.EditorFor(model =&gt; model.BusinessObject.ExpiryDate)%&gt; &lt;%: Html.ValidationMessageFor(model =&gt; model.BusinessObject.ExpiryDate)%&gt; &lt;/div&gt; &lt;br /&gt; //... </code></pre> <p>My Question are: </p> <ol> <li><p>How do I avoid the hardcoded property name strings "Expiry Date"?</p></li> <li><p>Because of the ViewModel, expects the ModelState key to be "BusinessObject.ExpiryDate". How do I, get my properties to match? How do I add a prefix or remove the automatically added prefix?</p></li> <li><p>Notice I currently use validationResult.MemberNames.First()). In my case, I only want one message in the validation summary, but I would like to have BOTH properties highlighted. i.e. only one message for ".validation-summary-errors" but both fields highlighted for ".input-validation-error" and ".field-validation-error" elements in the DOM.</p></li> </ol> <p>Thank you,</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload