In Web API side, I have a customer class like this
public class CustomerAPI
{
public string CustomerName { get; set; }
public string CustomerCity { get; set; }
}
In MVC side I have a customer class like this
public class CustomerMVC
{
public string CustomerName { get; set; }
public string CustomerCity{ get; set; }
}
I`m consuming Web API services in ASP.Net MVC4 like below:
var task = client.GetAsync("api/values")
.ContinueWith((taskwithresponse) =>
{
var response = taskwithresponse.Result;
var readtask = response.Content.ReadAsAsync<IEnumerable<CustomerMVC>>();
readtask.Wait();
serviceList = readtask.Result.ToList();
});
task.Wait();
I'm getting aggregate exception on doing this, How can I convert CustomerWebAPI
to CustomerMVC
.
From the start window select "Installed" -> "Visual C#" -> "Web". Select "ASP.NET MVC4 Web Application" and click on the "OK" button. From the "MVC4 Project" window select "Web API". Click on the "OK" button.
In order to add a Web API Controller you will need to Right Click the Controllers folder in the Solution Explorer and click on Add and then Controller. Now from the Add Scaffold window, choose the Web API 2 Controller – Empty option as shown below. Then give it a suitable name and click OK.
Method 2: Using Newtonsoft JArraydll to your ASP.NET MVC project and WebAPI as well. Now, on Web API controller side, you will get your complex types within JArray as shown below. In this way, you can easily pass your complex types to your Web API. There are two solution, there may be another one as well.
It might help to split your code up a bit. I also recommend using the Newtonsoft.Json nuget package for serialization.
var task = client.GetAsync("api/values").Result;
//get results as a string
var result = task.Content.ReadAsStringAsync().Result;
//serialize to an object using Newtonsoft.Json nuget package
var customer = JsonConvert.DeserializeObject<CustomerMVC>(result);
If you wanted to make it asynchronous you could use the async and await keywords in C#5:
public async Task<CustomerMVC> GetCustomer()
{
//return control to caller until GetAsync has completed
var task = await client.GetAsync("api/values");
//return control to caller until ReadAsStringAsync has completed
var result = await task.Content.ReadAsStringAsync()
return JsonConvert.DeserializeObject<CustomerMVC>(result);
}
The deserialization solution feels like a bit of a hack here. Unless there's something you left out, you were probably running into an UnsupportedMediaTypeException
which was showed up as an AggregateException
because this is how uncaught Task
exceptions rear their ugly heads.
Deserialization can be an expensive operation and with this solution you will end up taking the full hit every time you deserialize the object. Using response.Content.ReadAsAsync<IEnumerable<CustomerWebAPI>>()
would be far more efficient due to a recent performance improvement to the ReadAsAsync
extensions: http://blogs.msdn.com/b/webdev/archive/2015/02/09/asp-net-mvc-5-2-3-web-pages-3-2-3-and-web-api-5-2-3-release.aspx
As for converting from CustomerWebAPI to CustomerMVC, you could easily add a static convenience method like so:
public static CustomerMVC FromCustomerWebAPI(CustomerWebAPI customer){
return new CustomerMVC(){
CustomerName = customer.CustomerName,
CustomerCity = customer.CustomerCity
}
}
It's extra code, but should end up being far more efficient. If the customer object is a fairly large object, you can always use a tool like AutoMapper or ValueInjecter or you could just roll your own solution by caching the get (type you're mapping from) and set accessors (types you're mapping to) so you only have to incur the cost of reflection once - you would do this by compiling an expression - here's an example as to how you could do that for the Set
accessors:
public static Action<object, object> BuildSetAccessor( MethodInfo method )
{
var obj = Expression.Parameter(typeof(object), "o");
var value = Expression.Parameter(typeof(object));
Expression<Action<object, object>> expr =
Expression.Lambda<Action<object, object>>(
Expression.Call(
Expression.Convert( obj, method.DeclaringType )
, method
, Expression.Convert( value, method.GetParameters()[0].ParameterType )
), obj
, value );
return expr.Compile();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With