MVChttp://forums.asp.net//1146.aspx/1?MVCDiscussions regarding ASP.NET Model-View-Controller (MVC) Mon, 01 Jan 0001 00:00:00 -050011463513292http://forums.asp.net//p/1492860/3513292.aspx/1?NullReferenceException+when+field+in+error+is+not+a+property+of+ModelNullReferenceException when field in error is not a property of Model <p>I have an MVC application that is validating data and add errors to ModelState if it fails.&nbsp; I have a bunch of checkbox/drop-down pairs on a view where the checkbox indicates whether an item will be displayed on a public web site and, if that's unchecked, the drop-down indicates the reason it won't be displayed.&nbsp; I'm validating like this:</p> <p><pre class="prettyprint">private&nbsp;bool&nbsp;ValidateProcedureStatuses(FormCollection&nbsp;fields) { var&nbsp;procedureStatuses&nbsp;=&nbsp;from&nbsp;k&nbsp;in&nbsp;fields.AllKeys where&nbsp;k.StartsWith(&quot;ProcedureStatus&quot;) let&nbsp;dropDownName&nbsp;=&nbsp;k.Replace(&quot;Status&quot;,&nbsp;&quot;Reason&quot;) select&nbsp;new { CheckBoxName&nbsp;=&nbsp;k, DropDownName&nbsp;=&nbsp;dropDownName, Published&nbsp;=&nbsp;fields[k].StartsWith(&quot;true&quot;), Reason&nbsp;=&nbsp;fields[dropDownName] }; foreach&nbsp;(var&nbsp;procedureStatus&nbsp;in&nbsp;procedureStatuses) { if&nbsp;(!procedureStatus.Published&nbsp;&amp;&amp;&nbsp;string.IsNullOrEmpty(procedureStatus.Reason)) { this.ModelState.AddModelError(procedureStatus.DropDownName,&nbsp;&quot;A&nbsp;reason&nbsp;must&nbsp;be&nbsp;provided&nbsp;for&nbsp;unpublishing&nbsp;a&nbsp;procedure.&quot;); } } return&nbsp;this.ModelState.IsValid; } </pre></p><p> I'm then trying to display that error like so:</p><p><br></p><pre class="prettyprint">&lt;% object htmlAttributes; if (Model.Published) { htmlAttributes = new { disabled = "disabled", onchange = "syncChildDropDowns(this, 'Procedure', 'Facility');" + "syncChildDropDowns(this, 'Procedure', 'Doctor')" }; } else { htmlAttributes = new { onchange = "syncChildDropDowns(this, 'Procedure', 'Facility');" + "syncChildDropDowns(this, 'Procedure', 'Doctor')" }; } Response.Write(Html.DropDownList("ProcedureReason_" + controlSuffix, Model.Reasons, string.Empty, htmlAttributes)); %&gt; &lt;%= Html.ValidationMessage("ProcedureReason_" + controlSuffix, "*")%&gt; </pre><p>Now, if I don't add the error to ModelState all is well.&nbsp; If I add the error to ModelState with a different name all is well.&nbsp; Using the code above though, a NullReferenceException is thrown when Html.DropDown is called, seemingly when it's trying to determine whether to use a style that indicates an error.&nbsp; Here's the call stack:</p><pre class="prettyprint">[NullReferenceException: Object reference not set to an instance of an object.] System.Web.Mvc.HtmlHelper.GetModelStateValue(String key, Type destinationType) +60 System.Web.Mvc.Html.SelectExtensions.SelectInternal(HtmlHelper htmlHelper, String optionLabel, String name, IEnumerable`1 selectList, Boolean allowMultiple, IDictionary`2 htmlAttributes) +129 System.Web.Mvc.Html.SelectExtensions.DropDownList(HtmlHelper htmlHelper, String name, IEnumerable`1 selectList, String optionLabel, Object htmlAttributes) +66 ASP.views_shared_procedurestatusrowusercontrol_ascx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\SVN Source\Waiting_Times_On_The_Web\SI.WToW.Admin\Views\Shared\ProcedureStatusRowUserControl.ascx:73 System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +256 System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +19 System.Web.UI.Control.Render(HtmlTextWriter writer) +10 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99 System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +134 System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +19 System.Web.UI.Page.Render(HtmlTextWriter writer) +29 System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +59 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99 System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1266 </pre></p> <p>I've got Framework debugging on and I've traced execution as far as the GetModelStateValue method but I can't really see what's happening in there because it says that nothing can be evaluated because the code is optimised.</p> <p>My theory is that it has something to do with control names that don't correspond to a model property name.&nbsp; To test this, I made some adjustments to some other code that was successfully showing validation errors against a drop-down list.&nbsp; The view was for creating an Area Patient Access Coordinator and the drop-down listed Area Health Services.&nbsp; The control was named AreaID, which was the common field, and it worked fine.&nbsp; I changed the name of the control to &quot;AreaIDx&quot; and assigned the list of Areas to ViewData[&quot;AreaIDx&quot;] and the view still displayed correctly.&nbsp; When I tried to save without selecting an Area though, the error was added to ModelState state and then I got the very same NullReferenceException when I tried to redisplay the view.</p> <p>If anyone knows what I'm doing wrong or a workaround for this issue, your advioce would be gratefully accepted.<br> </p> 2009-11-15T04:41:57-05:003513453http://forums.asp.net//p/1492860/3513453.aspx/1?Re+NullReferenceException+when+field+in+error+is+not+a+property+of+ModelRe: NullReferenceException when field in error is not a property of Model <p>I searched before posting but apparently not very well.&nbsp; After posting I refined my serahc and found some useful information.&nbsp; For the moment I'm using this code as a workaround:</p> <p><pre class="prettyprint">this.ModelState.AddModelError(procedureStatus.DropDownName,&nbsp;&quot;A&nbsp;reason&nbsp;must&nbsp;be&nbsp;provided&nbsp;for&nbsp;unpublishing&nbsp;a&nbsp;procedure.&quot;); //&nbsp;This&nbsp;is&nbsp;required&nbsp;to&nbsp;avoid&nbsp;a&nbsp;NullReferenceException&nbsp;when&nbsp;binding&nbsp;the&nbsp;control. this.ModelState.SetModelValue(procedureStatus.DropDownName,&nbsp;new&nbsp;ValueProviderResult(string.Empty,&nbsp;string.Empty,&nbsp;null)); </pre>That seems like a bit of a hack though, so I'm planning to do some reading on custom model binders.&nbsp; Any constructive comments are still welcome.<br> </p> 2009-11-15T07:35:17-05:003514292http://forums.asp.net//p/1492860/3514292.aspx/1?Re+NullReferenceException+when+field+in+error+is+not+a+property+of+ModelRe: NullReferenceException when field in error is not a property of Model <p>Known bug in MVC 1, fixed in MVC 2.<br> </p> 2009-11-16T01:37:17-05:00