从web api返回没有其属性的JsonResult

Viv*_*ndi 19 c# asp.net-mvc json.net asp.net-mvc-4 asp.net-web-api

我有一个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 };
}
Run Code Online (Sandbox Code Playgroud)

但是这样,包含其Data属性的JsonResult对象被序列化为JSON.所以我通过动作返回的最终JSON如下所示:

{
    "ContentEncoding": null,
    "ContentType": null,
    "Data": {
        "ListItems": [
            {
                "ListId": 2,
                "Name": "John Doe"
            },
            {
                "ListId": 3,
                "Name": "Jane Doe"
            },
        ]
    },
    "JsonRequestBehavior": 1,
    "MaxJsonLength": null,
    "RecursionLimit": null
}
Run Code Online (Sandbox Code Playgroud)

我无法序列化此JSON字符串,因为该JsonResult对象向其添加了各种其他属性.我只对其感兴趣ListItems,别的什么.但它自动添加的东西,如:ContentType,MaxJsonLength等...

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

var myList = JsonConvert.DeserializeObject<List<ListItems>>(jsonString);
Run Code Online (Sandbox Code Playgroud)

有没有办法从动作发送JSON对象,以便它不会添加我不需要的所有属性?

Dyn*_*mic 46

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

ActionResult很糟糕,因为你已经发现了.

返回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);
}
Run Code Online (Sandbox Code Playgroud)

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

 public class ResponseResultExtractor
    {
        public T Extract<T>(HttpResponseMessage response)
        {
            return response.Content.ReadAsAsync<T>().Result;
        }
    }

var actual = ResponseResultExtractor.Extract<List<ListItems>>(response);
Run Code Online (Sandbox Code Playgroud)

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

  • 您的操作也可以返回错误消息和状态代码,如404找不到,所以以上述方式您可以轻松处理它.
  • 您的操作不仅限于JSON,还支持JSON,具体取决于客户端的请求首选项和Formatter中的设置.

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


Tim*_*mes 12

使用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;
}
Run Code Online (Sandbox Code Playgroud)

如果您从某些AJAX代码调用它,将产生JSON.

PS WebAPI应该是RESTful的,所以应该调用你的Controller并调用ListItemController你的方法Get.但那是另一天.


Joe*_*ing 9

我有一个类似的问题(差异是我想返回一个已经转换为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后可以在您的控制器中使用此类.这是一个简单的例子

public IHttpActionResult Get()
{
    var jsonString = "{\"id\":1,\"name\":\"a small object\" }";
    return new RawJsonActionResult(jsonString);
}
Run Code Online (Sandbox Code Playgroud)