0

I am trying to get validation to work in ASP.NET MVC 2, but without much success.

I have a complex class containing a large number of fields. (Don't ask - this is oneo f those real-world situations best practices can't touch) This would normally be my Model and is a LINQ-to-SQL generated class.

Because this is generated code, I have created a MetaData class as per http://davidhayden.com/blog/dave/archive/2009/08/10/AspNetMvc20BuddyClassesMetadataType.aspx.

public class ConsultantRegistrationMetadata
{

    [DisplayName("Title")]
    [Required(ErrorMessage = "Title is required")]
    [StringLength(10, ErrorMessage = "Title cannot contain more than 10 characters")]       
    string Title { get; set; }

    [Required(ErrorMessage = "Forename(s) is required")]
    [StringLength(128, ErrorMessage = "Forename(s) cannot contain more than 128 characters")]
    [DisplayName("Forename(s)")]
    string Forenames { get; set; }
       // ...

I've attached this to the partial class of my generated class:

[MetadataType(typeof(ConsultantRegistrationMetadata))]
public partial class ConsultantRegistration
{
   // ...

Because my form is complex, it has a number of dependencies, such as SelectLists, etc. which I have encapsulated in a ViewModel pattern - and included the ConsultantRegistration model as a property:

public class ConsultantRegistrationFormViewModel
{
    public Data.ConsultantRegistration ConsultantRegistration { get; private set; }

    public SelectList Titles { get; private set; }
    public SelectList Countries { get; private set; }
 // ...

So it is essentially ViewModel=>Model

My View then has:

    <p>
        <%: Html.LabelFor(model => model.ConsultantRegistration.Title) %>
        <%: Html.DropDownListFor(model => model.ConsultantRegistration.Title, Model.Titles,"(select a Title)") %>
        <%: Html.ValidationMessage("Title","*") %>
    </p>

    <p>
        <%: Html.LabelFor(model => model.ConsultantRegistration.Forenames) %>
        <%: Html.TextBoxFor(model => model.ConsultantRegistration.Forenames) %>
        <%: Html.ValidationMessageFor(model=>model.ConsultantRegistration.Forenames) %>
    </p>

The problem is, the validation attributes on the metadata class are having no effect. I tried doing it via an Interface, but also no effect. I'm beginning to think that the reason is because I am encapsulating my model within a ViewModel.

My Controller (Create Action) is as follows:

[HttpPost]
        public ActionResult Create(Data.ConsultantRegistration consultantRegistration)
        {
            if (ModelState.IsValid) // this is always true - which is wrong!!
            {
                try
                {

                    consultantRegistration = ConsultantRegistrationRepository.SaveConsultantRegistration(consultantRegistration);

                    return RedirectToAction("Edit", new { id = consultantRegistration.ID, sectionIndex = 2 });
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("CreateException",ex);
                }
            }

            return View(new ConsultantRegistrationFormViewModel(consultantRegistration));

        }

As outlined in the comment, the ModelState.IsValid property always returns true, despite fields with the Validaiton annotations not being valid. (Forenames being a key example).

Am I missing something obvious - considering I am an MVC newbie? I'm after the mechanism demoed by Jon Galloway at http://www.asp.net/learn/mvc-videos/video-10082.aspx.

(Am aware t is similar to ASP.NET MVC Model/ViewModel Validation but that post seems to talk about xVal. I have no idea what that is and suspect it is for MVC 1)

1 Answer 1

1

I've been trying to make this work for some time. Based on the code you've included I think you're doing it right.

I think the problem is with the javascript validators that are supposed to be "emitted" into the page. There are several other questions here on SO relating to this problem and I don't think any of them offer a solution that works across the board. As far as I can tell, MVC2 RC is still broken.

UPDATE:

If it works when you apply the attributes to the emitted code, take a look at this:

When using Data Annotations with MVC, Pro and Cons of using an interface vs. a MetadataType

It may be the MetadataType attribute that's not working. Does it work if you try an interface as suggested in the question above?

Also, another question: MetadataType and client validation in ASP.NET MVC 2

That one is fairly recent and confirms that this is still a bug in MVC2.

Sign up to request clarification or add additional context in comments.

3 Comments

Ah, great. It works (not JS, but half is as good) if I apply the attributes directly on the LINQ-to-SQL generated code. Obviously not a solution.
Thanks Dave. I'll have to wait till Wednesday to have a look as I'm off work for a bit. Noted, though.
I did try the interface method and it does sort of work. Problem being that the MVC part couldn't create the type from the interface (obviously) and a few other issues I can't remember (sorry) right now. I chose to drop this as it didn't seem pure enough. The MetaDataType method defo doesn't work on encapsulated properties. My data structure (& prescribed requirements) is such that I can't break a 52-field table down into better components which would lend to better validation. Hence having to hand-code for now. Thanks for your help, anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.