MVC4 WebAPI (ii)--web API working mode

Source: Internet
Author: User
Tags response code

In the previous article and everyone to learn the establishment of basic WEBAPI applications, immediately people think of some questions:
1. File transfer between client and webservice
2. Security control on client or server
To solve these problems, look at the basic way WEBAPI works.

(i) The class of work in Webapi

As you can see in MVC, getting request and response using HttpRequest and HttpResponse two classes, using two out of two classes in WEBAPI:
Httprequestmessage and Httpresponsemessage, respectively, for encapsulating Requset and response. In addition to these two classes, there is a common abstract class: Httpmessagehandler for filtering and processing httprequestmessage and Httpresponsemessage

(ii) addressing the first issue

In fact, the first problem is proposed should be related to the client, if the client's request is our handwritten submission, such as the use of HttpClient encapsulated request, then to pass the file, we will generally do a serialization, into a binary array, and so on the network transmission. In this case, in the action parameter of the controller, we only need to receive the object of the binary array type.
But if the client is a Web form, such as when we submit a form to the action of the specified controller, what type of argument does the action receive?
Or we ask another question, if I submit the Web form to a WEBAPI action, how do I get the data out of the form?
In fact, we should think that the parameters of our action settings can be assigned because the WEBAPI schema will parse the data from the HTTP request to the arguments in the action when the action is called, if that is the case, We only need to get the HTTP request in the action, and then get the data in the request directly, we can solve the above problem.
The idea is correct, except that the HTTP request at this point is not the most primitive HTTP requests, but has been converted to httprequestmessage, and in action we can call base directly. Requet to get this httprequestmessage instance, we can take out the data we want in the HTTP request at will.

2.1 Getting normal form data from Requestmessage

The normal form here refers to a form that does not contain file, that is, the enctype value of the form is not multipart/form-data, when the form's data is passed by default in JSON.
The following page

<form name= "form" action= "~/api/formsubmit?key=11234" method= "POST" >    <input type= "text" name= "key" id= " Txtkey "/>    <br/>    <input type=" text "name=" value "id=" Txtvalue "/>    <br/>        < Input type= "Submit" id= "Btnsubmit" value= "Submit"/>     </form>

The captured request is

Submit to the corresponding action as:

        [HttpPost]        Public async void SubmitForm ()        {            StringBuilder sb = new StringBuilder ();            Httpcontent content = request.content;            Jsonobject Jsonvalue = await content. Readasordefaultasync<jsonobject> ();            foreach (var x in Jsonvalue)            {                sb. Append (X.key);                String va;                if (x.value.tryreadas<string> (out va))                {                    sb. Append (VA);}}        

This can finally get the value of the JSON: {"key": "123", "value": "123"} after the value of SB processing is: key123value123

Note: The keyword async and await are used in this action, these new keywords in 4.5 are mainly used for multithreading, and in the design of MVCAPI, most of the methods are designed to resemble the following methods

public static task<t> readasordefaultasync<t> (this httpcontent content);

The return value is a task, and this method of returning a new thread can improve the responsiveness of the system, but multithreading is inconvenient for encoding, so the new keyword await is used to block the current thread and get the return value of the target thread. Using the await keyword in the method body requires that the method be declared as async to indicate that the method is asynchronous, and that the return value must be void or encapsulate the returnee in a task
Of course, if you don't like the notation, the action above can also be written as:

            Task readtask = content. Readasordefaultasync<jsonobject> (). ContinueWith (Task) = {Jsonvalue = task. Result; });            Readtask.wait ();


2.2 Getting multipart form data from Requestmessage
Overwrite the view page as

<form name= "form" action= "~/api/formsubmit?key=11234" method= "post" enctype= "Multipart/form-data" >    < Input type= "text" name= "key" id= "Txtkey"/>    <br/>    <input type= "text" name= "value" id= "Txtvalue"/& gt;    <br/>    <input type= "file" name= "file" id= "Upfile"/> <br/>    <input type= "Submit" id= " Btnsubmit "value=" Submit "/></form>

At this point the capture request is


The file content here is parsed into a string by the capture software, of course, if I upload other non-text formatted files, the file will be converted into a binary array
At this point, if we do not change the action, and call directly, there will be an error, because it is obvious that the message content of this HTTP can not be converted to JSON, we need to parse the form of the message into another format

                Ienumerable

The resulting treated SB value is:

