1

I have a domain object Owner. This has some data annotations which will be used in the web api post method to validate.

public class Owner
{
    [Required(ErrorMessage ="Please select a title")]
    public string Title { get; set; }

    [Required(ErrorMessage = "First name is required")]
    [MaxLength(100, ErrorMessage ="Too long")]
    public string Firstname { get; set; }

    [Required(ErrorMessage = "Last name is required")]
    public string Lastname { get; set; }
    public string PostalAddressStreet { get; set; }
    public string PostalAddressSuburb { get; set; }
    public string PostalAddressState { get; set; }

}

Now i need to send this object's validation rules (defined in data annotations) to the front end in a get request. I was looking at this question which explains how to do this in MVC. But couldnt get it to working in a web api Get method. This is what i tried.

    [HttpGet]
    [Route("GetOwnerDefinition")]
    public string GetPetOwnerDefinition()
    {
        Owner owner = new Owner();
        System.Web.Http.Metadata.Providers.DataAnnotationsModelMetadataProvider metaProvider = new System.Web.Http.Metadata.Providers.DataAnnotationsModelMetadataProvider();
        var metaData = metaProvider.GetMetadataForProperty(null, typeof(Owner), "Firstname");
        var validationRules = metaData.GetValidators(GlobalConfiguration.Configuration.Services.GetModelValidatorProviders());
        foreach(System.Web.Http.Validation.Validators.DataAnnotationsModelValidator modelValidator in validationRules)
        {
           //need help here
        }

At the end of the day i need to generate a JSON definition as below.

{"Firstname": "John", 
  "ValidationRules":[{"data-val-required":"This field is required.", "data-val-length-max":100}]}
Community
  • 1
  • 1
RasikaSam
  • 5,363
  • 6
  • 28
  • 36

1 Answers1

0

Not sure whether it is the best way, this is what i have done. I have created a new instance of MVC context inside a web api method.

var mvcContext = new System.Web.Mvc.ControllerContext();

See the code below.

 public Dictionary<string, string> GetValidationDefinition(object container, Type type)
    {
        var modelMetaData = System.Web.Mvc.ModelMetadataProviders.Current.GetMetadataForProperties(container, type);
        var mvcContext = new System.Web.Mvc.ControllerContext();
        var validationAttributes = new Dictionary<string, string>();
        foreach (var metaDataForProperty in modelMetaData)
        {
            var validationRulesForProperty = metaDataForProperty.GetValidators(mvcContext).SelectMany(v => v.GetClientValidationRules());
            foreach (System.Web.Mvc.ModelClientValidationRule rule in validationRulesForProperty)
            {
                string key = metaDataForProperty.PropertyName + "-" + rule.ValidationType;
                validationAttributes.Add(key, System.Web.HttpUtility.HtmlEncode(rule.ErrorMessage ?? string.Empty));
                key = key + "-";
                foreach (KeyValuePair<string, object> pair in rule.ValidationParameters)
                {
                    validationAttributes.Add(key + pair.Key, System.Web.HttpUtility.HtmlAttributeEncode(pair.Value != null ? Convert.ToString(pair.Value, System.Globalization.CultureInfo.InvariantCulture) : string.Empty));
                }
            }

        }
        return validationAttributes;
    }
RasikaSam
  • 5,363
  • 6
  • 28
  • 36