views:

254

answers:

3

Ok, I have a ViewModel that looks like this:

public class UserLogin
{
    [Required]
    public string EmailAddress { get; set; }

    [Required]
    public string Password { get; set; }
}

My controller looks like this:

[HttpPost]
public ActionResult LogIn(UserLogin model)
{
    if (!ModelState.IsValid)
    {
        // ...
    }
}

My view looks like this:

<% Html.BeginForm("Join", "User", FormMethod.Post); %>
    <%= Html.Hidden("ReturnUrl", Request.Url.AbsolutePath) %>

    <%= Html.TextBoxFor(c => c.EmailAddress, new { id = "join-emailaddress", @class = "text", uiHintText = "Email address" })%>
    <%= Html.ValidationMessageFor(c => c.EmailAddress, "*") %>

    <%= Html.PasswordFor(c => c.Password, new { id = "join-password", @class = "text", uiHintText = "Password" })%>
    <%= Html.ValidationMessageFor(c => c.Password, "*")%>

    <%= Html.PasswordFor(c => c.PasswordConfirm, new { id = "join-password-confirm", @class = "text", uiHintText = "Password (repeat)" })%>
    <%= Html.ValidationMessageFor(c => c.PasswordConfirm, "*")%>

    <input type="submit" value="Sign me up!" class="submit" />
<% Html.EndForm(); %>                

If I post the form with nothing entered in any of the fields, I consistently get a value of 'true' for 'ModelState.IsValid'.

Shouldn't it be 'false', since I've marked those fields as 'Required' and not entered any values?

+2  A: 

Have a look at the latest RC for ASP.NET MVC. It includes some fixes for this.

http://haacked.com/archive/2010/02/04/aspnetmvc2-rc2.aspx

Specifically, from the release notes:

Default validation system validates entire model
The default validation system in ASP.NET MVC 1.0 and in previews of ASP.NET MVC 2 prior to RC 2 validated only model properties that were posted to the server. In ASP.NET MVC 2 RC2, the new behavior is that all model properties are validated when the model is validated, regardless of whether a new value was posted.

For more information about this change, see the following posting on Brad Wilson’s blog:

Input Validation vs. Model Validation in ASP.NET MVC
http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html

Robert Harvey
I upgraded to ASP.NET MVC 2 RC 2, but I'm still having exactly the same problem. It doesn't seem like the upgrade has changed a thing.
jonathanconway
I think it's fixed now, but a strange fix... See my comment under @H_Sampat's answer.
jonathanconway
+1  A: 

I had the same problem earlier, but I was using ASP.NET MVC1. However I resolved the problem by adding the following code in Global.asax.vb file.

Sub Application_Start()
    RegisterRoutes(RouteTable.Routes)

    'Added following line
    ModelBinders.Binders.DefaultBinder = New Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder()        
End Sub

You'll need to import Microsoft.Web.Mvc.DataAnnotations.dll. You can get it from http://aspnet.codeplex.com/releases/view/24471

H Sampat
Fixed! I added the following statement to the Application_Start function: ModelBinders.Binders.DefaultBinder = new System.Web.Mvc.DefaultModelBinder();. I wonder why this would have been necessary. Will look into it some more when I get time.
jonathanconway
Ugh.. I was wrong. Ran the project a second time and it went back to giving me a 'true' for 'ModelState.IsValid'... I'll have to double-check all the changes I made and find out why it broke...
jonathanconway
+1  A: 

I figured out the cause of my particular problem.

When using the [Required] attribute on my ViewModel properties, I had specified a resource type and resource name for the error.

Example:

[Required(ErrorMessageResourceName = "FirstNameError", 
          ErrorMessageResourceType = typeof(MyResourceFile))]
public string FirstName { get; set; }

However I'd neglected to make the FirstNameError resource 'public'; it was still marked 'internal', and thus inaccessible.

After setting it public, everything worked and ModelState.IsValid contained a correct value.

I'm amazed that no errors were raised and this failed silently, but now I know why.

(Yes, I should have mentioned from the outset that I was using resources. I mistakenly thought this would be irrelevant but it turned out to be very relevant.)

jonathanconway
Make sure you let Phil Haack know about this, if you think it's a bonafide bug. http://haacked.com/contact.aspx. Would be nice to get it into the final release.
Robert Harvey
Good idea! I've sent a message off to Phil.
jonathanconway