I am getting this super annoying error when remote validation tries to check if a value already exists in the db:
The parameters dictionary contains a null entry for parameter 'gbsNumber' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.JsonResult DoesGbSNumberExist(Int32)' in 'ADVWKSP.Controllers.CRMTItemsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters
at System.Web.Mvc.ActionDescriptor.ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary`2 parameters, MethodInfo methodInfo)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
It happens intermittently, and I can't work out any kind of pattern - it seems totally random.
It is happening on 2 of my fields, both of which map to integer properties in the view model.
Not only is it going to fill up my error log, but it breaks the form so that occasionally the submit button doesn't work, which is so annoying.
Controller
[HttpPost]
public JsonResult DoesGbSNumberExist(int gbsNumber)
{
using (var db = new ADVWKSPEntities())
{
return Json(!db.CRMTItems.Any(i => i.GbsNumber == gbsNumber));
}
}
ViewModel
public class CRMTItemViewModel
{
public int Id { get; set; }
[Required]
[Display(Name = "Project Title")]
[Remote("DoesProjectTitleExist", "CRMTItems", HttpMethod = "POST",
ErrorMessage = "Workspace for that project title already exists.")]
public string ProjectTitle { get; set; }
[Required]
[Display(Name = "Project Stage")]
public ProjectStage? ProjectStage { get; set; }
[Required]
[Display(Name = "CRMT Number")]
[Remote("DoesCrmtNumberExist", "CRMTItems", HttpMethod = "POST",
ErrorMessage = "Workspace for that CRMT number already exists.")]
public int? CRMTNumber { get; set; }
[Required]
[Display(Name = "GBS Number")]
[Remote("DoesGbSNumberExist", "CRMTItems", HttpMethod = "POST",
ErrorMessage = "Workspace for that GBS project number already exists.")]
public int? GbSNumber { get; set; }
public bool Confidential { get; set; }
[Required]
[Display(Name = "Project Managers")]
public IEnumerable<string> SelectedTags { get; set; }
}
View
@using (Ajax.BeginForm("Create", "CRMTItems", new AjaxOptions
{
HttpMethod = "Post",
UpdateTargetId = "divToUpdate",
OnBegin = "submitBegin",
OnSuccess = "submitSuccess",
OnFailure = "submitFailure",
OnComplete = "submitComplete"
}, new { @ID = "AjaxForm" }))
{
<div class="form-horizontal">
<h4>New Project Workspace Form</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.ProjectTitle, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ProjectTitle, new { htmlAttributes = new { @class = "form-control"} })
@Html.ValidationMessageFor(model => model.ProjectTitle, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ProjectStage, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EnumDropDownListFor(model => model.ProjectStage, new { @class = "form-control"})
@Html.ValidationMessageFor(model => model.ProjectStage, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CRMTNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CRMTNumber, new { htmlAttributes = new { @class = "form-control"} })
@Html.ValidationMessageFor(model => model.CRMTNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.GbSNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.GbSNumber, new { htmlAttributes = new { @class = "form-control"} })
@Html.ValidationMessageFor(model => model.GbSNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Confidential, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.CheckBoxFor(model => model.Confidential, new { @class = "form-control", @style = "height:17px;" })
@Html.ValidationMessageFor(model => model.Confidential, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => Model.SelectedTags, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.HiddenFor(m => m.Id)
@Html.ListBoxFor(m => m.SelectedTags, new SelectList(users, "UserName", "DisplayName"), new { @class = "teamSelecter", name = "states[]", multiple = "multiple", style = "display:none; width:100%;"})
@Html.ValidationMessageFor(model => model.SelectedTags, "", new { @class = "text-danger" })
<p id="pmWarning" class="text-danger" hidden>Please select one or more project managers</p>
</div>
</div>
<br />
<button id="formSubmit" class="btn btn-default btn-lg pull-right" type="submit" value="submit">Submit</button>
<div class="loader pull-right" hidden></div>
</div>
}
I changed the parameter type to int?
and haven't seen the error since, so hopefully that is resolved but we will see.
Update controller:
[HttpPost]
public JsonResult DoesGbSNumberExist(int? gbsNumber)
{
using (var db = new ADVWKSPEntities())
{
return (gbsNumber == null) ? Json(false) : Json(!db.CRMTItems.Any(i => i.GbsNumber == gbsNumber));
}
}