Saturday, April 27, 2013

Talking to a PUT method in ASP.NET MVC Web API and back by way of serializing anonymous types.

Given the following ASP.NET MVC Web API Controller...

using System;
using System.Web.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Learning.Controllers
{
   public class ExperimentController : ApiController
   {
      public string Put(int id, [FromBody]string value)
      {
         var json = (JObject)JsonConvert.DeserializeObject(value);
         int foo = Convert.ToInt32(json["Foo"].ToString());
         int bar = Convert.ToInt32(json["Bar"].ToString());
         int composition = id + foo + bar;
         string explanation = id + " + " + foo + " + " + bar + " = " + composition;
         var compositionWithExplantion = new { Composition = composition,
               Explanation = explanation };
         return JsonConvert.SerializeObject(compositionWithExplantion);
      }
   }
}

 
 

I can report that...

   7 + 13 + 22 = 42

      ...ends up in the "status" variable here:

 
 

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Learning.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         string status;
         HttpClient client = new HttpClient();
         client.BaseAddress = new Uri("http://localhost:55352/");
         client.DefaultRequestHeaders.Accept.Add(new
               MediaTypeWithQualityHeaderValue("application/json"));
         var whatever = new { Foo = 13, Bar = 22 };
         var response = client.PutAsJsonAsync("api/experiment/7",
               JsonConvert.SerializeObject(whatever)).Result;
         if (response.IsSuccessStatusCode)
         {
            string messageBackFromApi = response.Content.ReadAsAsync<string>
                  ().Result;
            var json = (JObject)JsonConvert.DeserializeObject(messageBackFromApi);
            status = json["Explanation"].ToString();
         } else {
            status = "Fail!";
         }
         ViewBag.Status = status;
         return View();
      }
   }
}

 
 

.PutAsJsonAsync above could be .PostAsJsonAsync in a Post scenario or perhaps also either .DeleteAsync or .GetAsync in scenarios in which one passes the first of the two variables to the method but not the second. The signature is different for .DeleteAsync and .GetAsync as one does not hand in serialized junk with the DELETE and GET verbs. This, this, and this were some things I found while working this out. I supposed I could serialize a type that both sides understand instead of shoving anonymous types in and out of string types in the name of crosstalk. That may be the next thing to try.

1 comment: