2012-04-12 146 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