Extending the support for the ASP. NET Web API Jsonp

Source: Internet
Author: User

The existence of the Origin policy (same) causes the "source" from a script to operate only the DOM of the "Same origin" page, and the "cross-origin" operation from page B will be rejected. The same-Origin policy and cross-domain resource sharing are, in most cases, Ajax requests. The same-origin policy mainly restricts AJAX requests implemented through XMLHttpRequest, and if the request is a "heterogeneous" address, the browser will not be allowed to read the returned content. JSONP is a common solution for cross-domain resource sharing, and now we are leveraging the extensibility of the ASP. NET Web API itself to provide a "common" JSONP implementation scenario.

First, Jsonpmediatypeformatter

In the [CORS: cross-domain resource sharing] homology policy and JSONP, we are "populating" the returned JSON object into a JavaScript callback function in a specific action method, Now we are using custom mediatypeformatter to provide a more general implementation for JSONP.

We define the following Jsonpmediatypeformatter type by inheriting Jsonmediatypeformatter. Its read-only property, callback, represents the name of the JavaScript callback function, and the property is specified in the constructor. In the overridden method Writetostreamasync, for a non-JSONP call (the callback function does not exist), we directly invoke the method of the same name on the base class to implement the JSON serialization for the response object. Otherwise, call the WriteToStream method to populate the JavaScript callback function with the JSON string after the object is serialized.

1:public class Jsonpmediatypeformatter:jsonmediatypeformatter
   2: {
   3: Public     string Callback {get; private set;}
   
   5: Public     jsonpmediatypeformatter (string callback = null)
   6:     {
   7: This         . Callback = Callback;
   8:     }
   
  Ten: Public     override Task Writetostreamasync (type type, object value, Stream writestream, httpcontent content, TRANSP Ortcontext TransportContext)
  One:     {
  :         if (string. IsNullOrEmpty (this. Callback))
  :         {
  :             return base. Writetostreamasync (type, value, Writestream, content, TransportContext);
  :         }
  :         Try
  :         {
  : This             . WriteToStream (type, value, writestream, content);
  :             return task.fromresult<asyncvoid> (New asyncvoid ());
  :         }
  :         catch (Exception Exception)
  :         {
  :             taskcompletionsource<asyncvoid> Source = new taskcompletionsource<asyncvoid> ();
  :             source. SetException (Exception);
  :             return source. Task;
  :         }
  :     }
  
  :     private void WriteToStream (type type, object value, Stream writestream, httpcontent content)
  :     {
  To:         Jsonserializer serializer = jsonserializer.create (this. Serializersettings);
  :         using (StreamWriter StreamWriter = new StreamWriter (Writestream, this. Supportedencodings.first ()))
  :         using (jsontextwriter jsontextwriter = new JsonTextWriter (streamWriter) {closeoutput = false})
  :         {
  £ º             Jsontextwriter.writeraw (this. Callback + "(");
  Panax Notoginseng:             serializer. Serialize (jsontextwriter, value);
  :             Jsontextwriter.writeraw (")");
  :         }
  Max:     }
  
  All: Public     override Mediatypeformatter getperrequestformatterinstance (type type, httprequestmessage request, Mediatypeheadervalue mediatype)
  :     {
  :         if (request. Method! = httpmethod.get)
  :         {
  *:             return this;
  :         }
  Callback:         string;
  49:         
  :              pair = = pair. Value). TryGetValue ("Callback", out callback))
  Wuyi:         {
  Jsonpmediatypeformatter:             return New (callback);
  :         }
  Si:         return this;
  :     }
  
  £ º     [StructLayout (layoutkind.sequential, Size = 1)]
  Asyncvoid:     Private struct
  :     {}
  60:}


We have rewritten the Getperrequestformatterinstance method, by default, when the ASP. NET Web API chooses a mediatypeformatter that matches the current request by using the content negotiation mechanism. This method is called to create a Mediatypeformatter object that is really used to serialize the result of the response. In this overridden Getperrequestformatterinstance method, we try to get the JavaScript callback function name that is carried from the requested URL, which is a query string called "callback". If the callback function name does not exist, it returns itself directly, otherwise the Jsonpmediatypeformatter object created accordingly is returned.

Ii. apply Jsonpmediatypeformatter to ASP. NET Web API

Next we demonstrate the limitations of the same-origin policy for cross-domain AJAX requests through a simple example. As shown in the image on the right, we created two Web apps in the same solution using Visual Studio. As you can see from the project name, Webapi and Mvcapp are both ASP. NET Web API and MVC application, which is the caller of the Web API. We directly use the default IIS Express as the host for two applications, and fixed the port number: The port numbers for Webapi and Mvcapp are "3721" and "9527" respectively, so the URI to the two app must not be homologous.

In the WEBAPI application, we defined a Contactscontroller type that inherits from Apicontroller, and it has a unique action method getallcontacts returns a list of contacts.

