HttpClient + ASP.NET Web API, an alternative to WCF

Keywords: ASP.NET JSON JQuery IIS

Reference page:

http://www.yuanjiaocheng.net/webapi/create-crud-api-1.html

http://www.yuanjiaocheng.net/webapi/create-crud-api-1-get.html

http://www.yuanjiaocheng.net/webapi/create-crud-api-1-post.html

http://www.yuanjiaocheng.net/webapi/create-crud-api-1-put.html

http://www.yuanjiaocheng.net/webapi/create-crud-api-1-delete.html

WCF's ambition makes it huge and complex. HTTP's simplicity makes it simple and graceful. In order to implement distributed Web applications, we have to put the two together - WCF services are hosted in IIS with HTTP binding.

So there are dizzying configurations, depressing debugging, and the Service Contract, DataContract, EnumMember... and so on. Do not call WCF services in using statements...

So I often ask myself: Is it necessary to peel apples with a cow knife? Nonsense, of course, it's not necessary. Where's the fruit knife?

Microsoft watched so many people peeling apples with cow knives that it couldn't bear to watch them anymore. So a fruit knife came into being - ASP.NET Web API.

Recently, in our actual development, there is a place where it is too troublesome to use WCF, so we have a small try of fruit knife. It feels good.

Here is a simple example to share the usage of ASP.NET Web API fruit knife.

Implementation of ASP.NET Web API on Server

Tools to be prepared: Visual Studio 2010, NuGet

1. Create an empty ASP.NET Web Application project.

2. Add the reference of ASP.NET Web API through NuGet, search in NuGet with AspNet Web Api (which can not be searched with ASP.NET Web API), and then select ASP.NET Web API(Beta) to install.

3. Add Global.asax, register the route of Web API in Application_Start, and add the following code in Global.asax.cs:

protected void Application_Start(object sender, EventArgs e)
{
    RouteTable.Routes.MapHttpRoute("WebApi", "api/{controller}/{action}/{id}", 
        new { id = RouteParameter.Optional });
}

4. Add the Controllers folder, add the class file DemoController.cs, and let DemoController inherit from ApiController. The code is as follows:

namespace CNBlogsWebApiDemo.Controllers
{
    public class DemoController : ApiController
    {
    }
}

5. Add the ViewModels folder, add Site.cs to it, and define Site.

namespace CNBlogsWebApiDemo.ViewModels
{
    public class Site
    {
        public int SiteId { get; set; }
        public string Title { get; set; }
        public string Uri { get; set; }
    }
}

6. Add a method SiteList to DemoController and write our sample code. The code is as follows:

public class DemoController : ApiController
{
    public IList<Site> SiteList(int startId, int itemcount)
    {
        var sites = new List<Site>();
        sites.Add(new Site { SiteId = 1, Title = "test", Uri = "www.cnblogs.cc" });
        sites.Add(new Site { SiteId = 2, Title = "Blog Garden Home Page", Uri = "www.cnblogs.com" });
        sites.Add(new Site { SiteId = 3, Title = "Bo asked", Uri = "q.cnblogs.com" });
        sites.Add(new Site { SiteId = 4, Title = "Journalism", Uri = "news.cnblogs.com" });
        sites.Add(new Site { SiteId = 5, Title = "recruit", Uri = "job.cnblogs.com" });

        var result = (from Site site in sites
                        where site.SiteId > startId
                        select site)
                        .Take(itemcount)
                        .ToList();
        return result;
    }
}

7. Configure the startup settings Specific Page and Specific port for a Web project

8. Ctrl+F5 running project, the results are as follows:

As a result, we expect that the results of the Web API can be viewed directly with the browser, and the test will be very convenient.

Well, the server-side Web API is so easy to work out!

Client calls Web API of server through HttpClient

1. Create a new class library project for WebApiTest.

2. Add System.Net.Http(HttpClient is here), Json.NET, xUnit.net to NuGet.

3. Add the class file WebApiClientTest.cs and the test method WebApi_SiteList_Test:

namespace WebApiClientTest
{
    public class WebApiClientTest
    {
        [Fact]
        public void WebApi_SiteList_Test()
        {

        }
    }
}

4. Code implementation of WebApi_SiteList_Test()

4.1 First of all, three things should be identified:

(a) The way the client calls the Web API is Http Get and Http Post. We choose Http Post here.

b) The parameter format passed by the client when calling the Web API is Json.

c) The data format returned by the Web API is also Json (which is why Json.NET references were added earlier).

