MVC WebApi HttpGet具有复杂的对象

时间:2013-03-25 19:12:40

标签: asp.net asp.net-web-api deserialization json.net

我有一个现有的WebApi动作,我想从HttpPost切换到HttpGet。它目前只需要一个复杂的对象作为参数。

模特:

public class BarRequest
{
    [JsonProperty("catid")]
    public int CategoryId { get; set; }
}

控制器:

public class FooController : ApiController
{
    //[HttpPost]
    [HttpGet]
    [ActionName("bar")]
    public void Bar([FromUri] BarRequest request)
    {
        if (request != null)
        {
            // CategoryId should be 123, not 0
            Debug.WriteLine("Category ID :: {0}", request.CategoryId);
        }
    }
}

现在,当我发送以下请求时,一切都按预期工作。

GET /foo/bar?CategoryId=123

旧的POST请求也按预期工作。

POST /foo/bar {"catid":123}

但现在我需要以下请求才能工作:

GET /foo/bar?catid=123

我该如何做到这一点?

3 个答案:

答案 0 :(得分:11)

感谢您的建议,但唯一对我有用的解决方案如下:

<强>之前:

var data = {
    catid: 123,
    // <snip>
};
var json = JSON.stringify(data);
$.post('/foo/bar', json, callback);
public class FooController : ApiController
{
    [HttpPost, ActionName("bar")]
    public void Bar(BarRequest request)
    {
        // use request.Category to process request
    }
}

<强>后:

var data = {
    catid: 123,
    // <snip>
};
var json = JSON.stringify(data);
$.get('/foo/bar?data=' + encodeURIComponent(json), callback);
public class FooController : ApiController
{
    [HttpGet, ActionName("bar")]
    public void Bar(string data)
    {
        var request = JsonConvert.DeserializeObject<BarRequest>(data);
        // use request.Category to process request
    }
}

这样我就不需要触摸客户端或服务器上的任何模型,验证器等。此外,每个其他解决方案都要求我在服务器端或客户端更改命名约定。

答案 1 :(得分:1)

您可以使用datacontracts和datamember属性来执行此操作:

http://msdn.microsoft.com/en-us/library/ms733127.aspx

[DataContract]
public class BarRequest{  

   [DataMember(Name="catid")]  
    public int CategoryId { get; set; }
}

如果是Post方法

但是使用get方法,这是复杂对象的结构示例:

api/Bar?request.CategoryId =1&request.AnotherProp=foo

答案 2 :(得分:0)

URISystem.Net.Http.UriExtensions的扩展方法可以完全符合您的要求:TryReadQueryAs<T>(out T model)。您可以在ApiController中获取请求中的URI:Request.RequestUri。这是它的样子:

public class FooController : ApiController
{
    //[HttpPost]
    [HttpGet]
    [ActionName("bar")]
    public void Bar()
    {
        BarRequest request;
        if (Request.RequestUri.TryReadQueryAs(out model))
        {
            // CategoryId should be 123, not 0
            Debug.WriteLine("Category ID :: {0}", request.CategoryId);
        }
    }
}

这可能仅在您指定像Joan建议的[DataContract]时才有效。

请注意,空的查询字符串将进行解析,因此,如果您曾经根据数据是否POST执行了不同的操作,则需要检查模型的有效性。无论如何,希望你这样做。