{"Key": 123----"value": 123----"File":* the contents of the *****{file}*****----}
The integrated action is

        [HttpPost] public async void SubmitForm () {StringBuilder sb = new StringBuilder ();            Httpcontent content = request.content; if (content. Ismimemultipartcontent ()) {ienumerable

(iii) WEBAPI mode of work

It's not so easy to solve the second problem, we need to understand Webapi's working style more deeply.
In fact, for WEBAPI, it was originally designed to be the same as WCF: the client, the server two sets of structure, we have not yet mentioned the client, because we request another way to encapsulate the HTTP request or receive HTTP corresponding, such as Ajax and form form submission.

Here we first give a service-side response workflow, so that everyone has a general understanding

(Have to add a watermark in the picture, because see their hard to write things are taken directly, also do not give the original link, the heart is really bad to suffer. Hope will not affect everyone's reading ... )
Due to the size limit of the picture, all httprequestmessage are abbreviated to Httprequestmsg,httpresponsemessage httpresponsemsg

As you can see, HTTP requests are first passed to host, and if Webapi is hosted on IIS, the host is IIS and host is not capable or necessary to handle the request. The request was forwarded via host to Httpserver at this time has entered the WEBAPI processing range, Httpserver is a class in System.Net.HTTP, through Httpserver, the request is encapsulated into the webapi of the request bearer Class: Httprequestmessage, this encapsulated request can be processed by a series of custom handler that are concatenated into a pipeline, and the final request is passed to Httpcontroldispather, This class determines the action in the specific controller that the request will be forwarded to by retrieving the routing table.

Client-side processing is similar to the server, directly:

In fact, according to Microsoft, they are designed to be similar but can run independently of the structure

The ASP. NET Web API has a pipeline for processing HTTP messages on both the client and server. The client and server sides is designed to being symmetrical but independent; You can use each of the half by itself. Both sides is built on some common objects:

  • Httprequestmessage represents the HTTP request.
  • Httpresponsemessage represents the HTTP response.
  • Httpmessagehandler Objects process the request and response.

Looking directly at the graph, on the client side, the handlers pipeline is ultimately passed on to Httpclienthandler, which is responsible for the conversion of Httprequestmessage to the HTTP request.

Here is just a description of request,response and its similarity.

(iv) Resolution of the second issue

As we can see earlier, to solve the second problem, can be directly in the handler pipeline, this AOP-style filter (Interceptor) in the rest of the WebService security verification of the application is very wide, generally people are more happy in the HTTP header or in the The URL of the HTTP request is authenticated with the authentication field, and below is a small example of adding authentication information to the HTTP header

4.1 Client
The client's Customhandler is used to add the authentication information into the header

    Class Requestuphandler:delegatinghandler    {        protected override task

Note:
1.customhandler inherits from the Delegatinghandler class, as mentioned above, Webapi's client and server are designed to correspond to the two sets of structure, so whether in the client or the server, Customhandler are inherited from the Delegatinghandler class
The SendAsync method of 2.DelegatingHandler is the method that will be called when processing the request and accepting the request, the method return value is Httpresponsemessage, the value received is Httprequestmessage, In line with our general knowledge
3. At the end of the method, call base. SendAsync is to pass the request to the other customhandler of the pipeline and get its return value. Since this method does not contain the processing logic of response, it is only required to directly add the previous Customhandler
return value returns directly
Client Main Program

        static void Main (string[] args)        {            HttpClient client = new HttpClient (new Requestuphandler () {Innerhandler = new H Ttpclienthandler ()});            Httpresponsemessage response = client. Getasync ("Http://localhost:60023/api/FormSubmit"). Result;            Response. Content.readasasync<string> (). ContinueWith (str) = {Console.WriteLine (str. Result); });            Console.read ();        }

The client's main program creates a httpclient,httpclient that can accept a parameter, which is Customhandler, where we embed our defined Requestuphandler, For the processing of embedded authentication codes for the request header, Customhandler embeds its built-in next Customhandler through the Innerhandler attribute, where, because there is no next customerhandler, We embed Httpclienthandler directly to convert Httprequestmessage to HTTP requests, to convert HTTP responses to Httpresponsemessage

4.2 Service Side
The customhandler of the server is used to parse the authentication code in the HTTP header

        protected override system.threading.tasks.task

Note: The processing logic of the code is simple: If the authentication code matches successfully, it is through base. SendAsync continues to pass the request down, otherwise returns the delivery of the direct interrupt request, directly returning a response code of 403, indicating no permissions.
Note that because the return value of SendAsync needs to be encapsulated in a task, you need to use Task.Factory.StartNew to include the return value in the task

Inject the Customhandler into the host
In this case, WEBAPI host is on IIS, so we just need to define our defined Customhandler in Application_Start.

        protected void Application_Start ()        {            //Omit other logic code            GLOBALCONFIGURATION.CONFIGURATION.MESSAGEHANDLERS.ADD (New Httpurlhandler ());        }

Because Webapi host is on IIS, Httpserver and Httpcontrollerdispatcher do not have to handle it manually.

After adding the above processing, if there is no authentication code for the request, you will get the following response

******************************************************************************
Wang Kun
Source: http://www.cnblogs.com/wk1234

MVC4 WebAPI (ii)--web API working mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.