views:

144

answers:

1

I have a Create view which is passed a ViewModel. The ViewModel contains the following:

namespace MyProject.ViewModels
{
    public class MyObjectCreateView
    {
        public MyObject MyObject { get; set; }
        public List<OtherObject> OtherObjects { get; set; }
    }
}

The objects are generated using Entity Framework. I have a metadata partial class for MyObject:

[MetadataType(typeof(MyObjectMetaData))]
public partial class MyObject
{
    // Validation rules for the MyObject class

    public class MyObjectMetaData
    {
        // Validation rules for MyObjectId
        [DisplayName("MyObject")]
        [Required(ErrorMessage = "Please enter the MyObject ID number.")]
        [DisplayFormat( ApplyFormatInEditMode=true,
                                ConvertEmptyStringToNull=true,
                                HtmlEncode=true)]
        [DataType(DataType.Text)]
        [StringLength(25, ErrorMessage = "Must be under 25 characters.")]
        public object MyObjectId { get; set; }


        // Validation rules for Title
        [Required(ErrorMessage = "Please enter the Title for MyObject.")]
        [DataType(DataType.MultilineText)]
        [StringLength(200, ErrorMessage = "Must be under 200 characters.")]
        [DisplayFormat(ApplyFormatInEditMode = true,
                                ConvertEmptyStringToNull = true,
                                HtmlEncode = true)]
        public object Title { get; set; }

Etc...

My Create view looks like this:

<% Html.EnableClientValidation(); %>

<% using (Html.BeginForm()) {%>

    <%:Html.ValidationSummary(true, "Please fix the following errors:") %>
    <%:Html.EditorFor(model => model.MyObject) %>

    <p>
        <input type="submit" value="Save" />
    </p>

    <% } %>

<div>
    <%:Html.ActionLink("Back to List", "Index") %>
</div>

Finally, the editor for MyObject:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<TxRP.Models.MyObject>" %>
<%--EditorTemplate--%>

<fieldset>
    <div class="editor-label"><%:Html.LabelFor(model => model.MyObjectId)%></div>
    <div class="editor-field">
        <%:Html.TextBoxFor(model => model.MyObjectId)%>
        <%= Html.ValidationMessageFor(model => model.MyObjectId) %>
    </div>           

    <div class="editor-label"><%:Html.LabelFor(model => model.Title)%></div>
    <div class="editor-field">
        <%:Html.TextAreaFor(model => model.Title, new { cols = "80" })%>
        <%= Html.ValidationMessageFor(model => model.Title)%>
    </div>

I have Client validation set, and all the scripts are in the master page:

<script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcJQueryValidation.js" type="text/javascript"></script>
<script src="../../scripts/jquery-1.4.1.min.js" type="text/javascript"></script>  
<script src="../../Scripts/ui/minified/jquery.ui.core.min.js" type="text/javascript"></script>  
<script src="../../Scripts/ui/minified/jquery.ui.datepicker.min.js" type="text/javascript"></script>  

<link href="../../Content/Site.css" type="text/css" rel="Stylesheet" />  
<link href="../../Content/jquery-ui/sunny/jquery-ui-1.8.4.custom.css" type="text/css" rel="Stylesheet" /> 

When I click the Save button, no validation happens. No client validation, no server validation (it doesn't even seem to hit the Post create action at all!); it just bombs on the entity framework model with a ConstraintException, because Title is null. Argh!

I'm sure it's just some silly thing I've overlooked, but I know I had it working at one point, and now it's not, and I've been trying to figure this out all week. Thanks for any help, I'm developing a callous on my forehead from banging it on my desk!

EDIT: Here is the controller:

public ActionResult Create(MyObject myObject)
{
    if (!ModelState.IsValid) 
    {
        //ModelState is invalid
        return View(new MyObject());
    }
    try
    {
        //TODO: Save MyObject

        return RedirectToAction("Index");
    }
    catch
    {
        //Invalid - redisplay with errors

        return View(new MyObject());
    }           
}

and the exception stack trace:

at System.Data.Objects.DataClasses.StructuralObject.SetValidValue(String value, Boolean isNullable)
   at MyProject.Models.MyObject.set_Title(String value) in C:\CodeProjects\MyProject\Models\MyProjectDB.Designer.cs:line 4941
A: 

Couple of remarks about your code:

  1. You say that you have a view model but what I see looks more like an Entity Framework autogenerated model. Properties of type object, ... arghhh...
  2. You include both MicrosoftMvcValidation.js and MicrosoftMvcJQueryValidation.js but those are mutually exclusive. You have to decide whether you will do client validation using MS Technology or jquery validate plugin.

You didn't show any code of the controller actions nor the exact exception stack trace you are getting. You are saying that the Post action is not hit but you get an exception. Where do you get this exception?

Darin Dimitrov
Hmm...I had some thoughts about that viewmodel being somewhat unnecessary - can you elaborate on that?I'll update the question with the controller action and the exception stack. The exception occurs in the EDMX file generated by EF.
morganpdx
Also yeah, realized I had done that and took out the Ajax scripts. Now it's just jquery-1.4.1.min.js, jquery.validate.min.js, microsoftmvcjqueryvalidation.js
morganpdx
I found this feedback posted to microsoft. http://connect.microsoft.com/VisualStudio/feedback/details/571297/ado-net-entity-framework-out-of-the-box-validation-on-an-non-nullable-property-field-does-not-work . This is the exact result I'm getting, although I am using a viewmodel to pass data into the view. One note, the reason for the viewmodel is eventually I'll add the ability to add OtherObjects to the List<OtherObject> in the create view in a future release.
morganpdx
Finally found the solution! http://stackoverflow.com/questions/3129080/server-side-validation-of-a-required-string-property-in-mvc2-entity-framework-4-d .
morganpdx