随机抛出远程验证"字典包含空条目"错误

时间:2018-05-30 01:12:22

标签: c# ajax asp.net-mvc remote-validation

当远程验证尝试检查数据库中是否已存在某个值时,我收到这个超级烦人的错误:

  

参数字典包含参数' gbsNumber'的空条目。非可空类型的System.Int32' for method' System.Web.Mvc.JsonResult DoesGbSNumberExist(Int32)'在' ADVWKSP.Controllers.CRMTItemsController'。可选参数必须是引用类型,可空类型,或者声明为可选参数。   参数名称:参数

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)

间歇性地发生,我无法解决任何模式 - 看起来完全是随机的。

它发生在我的两个字段中,两个字段都映射到视图模型中的整数属性。

它不仅会填满我的错误日志,而且还会破坏表单,以便偶尔提交按钮不起作用,这非常烦人。

控制器

[HttpPost]
public JsonResult DoesGbSNumberExist(int gbsNumber)
{
    using (var db = new ADVWKSPEntities())
    {
        return Json(!db.CRMTItems.Any(i => i.GbsNumber == gbsNumber));
    }
}

视图模型

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; }
}

查看

@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>
}

2 个答案:

答案 0 :(得分:0)

我将参数类型更改为int?并且因为没有看到错误,所以希望这已经解决,但我们会看到。

更新控制器:

[HttpPost]
public JsonResult DoesGbSNumberExist(int? gbsNumber)
{
    using (var db = new ADVWKSPEntities())
    {
        return (gbsNumber == null) ? Json(false) : Json(!db.CRMTItems.Any(i => i.GbsNumber == gbsNumber));
    }
}

答案 1 :(得分:0)

您的视图模型将整数值定义为nullable int int?。如果int包含值,那么nullable int只能与int进行比较。

你的专栏:

return Json(!db.CRMTItems.Any(i => i.GbsNumber == gbsNumber));

应该测试null:

return Json(!db.CRMTItems.Any(i => (i.GbsNumber ?? 0) == gbsNumber));

将零替换为GbsNumber不包含的值。