将字段添加到web api返回对象

时间:2016-03-23 15:37:44

标签: json asp.net-mvc asp.net-web-api

在控制器中,我曾经像这样返回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?

2 个答案:

答案 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状态代码并对消息或响应对象执行某些操作。

此模式将阻止您向所有回复添加successmessage属性。它还允许您使用动作过滤器捕获一些常见的验证,例如使用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,如果出现错误,可能会使用正确的故障状态代码,而且应该是可能的。