使用Web API返回匿名类型

时间:2012-04-12 12:15:30

标签: c# json asp.net-web-api json.net

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

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

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

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

这会引发异常,因为DataContractJsonSerializer无法处理匿名类型。

我已根据 Json.Net 将此替换为此JsonNetFormatter。 如果我使用

,这是有效的
 public object Test()
 {
    return new { Message = "Hello" };
 }

但如果我没有返回HttpResponseMessage,我没有看到使用Web API的重点,我最好坚持使用vanilla MVC。如果我尝试使用:

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

序列化整个HttpResponseMessage

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

10 个答案:

答案 0 :(得分:79)

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

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

答案 1 :(得分:14)

这个答案可能会有点迟到,但截至今天WebApi 2已经出局,现在你可以更容易地做你想要的事情,你只需要这样做:

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

并沿着管道,它将根据客户端的首选项(xml标题)序列化为jsonAccept。希望这有助于任何人绊倒这个问题

答案 2 :(得分:6)

你可以使用JsonObject:

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

return new HttpResponseMessage<JsonObject>(json);

答案 3 :(得分:5)

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

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

答案 4 :(得分:4)

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

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

答案 5 :(得分:2)

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

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

如果您的课程中没有DataContractDataMebmer属性,那么它将依赖于序列化所有公共属性,这应该完全符合您的要求。

(直到今天晚些时候我才有机会对此进行测试,如果有什么不起作用,请告诉我。)

答案 6 :(得分: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());

答案 7 :(得分:1)

在ASP.NET Web API 2.1中,您可以以更简单的方式执行此操作:

public dynamic Get(int id) 
{
     return new 
     { 
         Id = id,
         Name = "X"
     };
}

您可以在https://www.strathweb.com/2014/02/dynamic-action-return-web-api-2-1/

上详细了解相关信息

答案 8 :(得分: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;
}

答案 9 :(得分: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();               
        }
    }
}