【问题标题】:Alternatives to MVC Controller Actions returning strings?返回字符串的 MVC 控制器操作的替代方案?
【发布时间】:2015-01-14 20:03:08
【问题描述】:

我一直在关注使用 Knockout 和实体框架的 MVC 项目的在线教程。我也在使用存储库模式。

根据我的发现,教程在执行 HTTP POST 请求时返回字符串,如下所示。我担心的是控制器正在返回字符串 - 它看起来非常初级,我似乎无法找到一个可靠的示例/教程来说明如何执行这些 POST 请求(而不返回视图),以及捕捉数据库异常和 POST 异常。

Javascript:

self.saveNRI = function () {
        var token = $('[name=__RequestVerificationToken]').val();
        var headers = {};
        headers["__RequestVerificationToken"] = token;
        $.ajax({
            type: "POST",
            url: '/nris/Create',
            headers: headers,
            dataType: 'json',
            data: ko.toJSON(self.nri),
            contentType: 'application/json',
            success: function (result) { },
            error: function (err) {
                if (err.responseText == "Success") {
                    window.location.href = '/nris/Index/';
                }
                if (err.responseText == "Failed") {
                    alert("save failed");
                }
            }
        });
    }

控制器:

[HttpPost]
public string Create(DTO incomingModel)
{  
    if (ModelState.IsValid){
        try
        {
            _nriRepository.Insert(incomingModel);                    
        }
        catch (Exception ex)
        {
            return "Failed";
        }         
    }
    return "Success";
}

存储库:

public async void Insert(DTO n)
{
    //Insert code removed for brevity
        await _context.SaveChangesAsync();
}

【问题讨论】:

  • 查看以下帖子,了解如何处理 AJAX 调用中的异常:stackoverflow.com/questions/4707755/…
  • @chickenricekid 很久没有收到你的关注了。您能否评论答案是否可以改进,或接受其中之一?谢谢。
  • @gadr90 道歉 - 我已经安排了几次商务旅行,所以我没有机会完全实施您的回答。然而,这似乎是我正在寻找的答案,而且不管它仍然是有价值的信息。我会继续接受你的回答。再次感谢!
  • 谢谢 :) 请在您尝试后更新我们

标签: c# ajax asp.net-mvc-4 knockout.js


【解决方案1】:

使用良好的旧常规 HTTP Status Codes 来传达 API 上的操作结果可能是一个好主意®。

创建资源时传达成功的适当代码是201。通常,响应正文将包含新创建资源的 ID 或 URL。

10.2.2 201 创建

请求已完成并导致新资源 创建的。新创建的资源可以被 URI(s) 引用 在响应的实体中返回,带有最具体的 URI Location 头域给出的资源。响应应该 包括一个包含资源特征列表的实体和 用户或用户代理可以从中选择最多的位置 合适的。实体格式由给出的媒体类型指定 Content-Type 标头字段。源服务器必须创建 返回 201 状态码之前的资源。如果动作不能 立即执行,服务器应该响应 202(接受) 而是回应。

不过,您也可以使用更通用的状态码200 来表示成功:

10.2.1 200 正常

请求成功。随响应返回的信息 取决于请求中使用的方法,例如:

GET 一个对应于请求资源的实体被发送到 回应;

HEAD 请求资源对应的实体头字段 在没有任何消息正文的响应中发送;

POST 描述或包含动作结果的实体;

TRACE 包含最终收到的请求消息的实体 服务器。

要传达故障,您可能会使用4xx5xx 范围内的代码。

4xx 表示失败发生在客户端。例如,客户端没有发送创建资源所需的所有属性。通用的400 很方便:

10.4.1 400 错误请求

由于格式错误,服务器无法理解请求 句法。客户端不应该重复请求 修改。

但是,5xx 表示您的服务器在完成请求时遇到了问题。

10.5.4 503 服务不可用

服务器当前无法处理请求,因为 服务器临时超载或维护。含义是 这是一种暂时的情况,经过一段时间后会得到缓解 延迟。如果已知,延迟的长度可以在一个 重试后标头。如果没有给出 Retry-After,客户端应该 像处理 500 响应一样处理响应。

在客户端,您可以依靠 jQuery.ajax 根据状态码适当地路由您的回调。您应该使用更新的基于 Promise 的 API,而不是成功和错误回调。例如:

var jqxhr = $.ajax( "example.php" )
  .done(function() {
    alert( "success" );
  })
  .fail(function() {
    alert( "error" );
  })
  .always(function() {
    alert( "complete" );
  });

来源:http://api.jquery.com/jquery.ajax/

您可以使用出色的httpstat.us 网络服务来测试响应代码。只需将所需的响应代码附加到 URL,它将返回一个模拟答案。例如成功:http://httpstat.us/200

【讨论】:

  • 谢谢 :) 尽可能遵守标准很重要。没有理由不这样做。
【解决方案2】:

我最喜欢@gadr90 的回答,但我想我还要提一下,您可以直接从 MVC 中的 ActionResult 返回 JSON。

[HttpPost]
public JsonResult Create(DTO incomingModel)
{  
    if (ModelState.IsValid)
    {
        try
        {
            _nriRepository.Insert(incomingModel);                    
        }
        catch (Exception ex)
        {
            var x = new
            {
                status = "Failed",
                message = ex.Message,
            };
            return this.Json(x);
        }         
    }
    var x = new
    {
        status = "Success",
        message = "",
    };
    return this.Json(x);
}

【讨论】:

    猜你喜欢
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    • 2011-08-16
    相关资源
    最近更新 更多