xVal 1.0 not generating the correct xVal.AttachValidator

Posted by bastijn on Stack Overflow See other posts from Stack Overflow or by bastijn
Published on 2010-03-31T21:10:47Z Indexed on 2010/03/31 21:13 UTC
Read the original article Hit count: 586

Filed under:
|
|

I'm currently implementing xVal client-side validation. The server-side validation is working correctly at the moment.

I have referenced xVall.dll (from xVal1.0.zip) in my project as well as the System.ComponentModel.DataAnnotations and System.web.mvc.DataAnnotations from the Data Annotations Model Binder Sample found at http://aspnet.codeplex.com/releases/view/24471. I have modified the method BindProperty in the DataAnnotationsModelBinder class since it returned a nullpointer exception telling me the modelState object was null. Some blogposts described to modify the method and I did according to this SO post.

Next I put the following lines in my global.asax:

protected void Application_Start()
        {
            // kept same and added following line
            RegisterModelBinders(ModelBinders.Binders); // Add this line
        }

        public void RegisterModelBinders(ModelBinderDictionary binders) // Add this whole method
        {
            binders.DefaultBinder = new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
        }

Now, I have made a partial class and a metadata class since I use the entity framework and you cannot create partial declarations as of yet so I have:

 [MetadataType(typeof(PersonMetaData))]
 public partial class Persons {
    // ....
 }
 public class PersonMetaData {

    private const string EmailRegEx = @"^(([^<>()[\]\\.,;:\s@\""]+"
                                        + @"(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@"
                                        + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
                                        + @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+"
                                        + @"[a-zA-Z]{2,}))$";

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

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

    [Required(ErrorMessage="Please fill in your email")]
    [RegularExpression(EmailRegEx,ErrorMessage="Please supply a valid email address")]
    public string Email { get; set; }
}

And in my controller I have the POST edit method which currently still use a FormCollection instead of a Persons object as input. I have to change this later on but due to time constraints and some strange bug this isnt done as of yet :). It shouldnt matter though. Below it is my view.

//
    // POST: /Jobs/Edit/5
    //[CustomAuthorize(Roles = "admin,moderator")]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit([Bind(Exclude = "Id")]FormCollection form) {
        Persons person = this.GetLoggedInPerson();
        person.UpdatedAt = DateTime.Now;               // Update the updated time.

        TryUpdateModel(person, null, null, new string[]{"Id"});
        if (ModelState.IsValid) {
            repository.SaveChanges();
            return RedirectToAction("Index", "ControlPanel");
        }
        return View(person);

    }
    #endregion

My view contains a partial page containing the form. In my edit.aspx I have the following code:

 <div class="content">
        <% Html.RenderPartial("PersonForm", Model); %>
    </div>
 </div>

and in the .ascx partial page:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WerkStageNu.Persons>" %>

<% if (!Model.AddressesReference.IsLoaded) { %> <% Model.AddressesReference.Load(); %> <% } %>

<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>

<% using (Html.BeginForm()) {%>
    <fieldset>
    <legend>General information</legend>
    <table>
        <tr>
            <td><label for="FirstName">FirstName:</label></td><td><%= Html.TextBox("FirstName", Model.FirstName)%><%= Html.ValidationMessage("FirstName", "*")%></td>
        </tr>
        <tr>
            <td><label for="LastName">LastName:</label></td><td><%= Html.TextBox("LastName", Model.LastName)%><%= Html.ValidationMessage("LastName", "*")%></td>
        </tr>
        <tr>
            <td><label for="Email">Email:</label></td><td><%= Html.TextBox("Email", Model.Email)%><%= Html.ValidationMessage("Email", "*")%></td>
        </tr>
        <tr>
            <td><label for="Telephone">Telephone:</label></td><td> <%= Html.TextBox("Telephone", Model.Telephone) %><%= Html.ValidationMessage("Telephone", "*") %></td>
        </tr>
        <tr>
            <td><label for="Fax">Fax:</label></td><td><%= Html.TextBox("Fax", Model.Fax) %><%= Html.ValidationMessage("Fax", "*") %></td>
        </tr>
    </table>

               <%--<p>
                     <label for="GenderID"><%= Html.Encode(Resources.Forms.gender) %>:</label>
                    <%= Html.DropDownList("GenderID", Model.Genders)%>
                </p>   --%>   
    </fieldset>
    <fieldset>
            <legend><%= Html.Encode(Resources.Forms.addressinformation) %></legend>

            <table>
                <tr>
                    <td><label for="Addresses.City"><%= Html.Encode(Resources.Forms.city) %>:</label></td><td><%= Html.TextBox("Addresses.City", Model.Addresses.City)%></td>
                </tr>
                <tr>
                    <td><label for="Addresses.Street"><%= Html.Encode(Resources.Forms.street) %>:</label></td><td><%= Html.TextBox("Addresses.Street", Model.Addresses.Street)%></td>
                </tr>
                <tr>
                    <td><label for="Addresses.StreetNo"><%= Html.Encode(Resources.Forms.streetNumber) %>:</label></td><td><%= Html.TextBox("Addresses.StreetNo", Model.Addresses.StreetNo)%></td>
                </tr>
                <tr>
                    <td><label for="Addresses.Country"><%= Html.Encode(Resources.Forms.county) %>:</label></td><td><%= Html.TextBox("Addresses.Country", Model.Addresses.Country)%></td>
                </tr>
            </table>
    </fieldset>

    <p>
                    <input type="image" src="../../Content/images/save_btn.png" /> 
    </p>
    <%= Html.ClientSideValidation(typeof(WerkStageNu.Persons)) %>

<% } %>

Still nothing really stunning over here. In combination with the edited data annotation dlls this gives me server-side validation working (although i have to manually exclude the "id" property as done in the TryUpdateModel). The strange thing is that it still generates the following script in my View:

xVal.AttachValidator(null, {"Fields":[{"FieldName":"ID","FieldRules":
[{"RuleName":"DataType","RuleParameters":{"Type":"Integer"}}]}]}, {})

While all the found blogposts on this ( 1, 2 ) but all of those are old posts and all say it should be fixed from xVal 0.8 and up.

The last thing I found was this post but I did not really understand. I referenced using Visual Studio -> add reference --> browse -> selected from my bin dir where I stored the external compiled dlls (copied to the bin dir of my project).

Can anyone tell me where the problem originates from?

© Stack Overflow or respective owner

Related posts about asp.net-mvc

Related posts about xval