8

I have an existing WebApi action, that I want to switch from HttpPost to HttpGet. It currently takes a single complex object as parameter.

The model:

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

The controller:

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);
        }
    }
}

Now when I send the following request, everything works as expected.

GET /foo/bar?CategoryId=123

Also the old POST request worked as expected.

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

But now I need the following request to work:

GET /foo/bar?catid=123

How can I accomplish this?

4

3 回答 3

12

感谢您的建议,但唯一适合我的解决方案如下。

前:

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
    }
}

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

于 2013-03-26T13:31:53.910 回答
2

您可以通过使用 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
于 2013-03-25T22:44:46.213 回答
0

有一个扩展方法可以完全满足您URI的要求: . 您可以在 ApiController: 中从您的请求中获取 URI 。这是它的样子:System.Net.Http.UriExtensionsTryReadQueryAs<T>(out T model)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);
        }
    }
}

仅当您指定[DataContract]Joan 建议的类似内容时,这可能才有效。

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

于 2016-07-28T16:53:42.033 回答