使用Web API返回匿名类型


74

使用MVC时,返回即席Json很容易。

return Json(new { Message = "Hello"});

我正在使用新的Web API寻找此功能。

public HttpResponseMessage<object> Test()
{    
   return new HttpResponseMessage<object>(new { Message = "Hello" }, HttpStatusCode.OK);
}

由于DataContractJsonSerializer无法处理匿名类型,因此引发了异常。

我有这个替换此JsonNetFormatter基于Json.Net。如果我使用这行得通

 public object Test()
 {
    return new { Message = "Hello" };
 }

但如果我不返回HttpResponseMessage,我看不到使用Web API的意义,那么最好还是坚持使用香草MVC。如果我尝试使用:

public HttpResponseMessage<object> Test()
{
   return new HttpResponseMessage<object>(new { Message = "Hello" }, HttpStatusCode.OK);
}

它序列化整个HttpResponseMessage

谁能引导我找到一种解决方案,在其中可以返回匿名类型HttpResponseMessage

Answers:


85

这在Beta版本中不起作用,但在最新版本(从http://aspnetwebstack.codeplex.com构建)中有效,因此它很可能是RC的方式。你可以做

public HttpResponseMessage Get()
{
    return this.Request.CreateResponse(
        HttpStatusCode.OK,
        new { Message = "Hello", Value = 123 });
}

1
在当前版本中似乎并非如此。执行上述操作时,我收到HTTP 500。
CodeMonkeyKing 2012年

在4.0 RTM中对我来说工作正常。
Snixtor

16
重要说明,只有默认的json序列化程序才能处理匿名对象的序列化。默认的xml序列化程序将出错,因此请确保是否返回客户端知道在标题中发送accept:application / json的匿名对象。像Chrome这样的浏览器也倾向于默认情况下也请求xml,因此请注意
。– Despertar

17

这个答案可能来得有点晚,但是截止到今天WebApi 2已经出炉了,现在您可以轻松地做自己想做的事情,您只需要做:

public object Message()
{
    return new { Message = "hello" };
}

并沿着管道将其序列化到xmljson根据客户的喜好(Accept标题)进行序列化。希望这可以帮助任何在此问题上绊脚石的人


@doker您正在使用什么版本的WebApi,我刚刚使用VS 2015和WebApi2从控制器粘贴了该代码
Luiso

5.2.3和我最后删除了xml格式化程序,因为大多数返回的对象无论如何都不会序列化为xml。
doker

@doker在您的情况下,那么当您尝试执行我建议的操作时会发生什么?你得到Exception吗?
Luiso

9

在Web API 2中,您可以使用新的IHttpActionResult(它代替HttpResponseMessage),然后返回一个简单的Json对象:(类似于MVC)

public IHttpActionResult GetJson()
    {
       return Json(new { Message = "Hello"});
    }

4
对我来说最好的答案。我需要一种从Web API Action返回苗条JSON的方法,而不必在不同的位置/程序集中产生其他内容。奇迹般有效!谢谢。
阿列克谢·马特维耶夫

7

您可以为此使用JsonObject:

dynamic json = new JsonObject();
json.Message = "Hello";
json.Value = 123;

return new HttpResponseMessage<JsonObject>(json);

5

您可以使用ExandoObject(添加using System.Dynamic;

[Route("api/message")]
[HttpGet]
public object Message()
{
    dynamic expando = new ExpandoObject();
    expando.message = "Hello";
    expando.message2 = "World";
    return expando;
}

3

您也可以尝试:

var request = new HttpRequestMessage(HttpMethod.Post, "http://leojh.com");
var requestModel = new {User = "User", Password = "Password"};
request.Content = new ObjectContent(typeof(object), requestModel, new JsonMediaTypeFormatter());


2

如果您使用泛型,则应该能够使它起作用,因为它将为您的匿名类型提供一个“类型”。然后,您可以将序列化程序绑定到该序列化程序。

public HttpResponseMessage<T> MakeResponse(T object, HttpStatusCode code)
{
    return new HttpResponseMessage<T>(object, code);
}

如果没有DataContract或者DataMebmer你的类属性,它会依傍序列化的所有公共属性,它应该做你寻找什么。

(直到今天晚些时候,我才有机会进行测试,请告知是否有任何问题。)


0

您可以将动态对象封装在返回对象中,例如

public class GenericResponse : BaseResponse
{
    public dynamic Data { get; set; }
}

然后在WebAPI中;做类似的事情:

[Route("api/MethodReturingDynamicData")]
[HttpPost]
public HttpResponseMessage MethodReturingDynamicData(RequestDTO request)
{
    HttpResponseMessage response;
    try
    {
        GenericResponse result = new GenericResponse();
        dynamic data = new ExpandoObject();
        data.Name = "Subodh";

        result.Data = data;// OR assign any dynamic data here;// 

        response = Request.CreateResponse<dynamic>(HttpStatusCode.OK, result);
    }
    catch (Exception ex)
    {
        ApplicationLogger.LogCompleteException(ex, "GetAllListMetadataForApp", "Post");
        HttpError myCustomError = new HttpError(ex.Message) { { "IsSuccess", false } };
        return Request.CreateErrorResponse(HttpStatusCode.OK, myCustomError);
    }
    return response;
}

0
public IEnumerable<object> GetList()
{
    using (var context = new  DBContext())
    {
        return context.SPersonal.Select(m =>
            new  
            {
                FirstName= m.FirstName ,
                LastName = m.LastName
            }).Take(5).ToList();               
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.