Classes used in 4.2

  • System.Net.Http.HttpClient
  • System.Net.Http.httpContent
  • System.Net.Http.StringContent
  • System.Net.Http.Headers.MediaTypeHeaderValue
  • Newtonsoft.Json.JsonConvert

4.3 Prepare the parameters that need to be passed to the Web API

The two parameters to be passed are startId, itemcount, and the format to be passed is Json. There is no JSON.stringify() in Javascript, but we have Json.NET, plus anonymous types, which feels a bit like js. The code is as follows:

var requestJson = JsonConvert.SerializeObject(new { startId = 1, itemcount = 3 });

The result of the code: {"startId":1,"itemcount":3}

Then pack it with System.Net.Http.StringContent:

HttpContent httpContent = new StringContent(requestJson);

Then set up ContentType:

httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

4.4 Call the Web API through Http Post to get the return result

HttpClient shines and calls its PostAsync() method to make it easy:

var httpClient = new HttpClient();
var responseJson = httpClient.PostAsync("http://localhost:9000/api/demo/sitelist", httpContent)
    .Result.Content.ReadAsStringAsync().Result;

Look at the results of response Json:

[{"SiteId":2,"Title":"Blog Garden Home Page","Uri":"www.cnblogs.com"},{"SiteId":3,"Title":"Bo asked","Uri":"q.cnblogs.com"},{"SiteId":4,"Title":"Journalism","Uri":"news.cnblogs.com"}]

Authentic Json! Did you notice that the code of the server-side Web API has not been changed, we just set ContentType to application/json in Http Headers, and the data returned is in Json format. And when we access it through browsers, we still get standard XML. This is one of the charms of ASP.NET Web API - one-time implementation, on-demand service.

4.5 Deserializes the results returned in Json format into strong types

Json.NET is on the scene again:

var sites = JsonConvert.DeserializeObject<IList<Site>>(responseJson);

Show the return result:

Code

sites.ToList().ForEach(x => Console.WriteLine(x.Title + ": " + x.Uri));

Results

  Blog Garden Home Page: www.cnblogs.com
  Boq: q.cnblogs.com
  News: news.cnblogs.com

4.6 Complete implementation code of WebApi_SiteList_Test()

public class WebApiClientTest
{
    [Fact]
    public void WebApi_SiteList_Test()
    {            
        var requestJson = JsonConvert.SerializeObject(new { startId = 1, itemcount = 3 });

        HttpContent httpContent = new StringContent(requestJson);
        httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

        var httpClient = new HttpClient();
        var responseJson = httpClient.PostAsync("http://localhost:9000/api/demo/sitelist", httpContent)
            .Result.Content.ReadAsStringAsync().Result;

        var sites = JsonConvert.DeserializeObject<IList<Site>>(responseJson);

        sites.ToList().ForEach(x => Console.WriteLine(x.Title + ": " + x.Uri));
    }
}

Note: Before running the code here, you have to run the Web API project first, and run the service first, so that the client can enjoy the service.

Compare with jQuery ajax calling code:

var requestJson = JSON.stringify({ startId: 1, itemcount: 3 });
$.ajax({
    url: '/api/demo/sitelist',
    data: requestJson,
    type: "post",
    dataType: "json",
    contentType: "application/json; charset=utf8",
    success: function (data) {
        jQuery.each(data, function (i, val) {
            $("#result").append(val.Title + ':  ' + val.Uri +'<br/>');
        });
    }
});

Note: The above code is real. The code is in the Ajax WebApi. HTM file of the sample code WebApiDemo project. This is also the embodiment of ASP.NET Web API "one-time implementation, on-demand service".

Summary

The fruit knife (ASP.NET Web API) feels good when used. It can not only peel apples, but also pears and watermelons. If you don't use a cow knife (WCF), you have to think about it.

Sample code download

http://files.cnblogs.com/dudu/CNBlogsWebApiDemo.rar

To update

Wahaha ABC Put forward one. Good question:

WebApiTest refers to WebApiDemo. Strong typing is implemented. Is this still a distributed application?

Powerful Json.NET can easily solve this problem. The code is modified as follows:

//The original code: var sites = JsonConvert.DeserializeObject<IList<Site>>(responseJson);
var sites = JArray.Parse(responseJson);
sites.ToList().ForEach(x => Console.WriteLine(x["Title"] + ": " + x["Uri"]));

Posted by AE117 on Fri, 04 Jan 2019 10:51:09 -0800