MVC WebApi HttpGet with complex object

15,458

Solution 1

Thanks for suggestions, but the only solution that works for me, is the following.

Before:

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

After:

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

This way I don't need to touch any model, validator, etc. on the client or server. Additionally every other solution required me to change the naming conventions on either the server or the client side.

Solution 2

you can do it by using datacontracts and datamember attribute:

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

[DataContract]
public class BarRequest{  

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

if it's a Post method

but with get method this is an example of structure for complex objects :

api/Bar?request.CategoryId =1&request.AnotherProp=foo
Share:
15,458
Daniel Kuppitz
Author by

Daniel Kuppitz

Updated on June 15, 2022

Comments

  • Daniel Kuppitz
    Daniel Kuppitz almost 2 years

    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?

  • Daniel Kuppitz
    Daniel Kuppitz about 11 years
    Tried it, but it's the same result as with JsonProperty; CategoryId is still 0 (default value).
  • Joan Caron
    Joan Caron about 11 years
    you apply this method : JsonConvert.DeserializeObject<BarRequest>(json); ?
  • Daniel Kuppitz
    Daniel Kuppitz about 11 years
    What you mean? Should the client send the json via GET?
  • Joan Caron
    Joan Caron about 11 years
    json can be a post too its passed as a parameter in your controller
  • Daniel Kuppitz
    Daniel Kuppitz about 11 years
    Please read the initial question. I need to switch from POST to GET.
  • Joan Caron
    Joan Caron about 11 years
    okay your parameter must be an int named catid instead of BarRequest object
  • Daniel Kuppitz
    Daniel Kuppitz about 11 years
    I have more than this parameter. The example is just broken down to the root of all evil. What I not want is a method signature with 10+ parameters.
  • staticboy
    staticboy about 11 years
    Thank you, this is exactly the answer I was looking for as I wanted to achieve the very same result.
  • radu florescu
    radu florescu over 10 years
    @Joan this answer helped me, very useful. this is the best approach, the accepted answer would break Restful service rules.
  • Max Bündchen
    Max Bündchen almost 8 years
    Remember that with this approach you lost functionalities like attribute validations.