3

seems like I have the most basic problem, yet I cannot find the documentation I need to solve it.

I have an mvc webapi controller:

public class TestController : ApiController
{
    [HttpGet]
    public MyClass Other([FromUri]MyClass id)
    {
        id.Value++;
        return id;
    }        
}

public class MyClass
{
    public int Value {get;set;}
}

which I am executing from a HttpClient:

using (var client = new System.Net.Http.HttpClient())
{
    client.BaseAddress = new System.Uri("http://localhost:31573/api/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    var obj = new MyClass { Value = 3 };
    var data = JsonConvert.SerializeObject(obj);
    StringContent queryString = new StringContent(data, Encoding.UTF8, "application/json");
    var paramsValue = queryString.ReadAsStringAsync().Result;
    var response = client.GetAsync("Test/?id="+ paramsValue).Result;                    
    var textResponse = response.Content.ReadAsStringAsync().Result;
    var result = JsonConvert.DeserializeObject<MyClass>(textResponse);                    
 }

The problem is that the parameter id which is received by the controller is a default instance of MyClass (i.e. Value = 0). If I change the prototype of the method to accept a string:

[HttpGet]
public MyClass Other([FromUri]string id)
{
    var val = JsonConvert.DeserializeObject<MyClass>(id);
    val.Value++;
    return val; 
}    

it all works fine, but I would rather not have to manually do the deserialization in every controller method.

I have tried many combinations of how I create the query string, so far having no luck.

It appears that the data is getting to the webApi correctly, but the deserialization is not happening, so I suspect that I have not configure the webApi correctly to use json form the request parameters.

my webapiconfig looks like:

public static void Register(HttpConfiguration config)
        {
            if (config == null)
                throw new ArgumentNullException(nameof(config));

            // Web API configuration and services
            config.Formatters.Clear();
            config.Formatters.Add(new JsonMediaTypeFormatter());

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });
        }

so its returning json correctly, but incoming parameters are not deserialized correctly.

Can anyone help??

0

2 Answers 2

2

Thanks to the help from @Mostafizur Rahman, I came to the conclusion that a get method was not appropriate here, So I have changed to a Post method and pass the data in the body:

public class TestController : ApiController
{
    public MyClass PostMethod([FromBody]MyClass id)
    {            
        id.Value++;
        return id;
    }
}

public class MyClass
{
    public int Value {get;set;}
}

with the client side becoming:

using (var client = new System.Net.Http.HttpClient())
{
    client.BaseAddress = new System.Uri("http://localhost:31573/api/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    var obj = new MyClass { Value = 3 };
    var data = JsonConvert.SerializeObject(obj);
    StringContent queryString = new StringContent(data, Encoding.UTF8, "application/json");
    var paramsValue = queryString.ReadAsStringAsync().Result;
    var response = client.PostAsync("Test/PostMethod",  queryString).Result;
    var textResponse = response.Content.ReadAsStringAsync().Result;
    var result = JsonConvert.DeserializeObject<MyClass>(textResponse);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Correct. As you are sending data to API - FromBody won't work via GET request. You need either use POST or flatter MyClass parameted in your action to the list of parameters corresponding to the MyClass properties
0

this is the querystring that you'll need to form -

http://localhost:61817/api/Test?Value=3

Then the code changes like -

var response = client.GetAsync("Test?Value="+ obj.Value).Result;

enter image description here

2 Comments

That is easy for the simple case of MyClass but for an object with dozens of properties, how would I generate the querystring?
You'll need to append them as key-value in the queryString, or better you issue an HTTP POST, in that case the the request body contains all those properties.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.