0

I have got an extension method which I call from within my EditorTemplate (for a string) which sets the Label and the Required metadata on the on the control. (I cannot annotate my models so this is why I am doing this).

 public static void SetMetadata(this ViewUserControl control)
    {
        if (!string.IsNullOrEmpty((string)control.ViewData["labeltext"]))
            control.ViewData.ModelMetadata.DisplayName = (string)control.ViewData["labeltext"];

        if (control.ViewData["required"] != null)
            control.ViewData.ModelMetadata.IsRequired = (bool)control.ViewData["required"];
    }

Has anyone got any ideas why ModelState.IsValid would not be picking up on the fields I have set to Required = true?

kiwiaddo
  • 75
  • 1
  • 5

2 Answers2

3

The problem here is that you are modifying the ModelMetadata on your get request of the page. This information is not persisted when you post to your action (as there is no ViewStateesque mechanism in MVC).

Is the class you attempting to validate marked as partial? If so, you can use the cool MetadataType attribute to decorate the class with validation attributes:

[MetadataType(typeof(JobOpening_Validation))]
public partial class JobOpening
{
     //JobOpening is generated by LinqToSql but I want to validate the Title Property
}

internal class JobOpening_Validation
{
    [Required]
    [StringLength(150, ErrorMessage = "Must be under 150 characters")]
    public string Title { get; set; }
}

Using this "throwaway" (JobOpening_Validation) class we create the same properties we want validated on the "target" (JobOpening) class. Any decorating of the attributes on the "throwaway" class will be copied to "target" class.

If this doesn't work for you, you can create a FilterAttribute and override the OnActionExecuting method and perform the validation of your model in there. You will also be able to update the modelstate accordingly.

Nathan Anderson
  • 6,768
  • 26
  • 29
  • @nathan-anderson Thanks for the feedback. This does sound like a reasonable approach but not quite what I was after. I don't really want to markup the view model as it is a proxy class coming from a webservice. Maybe MVC Extensions - using configuration to modify the metadata will be the way to go. – kiwiaddo Feb 23 '11 at 21:07
  • Would there be any way I can access the metadata that I am setting in the `EditorTemplate` through to `ActionMethod` on Post? – kiwiaddo Feb 23 '11 at 21:10
  • Not without posting the metadata itself and performing some form of interpretation not unlike the `FilterAttribute` option I suggested. – Nathan Anderson Feb 24 '11 at 05:57
0

After experimenting with using MvcExtensions - and failing because is was just too difficult to shoehorn it into my project. I ended finding a brilliant little project called Fluent Validation

It's easy to use and integrates easily with MVC.

kiwiaddo
  • 75
  • 1
  • 5