Upload
others
View
17
Download
0
Embed Size (px)
Citation preview
Saideep's notes
ASP.NET Web API
> Web API- (Application Programming Interface) framework for building HTTP based web services.
REST is a sub-set n implementation of HTTP. Web API services may or may not be RESTful services.
____________________________________________________________________________________
> REST (Representational State Transfer): an architectural pattern for creating an API that uses HTTP as its
underlying communication method. The REST architectural pattern specifies a set of constraints that a system
should adhere to. Here are the REST constraints:
Client Server constraint - Client sends a request and the Server sends a response. Separation of concerns
Stateless constraint - Communication must be stateless between requests- no storing involved
Cacheable constraint - Some data provided by the server are cacheable eg. client does not have to come
back to the server for that data over and over again.
Uniform Interface - Defines the interface between the client and the server. To understand the uniform
interface constraint, we need to understand what a resource is and the HTTP verbs - GET, PUT, POST &
DELETE.
Saideep's notes
In the context of a REST API, resources typically represent data entities. Product, Employee, Customer etc are
all resources. The HTTP verb (GET, PUT, POST, DELETE) that is sent with each request tells the API what to
do with the resource. Each resource is identified by a specific URI (Uniform Resource Identifier).
Resource Verb Outcome
/Employees GET Gets list of employees /Employee/1 GET Gets employee with Id = 1 /Employees POST Creates a new employee /Employee/1 PUT Updates employee with Id = 1 /Employee/1 DELETE Deletes employee with Id = 1
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
____________________________________________________________________________________
Content Negotiation > Using the Accept header, the client can specify the format for the response. For example
Accept: application/xml returns XML Accept: application/json returns JSON
> When the response is being sent to the client in the requested format, the Content-Type header of the
response is set to the appropriate value.
Eg. if the client has requested application/xml, the server send the data in XML format and also sets the
Content-Type=application/xml.
> The formatters are used by the server for both request and response messages. When the client sends a
request to the server, we set the Content-Type header to the appropriate value to let the server know the
format of the data that we are sending.
> Changing the serialization settings of these formatters: For example, if you want the JSON data to be
properly indented and use camel case instead of pascal case for property names, all you have to do is modify
the serialization settings of JSON formatters as shown below. This code goes in WebApiConfig.cs file in
App_Start folder:
config.Formatters.JsonFormatter.SerializerSettings.Formatting =
Newtonsoft.Json.Formatting.Indented;
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
____________________________________________________________________________________
> MediaTypeFormatter:
An abstract class from which JsonMediaTypeFormatter and XmlMediaTypeFormatter classes inherit from.
JsonMediaTypeFormatter handles JSON and XmlMediaTypeFormatter handles XML.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> Return only JSON from ASP.NET Web API Service irrespective of the Accept header value: In Register() method of WebApiConfig.cs file in App_Start folder.
Saideep's notes
config.Formatters.Remove(config.Formatters.XmlFormatter);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->
Return only XML from ASP.NET Web API Service:
config.Formatters.Remove(config.Formatters.JsonFormatter);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> Return JSON instead of XML when a request is made from the browser: So here is what we want the service to do 1. When a request is issued from the browser, the web API service should return JSON instead of XML. 2. When a request is issued from a tool like fiddler the Accept header value should be respected. This means if
the Accept header is set to application/xml the service should return XML and if it is set to application/json the
service should return JSON.
Approach 1: Include the following line in Register() method of WebApiConfig.cs file in App_Start folder which
tells ASP.NET Web API to use JsonFormatter when a request is made for text/html which is the default for
most browsers.
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
Approach problem: Content-Type header of the response is set to text/html which is misleading.
Approach 2: Include the following class in WebApiConfig.cs file in App_Start folder.
public class CustomJsonFormatter : JsonMediaTypeFormatter { public CustomJsonFormatter() { this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); } public override void SetDefaultContentHeaders(Type type, HttpContentHeadersheaders, MediaTypeHeaderValue mediaType) { base.SetDefaultContentHeaders(type, headers, mediaType); headers.ContentType = new MediaTypeHeaderValue("application/json"); } }
Register the formatter in Register() method of WebApiConfig.cs file in App_Start folder:
config.Formatters.Add(new CustomJsonFormatter()); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> ASP.NET Web API is an extensible framework i.e. you can also plugin your own custom formatter.
Eg, for CSV format response, create custom CSVMediaTypeFormatter that inherits from the base abstract
class MediaTypeFormatter:
http://www.tugberkugurlu.com/archive/creating-custom-csvmediatypeformatter-in-asp-net-web-api-for-comma-separated-values-csv-format
____________________________________________________________________________________
Saideep's notes
> Implementing POST method: - using [FromBody] attribute
[Note: it returns 201 Created status code n the location of newly created employee]
Saideep's notes
____________________________________________________________________________________
> Implementing DELETE method: It should return Http Status code 200 OK if successful n code 404 NOT FOUND if un-successful
____________________________________________________________________________________
Saideep's notes
> Implementing PUT method:
____________________________________________________________________________________
> Query string parameters:
Saideep's notes
____________________________________________________________________________________
> FromBody and FromUri:
Saideep's notes
____________________________________________________________________________________
> Calling Web API from jQuery:
Saideep's notes
____________________________________________________________________________________
> Calling ASP.NET Web API service in a cross domain using jQuery ajax: (JSONP)
Same origin policy: Browsers allow a web page to make AJAX requests only within the same domain.
Browser security prevents a web page from making AJAX requests to another domain.
Saideep's notes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> Using JSONP
- Install WebApiContrib.Formatting.Jsonp to support JSONP format:
- In WebApiConfig.cs, within the Register method, create a new instance of JsonpMediaTypeFormatter n to
the constructor of this class pass the json formatter, n then inject this into config.Formatters:
Saideep's notes
Note: the dataType we get back will be 'jsonp' on the jQuery code on html page:
Saideep's notes
Testing the ASP.NET Web API Service using fiddle:
If you want JSON data back, set Accept header to application/json and there is no need to specify the
callback function in the URI. The request completes successfully.
If you want JSONP formatted data back, set Accept header to application/javascript and specify a name for
the callback function in the URI. We have set it to ABC.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> Enabling CORS
If applied at a controller level then it is applicable for all methods in the controller. To apply it at the controller
level, no need to create an instance of EnableCorsAttribute but Call the EnableCors() method without any
Saideep's notes
parameter values, unlike above. Then, apply the EnableCorsAttribute on the controller-class/method level:
[EnableCorsAttribute("*", "*", "*")]
public class EmployeesController : ApiController
{
}
To disable CORS for a specific action apply [DisableCors] on that specific action
When CORS is enabled, the browser sets the origin header of the request to the domain of the site making
the request. The server sets Access-Control-Allow-Origin header in the response to either * or the origin that
made the request. * indicates any site is allowed to make the request.
____________________________________________________________________________________
> Enable SSL:
Two simple steps to enable HTTPS for ASP.NET Web API service:
Step 1: Add a class file 'RequireHttpsAttribute' n inherit from AuthorizationFilterAttribute n override
OnAuthorization method:
namespace EmployeeService { public class RequireHttpsAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext actionContext) { if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps) { actionContext.Response = actionContext.Request .CreateResponse(HttpStatusCode.Found); actionContext.Response.Content = new StringContent ("<p>Use https instead of http</p>", Encoding.UTF8, "text/html");
Saideep's notes
UriBuilder uriBuilder = new UriBuilder(actionContext.Request.RequestUri); uriBuilder.Scheme = Uri.UriSchemeHttps; uriBuilder.Port = 44337; actionContext.Response.Headers.Location = uriBuilder.Uri; } else { base.OnAuthorization(actionContext); } } } }
Step 2: Include the following line of code in Register() method of WebApiConfig class in WebApiConfig.cs
file in App_Start folder. This adds RequireHttpsAttribute as a filter to the filters collection. So for every
request the code in this filter is executed. If the request is issued using HTTP, it will be automatically redirected
to HTTPS.
config.Filters.Add(new RequireHttpsAttribute());
[Note: If you don't want to enable HTTPS for the entire application then don't add RequireHttpsAttribute to the
filters collection on the config object in the register method. Simply decorate the controller class or the action
method with RequireHttpsAttribute for which you want HTTPS to be enabled. For the rest of the controllers and
action methods HTTPS will not be enabled]
____________________________________________________________________________________
> Implementing basic authentication in ASP.NET Web API
Saideep's notes
> Call Web API service with basic authentication using jQuery ajax:
Saideep's notes
- - - - - - - - - - - - - - - - -actual codes - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> <script src="Scripts/jquery-1.10.2.js"></script> <script type="text/javascript"> $(document).ready(function () { var ulEmployees = $('#ulEmployees'); $('#btn').click(function () { // Get the username & password from textboxes var username = $('#txtUsername').val(); var password = $('#txtPassword').val(); $.ajax({ type: 'GET', // Make sure to change the port number to where you have the employee service running on your local machine url: 'http://localhost:35171/api/Employees', dataType: 'json', // Specify the authentication header btoa() method encodes a string to Base64 headers: { 'Authorization': 'Basic ' + btoa(username + ':' + password) }, success: function (data) { ulEmployees.empty(); $.each(data, function (index, val) { var fullName = val.FirstName + ' ' + val.LastName; ulEmployees.append('<li>' + fullName + ' (' + val.Gender + ')</li>') }); }, complete: function (jqXHR) { if (jqXHR.status == '401') {
Saideep's notes
ulEmployees.empty(); ulEmployees.append('<li style="color:red">' + jqXHR.status + ' : ' + jqXHR.statusText + '</li>') } } }); }); $('#btnClear').click(function () { ulEmployees.empty(); }); }); </script> </head> <body> Username : <input type="text" id="txtUsername" /> Password : <input type="password" id="txtPassword" /> <br /><br /> <input id="btn" type="button" value="Authenticate and Get Employees" /> <input id="btnClear" type="button" value="Clear" /> <ul id="ulEmployees"></ul> </body> </html> ____________________________________________________________________________________