MetadataType and client validation in ASP.NET MVC 2

前端 未结 3 1871
刺人心
刺人心 2021-01-13 02:31

Inherited properties and MetadataType does not seem to work with client side validation in ASP.NET MVC 2.

The validation of our MetadataTypes work a

相关标签:
3条回答
  • 2021-01-13 03:00

    According to a Microsoft official this is a bug in ASP.NET MVC 2. I was given the link below and although the scenario isn't exactly the same, it seems to be the same problem. As far as I can tell it is related to inhertited properties and DataAnnotations model metadata provider. The link says they will try to fix the issue in ASP.NET MVC 3.

    Asp.net MVC 2 RC2: the client side validation does not work with overridden properties

    0 讨论(0)
  • 2021-01-13 03:00

    Maybe it's too late but this is the way I managed to solve this bug.
    I've created a custom model metadata provider that inherits from DataAnnotationsModelMetadataProvider and override the CreateMetadata method. The problem is that the value in containerType parameter points to the base class instead of pointing to inherited class. Here is the code

    public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata CreateMetadata(
            IEnumerable<Attribute> attributes, 
            Type containerType, 
            Func<object> modelAccessor, 
            Type modelType, 
            string propertyName)
        {
    
            if (modelAccessor != null && containerType != null)
            {                
                FieldInfo container = modelAccessor.Target.GetType().GetField("container");
                if (containerType.IsAssignableFrom(container.FieldType))
                    containerType = container.FieldType;
            }
    
            var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
    
    
    
            return modelMetadata;
        }
    }
    

    And finally we have to register this custom metadata provider in Global.asax at Application_Start

    ModelMetadataProviders.Current = new CustomModelMetadataProvider();
    

    Sorry for my English!

    0 讨论(0)
  • 2021-01-13 03:12

    Are you sure? I've got a ASP.NET MVC 2 site set up as you describe and I have client side validation of both required and regex based attributes that works fine. It doesn't work with my own validators (that derive from ValidationAttribute) at the moment though:

    [MetadataType(typeof(AlbumMetadata))]
    public partial class Album {}
    
    public class AlbumMetadata {
        [Required(ErrorMessage = "You must supply a caption that is at least 3 characters long.")]
        [MinLength(3, ErrorMessage = "The caption must be at least {0} characters long.")]
        [RegularExpression(@".{3,}")]
        public string Caption { get; set; }
    }
    

    (MinLength basically provides a more obvious way to see what's happening in the Regular Expression attribute, which was added for testing)

    I then have the following in my view:

    <script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
    <script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
    
    <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
    <% Html.EnableClientValidation(); %>
    <% using (Html.BeginForm()) {%>
    <fieldset>
        <legend>Album details</legend>
        <div class="form_row">
            <label for="Caption" class="left_label">Album caption:</label>
            <%= Html.TextBox("Caption", Model.Caption, new { @class = "textbox" })%>
            <%= Html.ValidationMessage("Caption", "*") %>
            <div class="cleaner">&nbsp;</div>
        </div>
        <div class="form_row">
            <label for="IsPublic" class="left_label">Is this album public:</label>
            <%= Html.CheckBox("IsPublic", Model.IsPublic) %>
        </div>
        <div class="form_row">
            <input type="submit" value="Save" />
        </div>
    </fieldset>
    <% } %>
    

    Which results in the following being output to the client below the form tags (formatted for clarity):

    <script type="text/javascript">
    //<![CDATA[
    if (!window.mvcClientValidationMetadata)
    { window.mvcClientValidationMetadata = []; }
    window.mvcClientValidationMetadata.push({
        "Fields":[
          {"FieldName":"Caption",
           "ReplaceValidationMessageContents":false,
           "ValidationMessageId":"Caption_validationMessage",
           "ValidationRules":[
             {"ErrorMessage":"You must supply a caption that is at least 3 characters long.",
              "ValidationParameters":{},
              "ValidationType":"required"},
             {"ErrorMessage":"The field Caption must match the regular expression \u0027.{3,}\u0027.",
              "ValidationParameters":{"pattern":".{3,}"},
              "ValidationType":"regularExpression"}]
          }],
          "FormId":"form0","ReplaceValidationSummary":false});
    //]]>
    </script>
    
    0 讨论(0)
提交回复
热议问题