Posting JSON to WebApi without reference to a model in C#

Post JSON data to WebApi without having new model class on the client

  • Share

Web API and in general REST services are becoming more and more often used layer of the applications. It relies on the HTTP, it is lighter than the SOAP and more natural to JavaScript, therefore easy to use both from the client and serer side.

Implementation of the WebApi in ASP.NET is pretty simple. You just need to declare the class of the model you want to receive and respond with in your web method, and WebAPI will handle the deserialization for the input and serialization for the return value. A lot of things out of the box.

Since you are exposing the service, if yu are the owner of the client, things get pretty easy as you can share the model classes and you do need to care much, but in case you are developing only the client, and the actual REST service is not owned by you, you may not have that luxury.

Even this case is not that big deal, as you can easily create model classes from JSON using online services such as json2csharp.com or jsonutils.com.

Guess what, you do not need to create all these models, thanks to dynamic and ExpandoObject.

I used ExpandoObjects in my previous topics to transform different types of objects. This time we will use it to simple create JSON for WebAPI call. Let's start with code.

First we'll create a dummy model class Car:

using System;

namespace ConsoleApp2
{
    public class Car
    {
        public String Color { get; set; }
        public int Serial { get; set; }
    }
}
    

Now we are going to try to generate the same object structure using dynamic as we are not having the reference to class Car:

            dynamic carDynamic = new ExpandoObject();
            carDynamic.Color = "Red";
            carDynamic.Serial = 12345;

            Car concreteCar;

            //Direct cast
            concreteCar = carDynamic as Car; //Null result

            //Serialize
            String serializedString = JsonConvert.SerializeObject(carDynamic);

            //Deserialize to concrete
            concreteCar = JsonConvert.DeserializeObject<Car>(serializedString); //Car class instance with assigned property values



    

As you can see, we cannot do direct cast from constructed dynamic object instance, but if we serialize it and deserialize to a Car class, we get the Car class instance with all property values as they are assigned when dynamic object is created. This means we can easily transfer our dynamic to a concrete class instance on the WebAPI endpoint.

In the next step we are going to actually do this, we'll remove the Car class from the client app and have it only in the WebApi project.

So we first remove the Car class from the client and move it to WebApi. We'll change the namespace to reflect the project name:

using System;

namespace WebApplication2.Models
{
    public class Car
    {
        public String Color { get; set; }
        public int Serial { get; set; }
    }
}

    

Now we set the endpoint we are going to call on the WebApi:

using WebApplication2.Models;

namespace WebApplication2.Controllers
{
    public class CarController : ApiController
    {
        public void Post(Car car)
        {

        }
    }
}

    

From the client we will now call the endpoint by creating dynamic instance which has the same structure as the Car class. To call the WebApi endpoint I used Microsoft.AspNet.WebApi.Client NuGet package. More documentation how to call the WebApi you can find at Microsoft Docs.

Now in our client we are going to call this enpoint by seralizing the dynamic to a JSON string:

using System;
using System.Dynamic;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic carDynamic = new ExpandoObject();
            carDynamic.Color = "Red";
            carDynamic.Serial = 12345;

            PostCarAsync(carDynamic);

            Console.ReadLine();
        }

        static async Task PostCarAsync(dynamic car)
        {
            var client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:58970/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var content = new StringContent(JsonConvert.SerializeObject(car), Encoding.UTF8, "application/json");

            HttpResponseMessage response = await client.PostAsync("/api/Car", content);
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine("Data posted");
            }
            else
            {
                Console.WriteLine(%%%~COMPRESS~PRE~4~%%%quot;Failed to poste data. Status code:{response.StatusCode}");
            }
        }

    }
}

    

The whole solution is attachd to this article so you can download it and run on your machine. Both projects (client and WebApi service) are set in solution to run at the same time. If you put the breakpoint at the WebApi etho, you will see that it is hit with the Car class instance.

Thsi way, we can do post by generating objects on the client pretty much like in JavaScript manner where we do not have a class which instance we need to create to invoke the web method.

References

  • Share

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.

Comments for this article

comments powered by Disqus