如何在 MVC Web API post 方法中将 ModelState 错误返回给 Kendo 网格? [英] How to return ModelState errors to Kendo grid in MVC Web API post method?

查看:17
本文介绍了如何在 MVC Web API post 方法中将 ModelState 错误返回给 Kendo 网格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I haven't been able to find an example of Kendo + MVC Web API where post/update methods return validation errors. It doesn't look like there is a Kendo extension that could make the following code work.

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

因为 ModelState 在这个上下文中是 System.Web.Http.ModelBinding.ModelStateDictionary 和 Kendo 扩展需要 System.Web.Mvc.ModelStateDictionary.

becaue ModelState in this context is System.Web.Http.ModelBinding.ModelStateDictionary and Kendo extensions expect System.Web.Mvc.ModelStateDictionary.

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

So what is the best way to return ModelState errors from Web API to Kendo?

推荐答案

这对我们来说效果很好,尽管我们从未看到 ModelState 错误并且通常会忽略那部分...

This works fantastic for us, though we never see ModelState errors and usually omit that part...

@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"))
    )
)

控制器

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

更新的控制器

我们发现这个流程工作得更好一些,它向 Elmah 添加了错误日志(通用示例)...

UPDATED Controller

We have found this flow to work a bit better and it adds error logging to Elmah (generic example)...

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

常见的 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:
";
        $.each(e.errors, function (key, value) {
            if ('errors' in value) {
                $.each(value.errors, function () {
                    message += this + "
";
                });
            }
        });
        showAlertWindow(message);
    }
}

奖金

我们的 BaseModel 也有一个 ErrorMessage 参数,我们将其他类型的错误放入该参数中,用于检查页面加载是否应该为其他任何内容打开相同的警报窗口.

Bonus

Our BaseModel also has an ErrorMessage parameter that we put other types of errors into that checks on page load if the same alert window should be opened for anything else.

$(document).ready(function () {
    if ("@Model.ErrorMessage" != "") {
        showAlertWindow("@Model.ErrorMessage");
    }
});

当抛出错误时,这有一个非常好的演示 - 防止我们的内部用户惊慌失措.我希望这对您有所帮助.

This has a very nice presentation when an error is thrown - keeps our in-house users from freaking out. I hope this helps you out.

这篇关于如何在 MVC Web API post 方法中将 ModelState 错误返回给 Kendo 网格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