在控制器中,我曾经像这样返回json:
[System.Web.Http.HttpGet]
public JsonResult GetData()
{
return Json(new { success = true, msg = "", result = myObject}, JsonRequestBehavior.AllowGet);
}
由于extjs期望成功消息作为json的一部分,我不得不将其添加到每个响应中,并且对象包含我通常添加到结果中的所有数据。
现在我有网络API。在这里你必须定义一些方法的返回类型作为对象,并基于接受头,结果将是json或xml(我有很多问题,因为IE没有发送这个头,我总是得到xml作为返回 - 但我解决了这个配置格式化程序添加):
public myObject GetData(){
...
return myObject;
}
有效。但是现在没有{success = true,msg =""}作为返回的json的一部分。 如何以与控制器相同的方式添加此项? (没有创建自定义HttpContent类,因为它是丑陋的解决方法)。
最后,是否有任何意义使用web api而不使用mvc控制器 - 旧的方式? 接受标头存在问题,测试更难(我必须模拟ajax调用,而控制器只需调用url),因为看起来更合适的是获得适当的json。 我看到的web api的唯一好处是根据accept标头为客户端提供不同的序列化,但实际上除了json之外不需要获取其他数据(至少我不需要它)。那么,为什么不使用mvc控制器代替web api?
答案 0 :(得分:1)
您可以创建一个类ResultBase
,如下所示
class ResultBase<T> {
public bool success {get;set;}
public string msg {get;set;}
public T result {get;set;}
}
然后更改您的控制器代码,如下所示
public ResultBase<MyObject> GetData(){
...
return new ResultBase<MyObject>{success = true, msg = "", result = myObject};
}
答案 1 :(得分:0)
Web api旨在在发生故障时返回Http状态代码。然后,您可以在响应中包含该消息。您还可以发回here is a list of possible status codes。有更常见的响应原因的内置方法。因此,您的Web Api方法最终会看起来像这样(请参阅下面的代码示例)。现在,调用客户端将知道是否收到状态200(默认为Ok),然后在服务器上正确处理所有内容,否则处理Http状态代码并对消息或响应对象执行某些操作。
此模式将阻止您向所有回复添加success
和message
属性。它还允许您使用动作过滤器捕获一些常见的验证,例如使用Authorize
过滤器属性进行授权检查。
[HttpGet]
public IHttpActionResult GetData()
{
try {
object somethingToReturn;
// do something to populate your result
return Ok(somethingToReturn);
}
catch(SomeDataException someException){
// log or do something
return BadRequest("The object A could not be found with these parameters!");
}
catch(Exception totallyUnexpectedException){
// log or do something
return InternalServerError();
}
}
那么,为什么不使用mvc控制器代替web api?
之前已经问过这个问题,请看这些SO帖子
根据最新评论。下面是一些代码,您可以使用它们动态创建通用响应对象,而无需手动包装所有内容。通过创建一些扩展方法,您可以将响应包装器抽象为一些辅助方法。
public class TestController : ApiController
{
[HttpGet]
public IHttpActionResult Get()
{
var success = false;
try
{
var someResult = new SomeObject() {Name = "igor"};
// do something
if (success)
return this.Ok(new SomeObject() {Name = "igor"}); // sends success
return this.Failure(someResult, "some known error"); // sends failure with partial object (if possible)
}
catch (Exception ex)
{
return this.Failure("Something bad happened"); // sends failure with no object because you could not create it
}
}
}
public static class ApiControllerExtensions
{
public static OkNegotiatedContentResult<ResultWrapper<T>> Ok<T>(this ApiController controller, T content)
{
return new OkNegotiatedContentResult<ResultWrapper<T>>(new ResultWrapper<T>() { Result = content, Success = true, Message = null }, controller);
}
public static OkNegotiatedContentResult<ResultWrapper<T>> Failure<T>(this ApiController controller, T content, string message)
{
return new OkNegotiatedContentResult<ResultWrapper<T>>(new ResultWrapper<T>() { Result = content, Success = false, Message = message }, controller);
}
public static OkNegotiatedContentResult<FailureResult> Failure(this ApiController controller, string message)
{
return new OkNegotiatedContentResult<FailureResult>(new FailureResult() { Success = false, Message = message }, controller);
}
}
public class ResultWrapper<T>
{
public T Result { get; set; }
public string Message { get; set; }
public bool Success { get; set; }
}
public class FailureResult // simple class used strictly for failures (unless you ever have an operation with no result that can succeed then modify the name and reuse)
{
public string Message { get; set; }
public bool Success { get; set; }
}
public class SomeObject
{
public string Name { get; set; }
}
不确定您是否已经尝试过,但我检查了the documentation for extjs。
回调选项
并非每个AJAX请求都成功:有时服务器已关闭,或者您的互联网连接中断,或者发生其他不良事件。 Ext.Ajax允许您为每个案例指定单独的回调
Ext.Ajax.request({
url: 'myUrl',
success: function(response) {
console.log("Spiffing, everything worked");
},
failure: function(response) {
console.log("Curses, something terrible happened");
},
callback: function(options, success, response) {
console.log("It is what it is");
}
});
所以基于这种模式,似乎是我的第一个场景,使用Web API,如果出现错误,可能会使用正确的故障状态代码,而且应该是可能的。