5

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.

2 Answers 2

5

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);
}
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

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.