2012-04-12 181 views
57

使用MVC时,返回adhoc Json非常简单。使用Web API返回匿名类型

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

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

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

由于DataContractJsonSerializer无法处理匿名类型,所以会引发异常。

我用JsonNetFormatter替换了这个JsonNetFormatter根据Json.Net。 这工作,如果我使用

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

,但我没有看到使用Web API,如果我不返回HttpResponseMessage点,我会过得更好香草MVC坚持。如果我尝试和使用:

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

它序列化整个HttpResponseMessage

任何人都可以指导我解决方案,我可以在HttpResponseMessage内返回匿名类型吗?

回答

67

这不会在Beta版本的工作,但它在最新的不位(从http://aspnetwebstack.codeplex.com构建),所以它可能是RC的方式。你可以做

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

这似乎并不是在当前版本中的情况。执行类似上述操作时,我收到一个HTTP 500。 – CodeMonkeyKing 2012-09-26 23:14:17

+0

在4.0 RTM中适合我。 – Snixtor 2012-11-09 06:45:23

+14

一个重要的注意事项,只有默认的json序列化器可以处理匿名对象的序列化。默认的xml序列化程序将会出错,因此请确保您返回客户端知道要发送的匿名对象接受:application/json in header。浏览器的Chrome浏览器倾向于默认要求xml,所以只是一个抬头.. – Despertar 2013-02-15 02:21:48

1

如果您使用泛型,您应该能够使其工作,因为它会为您提供匿名类型的“类型”。然后你可以绑定序列化程序。

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

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

(我不会有机会测试,直到今天晚些时候,让我知道,如果事情不工作。)

3

可以使用的JSONObject此:

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

return new HttpResponseMessage<JsonObject>(json); 
2

你也可以尝试:

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()); 
3

你可以使用一个ExandoObject(添加using System.Dynamic;

[Route("api/message")] 
[HttpGet] 
public object Message() 
{ 
    dynamic expando = new ExpandoObject(); 
    expando.message = "Hello"; 
    expando.message2 = "World"; 
    return expando; 
} 
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; 
} 
10

这个答案可能会有点晚了,但今天的WebApi 2已经出来,现在更容易做你想要什么,你就只需要做:

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

和沿着流水线,它将根据或客户的喜好(Accept标题)被序列化为xmljson。希望这可以帮助任何人绊倒这个问题

+0

我不适合我 – doker 2016-06-09 08:52:15

+0

@doker您使用的是什么版本的WebApi,我刚刚使用VS 2015和WebApi2从我的控制器粘贴了该代码 – Luiso 2016-06-09 14:16:32

+0

5.2 .3我最终删除了xml formater,因为大多数返回的对象不会序列化为xml。 – doker 2016-06-10 08:32:37