从web api返回不带属性的JsonResult

本文关键字:属性 JsonResult web api 返回 | 更新日期: 2023-09-27 18:18:54

我有一个Web API控制器,从那里我从一个动作返回一个JSON对象。

我是这样做的:

public ActionResult GetAllNotificationSettings()
{
    var result = new List<ListItems>();
    // Filling the list with data here...
    // Then I return the list
    return new JsonResult { Data = result };
}

但是通过这种方式,JsonResult对象(包括其Data属性)被序列化为JSON。操作返回的最终JSON是这样的

{
    "ContentEncoding": null,
    "ContentType": null,
    "Data": {
        "ListItems": [
            {
                "ListId": 2,
                "Name": "John Doe"
            },
            {
                "ListId": 3,
                "Name": "Jane Doe"
            },
        ]
    },
    "JsonRequestBehavior": 1,
    "MaxJsonLength": null,
    "RecursionLimit": null
}

我不能序列化这个JSON字符串,因为JsonResult对象添加了各种其他属性。我只对ListItems感兴趣,别的都不感兴趣。但它会自动添加:ContentType, MaxJsonLength等…

现在这对我不起作用,因为JSON字符串中的所有其他属性…

var myList = JsonConvert.DeserializeObject<List<ListItems>>(jsonString);

是否有一种方法从动作发送JSON对象,使它不会添加我不需要的所有属性?

从web api返回不带属性的JsonResult

作为一个使用过ASP的人。. NET API大约3年,我建议返回HttpResponseMessage代替。不要使用ActionResult或IEnumerable!

ActionResult是坏的,因为正如你所发现的。

Return IEnumerable<>是不好的,因为您可能希望稍后扩展它并添加一些头等。

使用JsonResult是不好的,因为你应该允许你的服务是可扩展的,并支持其他响应格式,以防将来;如果你真的想限制它,你可以使用动作属性,而不是在动作主体中。

public HttpResponseMessage GetAllNotificationSettings()
{
    var result = new List<ListItems>();
    // Filling the list with data here...
    // Then I return the list
    return Request.CreateResponse(HttpStatusCode.OK, result);
}

在我的测试中,我通常使用下面的帮助方法从HttpResponseMessage中提取对象:

 public class ResponseResultExtractor
    {
        public T Extract<T>(HttpResponseMessage response)
        {
            return response.Content.ReadAsAsync<T>().Result;
        }
    }
var actual = ResponseResultExtractor.Extract<List<ListItems>>(response);

通过这种方式,您实现了以下目标:

  • 你的动作也可以返回错误消息和状态码,如404未找到,所以在上面的方式你可以很容易地处理它。
  • 你的动作不仅限于JSON,还支持JSON,这取决于客户端的请求偏好和Formatter中的设置。

看这个:http://www.asp.net/web-api/overview/formats-and-model-binding/content-negotiation

当使用WebAPI时,你应该只返回Object而不是特别返回Json,因为API将根据请求返回Json或XML。

我不知道为什么你的WebAPI返回一个ActionResult,但我会改变代码类似的东西;

public IEnumerable<ListItems> GetAllNotificationSettings()
{
    var result = new List<ListItems>();
    // Filling the list with data here...
    // Then I return the list
    return result;
}

如果你从一些AJAX代码中调用它,这将产生JSON。

p。S WebAPI应该是RESTful的,所以你的控制器应该被称为ListItemController,你的方法应该被称为Get。但那是另一天的事了。

我有一个类似的问题(不同之处在于我想返回一个对象,已经转换为json字符串和我的控制器得到返回一个IHttpActionResult)

我是这样解决的。首先,我声明了一个实用程序类

public class RawJsonActionResult : IHttpActionResult
{
    private readonly string _jsonString;
    public RawJsonActionResult(string jsonString)
    {
        _jsonString = jsonString;
    }
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var content = new StringContent(_jsonString);
        content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
        return Task.FromResult(response);
    }
}

这个类可以在你的控制器中使用。下面是一个简单的例子

public IHttpActionResult Get()
{
    var jsonString = "{'"id'":1,'"name'":'"a small object'" }";
    return new RawJsonActionResult(jsonString);
}
return JsonConvert.SerializeObject(images.ToList(), Formatting.None, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.None, ReferenceLoopHandling = ReferenceLoopHandling.Ignore });

using Newtonsoft.Json;