如何在MVC Web API post方法中将ModelState错误返回给Kendo网格?

blu*_*lue 11 c# validation kendo-ui asp.net-web-api

我无法找到一个Kendo + MVC Web API的示例,其中post/update方法返回验证错误.看起来没有Kendo扩展可以使以下代码工作.

public HttpResponseMessage Post([ModelBinder(typeof(Prototype.WebApi.ModelBinders.DataSourceRequestModelBinder))][DataSourceRequest] DataSourceRequest request, User user)
    {
        if (this.ModelState.IsValid)
        {               
           //save               
        }
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, this.ModelState.ToDataSourceResult());            
    }
Run Code Online (Sandbox Code Playgroud)

因此,在此上下文中的ModelState是System.Web.Http.ModelBinding.ModelStateDictionary和Kendo扩展期望System.Web.Mvc.ModelStateDictionary.

那么将ModelState错误从Web API返回到Kendo的最佳方法是什么?

Tre*_*ann 14

这对我们很有用,虽然我们从未看到ModelState错误,并且通常会省略该部分...

剑道网格

@model SysMaintViewModel
@(Html.Kendo().Grid<BuildingModel>()
    .Name("BuildingsGrid")
    .Columns(columns =>
    [Stuff Omitted]
    .DataSource(dataSource => dataSource
        .Ajax()
>>>     .Events(e => e.Error("error_handler"))
        .Model(model =>
        {
            model.Id(m => m.Id);
            model.Field(m => m.ProjectId).DefaultValue(Model.ProjectId);
            model.Field(m => m.IsActive).DefaultValue(true);
        })
        .Create(create => create.Action("CreateBuilding", "SysMaint"))
        .Read(read => read.Action("ReadBuildings", "SysMaint", Model))
        .Update(update => update.Action("UpdateBuilding", "SysMaint"))
        .Destroy(destroy => destroy.Action("DestroyBuilding", "SysMaint"))
    )
)
Run Code Online (Sandbox Code Playgroud)

调节器

[HttpPost]
public JsonResult UpdateBuilding([DataSourceRequest]DataSourceRequest request, BuildingModel modelIn)
{
    var building = new BuildingModel();
    if (ModelState.IsValid)
    {
        try
        {
            building = _presentationService.UpdateBuilding(modelIn);
        }
        catch (Exception e)
        {
            ModelState.AddModelError(string.Empty, e.Message);
        }
    }
    else
    {
        var errMsg = ModelState.Values
            .Where(x => x.Errors.Count >= 1)
            .Aggregate("Model State Errors: ", (current, err) => current + err.Errors.Select(x => x.ErrorMessage));
        ModelState.AddModelError(string.Empty, errMsg);
    }
    var buildings = (new List<BuildingModel> {building}).ToDataSourceResult(request, ModelState);
    return Json(buildings, JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)

更新的控制器

我们发现这个流程工作得更好,它将错误记录添加到Elmah(通用示例)......

[HttpPost]
public JsonResult Update([DataSourceRequest]DataSourceRequest request, MyObjectModel modelIn)
{
    try
    {
        if (ModelState.IsValid)
        {
            var myObject = _presentationService.Update(modelIn, User.Identity.Name);
            var myObjectList = new List<MyObjectModel> { myObject };
            return Json(myObjectList.ToDataSourceResult(request, ModelState), JsonRequestBehavior.AllowGet);
        }
        else
        {
            var myObjectList = new List<MyObjectModel> { modelIn };
            return Json(myObjectList.ToDataSourceResult(request, ModelState), JsonRequestBehavior.AllowGet);
        }
    }
    catch (Exception e)
    {
        Elmah.ErrorSignal.FromCurrentContext().Raise(e);
        ModelState.AddModelError(string.Empty, e.Message);
        var myObjectList = new List<MyObjectModel> { modelIn };
        return Json(myObjectList.ToDataSourceResult(request, ModelState), JsonRequestBehavior.AllowGet);
    }
}
Run Code Online (Sandbox Code Playgroud)

常见的JavaScript和Kendo窗口

@(Html.Kendo().Window()
    .Name("alertWindow")
    .Title("Status Message from Server")
    .Draggable()
    .Resizable()
    .Width(400)
    .Height(200)
    .Modal(true)
    .Visible(false)
)
function showAlertWindow(message) {
    var alertWindow = $('#alertWindow').data('kendoWindow');
    alertWindow.content(message);
    alertWindow.refresh();
    alertWindow.center();
    alertWindow.open();
}
function error_handler(e) {
    if (e.errors) {
        var message = "Errors:\n";
        $.each(e.errors, function (key, value) {
            if ('errors' in value) {
                $.each(value.errors, function () {
                    message += this + "\n";
                });
            }
        });
        showAlertWindow(message);
    }
}
Run Code Online (Sandbox Code Playgroud)

奖金

我们的BaseModel还有一个ErrorMessage参数,如果应该为其他任何东西打开相同的警报窗口,我们会将其他类型的错误放入页面加载的检查中.

$(document).ready(function () {
    if ("@Model.ErrorMessage" != "") {
        showAlertWindow("@Model.ErrorMessage");
    }
});
Run Code Online (Sandbox Code Playgroud)

当出现错误时,这会有一个非常好的演示 - 让我们的内部用户不会惊慌失措.我希望这能够帮到你.