locked
Validation of model in side model RRS feed

  • Question

  • User-1310000735 posted

    Hello Everyone,

    I have recently started working on ASP.NET with MVC 2 framework, and I am facing following difficulty in validating my data,

    Scenario:

    In my application the view (ASPX) is divided into tabs (jQuery) and each tab's content is ViewUserControl (ASCX). The main model for the view has collection of sub models for individual tabs. I use RenderPartial method to render view user control.


                <div id="divPage1" class="tabs">
                    <% Html.RenderPartial("Tab1", Model.Tabs["Tab1"]); %>
                </div>
    

    And the user control (Tab1.ascx) refers the specific model for it,

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NDTMS.Models.Tab1Model>" %>
    <table width="100%" align="left" style="caption-side: top" class="details">
        <tr>
            <td>
                <%= Html.LabelFor(m => m.FirstName) %>
            </td>
            <td>
                 <%= Html.TextBoxFor(m => m.FirstName) %>
    
               <%= Html.ValidationMessageFor(m => m.FirstName) %>
    
     	</td>
        </tr>
        <tr>
            <td>
                <%= Html.LabelFor(m => m.LastName) %>
            </td>
            <td>
                 <%= Html.TextBoxFor(m => m.LastName) %>
    
               <%= Html.ValidationMessageFor(m => m.LastName) %>
    
     	</td>
        </tr>
    </table>
    
    
    

    Now if in my Tab1Model if I put following validation


            [DisplayName("First Name:")]
            [Required(ErrorMessage="Please enter first name.")]
            public string FirstName { get; set; }
    
            [DisplayName("Last Name:")]
            [Required(ErrorMessage="Please enter last name.")]
            public string LastName { get; set; }



    In the controller ModelState.IsValid is always indicates TRUE. How do I override the validation behavior such that it as well looks the items in the collection member (which holds sub models) as well.


    Thanks & Regards,

    Mukesh

                 <%= Html.ValidationMessage("FirstName") %>

    Tuesday, October 12, 2010 1:48 AM

Answers

  • User-1620313041 posted

    The top level IsValid property should reflect all errors! However, if you don't pass to the partial view the dictionary with all errors errors are not displayed properly in the partial view.

    For this purpose you have to use this overload of the RenderPartial:

    RenderPartial(HtmlHelper, String, ViewDataDictionary)

    Where the data dictionary is built as follows:

     ViewDataDictionary<TItem> dataDictionary = new ViewDataDictionary<TItem>(Item.Value);
                dataDictionary.TemplateInfo.HtmlFieldPrefix = BasicHtmlHelper.AddField(prefix, "$.Item.Value");
                BasicHtmlHelper.CopyRelevantErrors(dataDictionary.ModelState, htmlHelper.ViewData.ModelState, dataDictionary.TemplateInfo.HtmlFieldPrefix);

     ViewDataDictionary<YourSubModelType> dataDictionary = new ViewDataDictionary<YourSubModelType>(YourSubModel);

     dataDictionary.TemplateInfo.HtmlFieldPrefix = PrefixFromPrincipalModel;

     CopyRelevantErrors(dataDictionary.ModelState, Html.ViewData.ModelState, dataDictionary.TemplateInfo.HtmlFieldPrefix);


    The Copy Relevant errors copy in the error dictionary of the partial vie only the relevant errors, i.e. only the ones with the right prefix;

    its implemntation is something like:

    void CopyRelevantErrors(ModelStateDictionary destination, ModelStateDictionary origin, string prefix)

            {

                foreach (KeyValuePair<string, ModelState> pair in origin)

                {

                    if (pair.Key.StartsWith(prefix)) destination.Add(pair);

                }

           }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 12, 2010 3:55 AM