1:public class Contactscontroller:apicontroller
   2: {
   3: Public     ienumerable<contact> getallcontacts ()
   4:     {
   5:         contact[] contacts = new contact[]
   6:         {
   7:             New contact{name= "Zhang San", phoneno= "123", emailaddress= "[email protected]"},
   8:             new contact{name= "John Doe", phoneno= "456", emailaddress= "[email protected]"},
   9:             new contact{name= "Harry", phoneno= "789", emailaddress= "[email protected]"},
  Ten:         };
  One:         return contacts;
  :     }
  13:}
  
  15:public class Contact
  16: {
  N: Public     string Name {get; set;}
  : Public     string Phoneno {get; set;}
  : Public     string EmailAddress {get; set;}
  20:}


Now we use the following program to create this Jsonpmediatypeformatter object in the global.asax of the WEBAPI application and add the currently registered Mediatypeformatter list. To make it a priority, we put this Jsonpmediatypeformatter object at the forefront of this list.

   1:public class WebApiApplication:System.Web.HttpApplication
   2: {
   3:     protected void Application_Start ()
   4:     {
   5:         GlobalConfiguration.Configuration.Formatters.Insert (0, New Jsonpmediatypeformatter ());
   6:         //Other operations
   7:     }
   8:}

The following homecontroller are defined in the Mvcapp application, and the default action method, index, renders the corresponding view.

   1:public class Homecontroller:controller
   2: {
   3: Public     actionresult Index ()
   4:     {
   5:         return View ();
   6:     }
   7:}

As shown below, the action method index corresponds to the view definition. Our goal is to invoke the Web API defined above as an AJAX request to get a list of contacts after the page has been successfully loaded, and will be rendered from the page. As shown in the following code snippet, we call the $.ajax method directly and set the datatype parameter to "JSONP".

   1: 
   2: 
   3:     <title> Contact List </title>
   4:     <script type= "Text/javascript" src= "@Url. Content (" ~/scripts/jquery-1.10.2.js ")" ></script>
   5: 
   6: <body>
   7:     <ul id= "Contacts" ></ul>
   8:     <script type= "Text/javascript" >
   9:         $ (function ()
  Ten:         {
  One:             $.ajax ({
                   Type       : "GET",
  :                 URL        : "Http://localhost:3721/api/contacts",
  DataType:   "jsonp",
  :                 success    : listcontacts
  :             });
  :         });
  
  :         function Listcontacts (contacts) {
  :             $.each (Contacts, function (index, contact) {
  $:                 var html = "<li><ul>";
  :                 html + = "<li>name:" + contact. Name + "</li>";
  Page:                 html + = "<li>phone No:" + contact. Phoneno + "</li>";
  :                 html + = "<li>email Address:" + contact. EmailAddress + "</li>";
  :                 html + = "</ul>";
  :                 $ ("#contacts"). Append ($ (HTML));
  :             });
  :         }
  £ º     </script>
  : </body>
  : 

After you run the ASP. NET MVC program, you get the output as shown, and the list of contacts that you get through the cross-domain call to the Web API is displayed properly.

Iii. requests and responses for JSONP

The AJAX request and response content for JSONP, as shown below. You can see that the URL of the request provides the name of the JavaScript callback function through the query string "callback", while the body part of the response is not a purely JSON object, but rather a function call statement generated by populating the JSON object into the callback return.

   1:get http://localhost:3721/api/contacts?callback=jQuery110205729522893670946_1386232694513 &_=1386232694514 http/1.1
   2:host:localhost:3721
   3:connection:keep-alive
   4:accept: */*
   5:user-agent:mozilla/5.0 (Windows NT 6.1) applewebkit/537.36 (khtml, like Gecko) chrome/31.0.1650.57 safari/537.36
   6:referer:http://localhost:9527/
   7:accept-encoding:gzip,deflate,sdch
   
   9:http/1.1 OK
  10:cache-control:no-cache
  11:pragma:no-cache
  12:content-type:application/json; Charset=utf-8
  13:expires:-1
  14:server:microsoft-iis/8.0
  15:x-aspnet-version:4.0.30319
  16:x-sourcefiles: =? UTF-8? B? Rtpc5oir55qe6jgx5l2cxeftuc5orvqgv2viiefqseahhuaetuapreenmfxozxcgu2ftcgxlc1xdagfwdgvyide0xfmxndazxfdlykfwavxhcglcy29ud ?=
  17:x-powered-by:asp.net
  18:date:thu, 08:38:15 GMT
  19:content-length:248
  
  21:jquery110205729522893670946_1386232694513 ([{"Name": "Zhang San", "Phoneno": "123", "EmailAddress": "[email protected]"}, {"Name": "John Doe", "Phoneno": "456", "EmailAddress": "[email protected]"},{"name": "Harry", "Phoneno": "789", "EmailAddress": [email protected]}])



This article turns from http://www.cnblogs.com/artech/archive/2013/12/05/3460544.html

Extending the support for the ASP. NET Web API Jsonp

Related Article

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.