the full power of asp.net web api

Post on 10-May-2015

57.714 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

The Full Power of ASP.NET Web API

TRANSCRIPT

Eyal VardiCEO E4D Solutions LTDMicrosoft MVP Visual

C#Site: www.e4d.co.il

The Full Power of ASP.NET Web API

The Challenge

HTML 5 )Changes The Rules of The

Game(

Traditional apps

Browser Request

Index.html

MVC4

Traditional Request / Response for ALL rendered content and assets

Web Application (SPA)

Initial Request

Application.htm

MVC4

RequireJS Loader

Page1 Partial.htm

IndexViewModel.js

Application.js (bootstrap)

ViewModel (#index)

ViewModel (#login)

Model (LoginModel)JSON Requests

HTML5 localstorage

Handling disconnection

Web API Growth

Source: www.programmableweb.com – current APIs: 4,535

Single Page Web Apps (SPA)

WCF vs. ASP.NET Web API

SOAP WSDL HTTP

POST SimpleService.asmx/EchoString HTTP/1.1 Host: localhost:1489 User-Agent: Mozilla/5.0 Accept: text/html Content-Type: application/json; Content-Length: 27 ...

XML, JSON, SOAP, AtomPub ...

HTTP Communication

Headers

Data

Verb URL

POST SimpleService.asmx/EchoString HTTP/1.1 Host: localhost:1489 User-Agent: Mozilla/5.0 Accept: text/html,application/xhtml+xml Content-Type: application/json; Content-Length: 27 ...

JSON vs. SOAP

{"Age":37,"FirstName":"Eyal",

"ID":"123", "LastName":"Vardi“ }

Headers

Data

Verb URL

<Envelope> <Header> <!–- Headers --> <!-- Protocol's & Polices --> </Header> <Body> <!– XML Data --> </Body> </Envelope>

Protocols & Formats

BL’s

Interfaces

Services

WCF

WCF Data

Services

ASMX MVC Web API SignalR

B B B B B

SOAP REST OData JSON POX ??

ASP.NET Web API vs. ASP.NET MVC

Validation

Help Page

Security

Routing

Self-Hosting

Dependency Injection

Filters

Content Negotiation

RESTful APIHTTP Message Handlers

Media Formatter

OData

Testing

MICROSOFT CONFIDENTIAL – INTERNAL ONLY

GET /en/html/dummy.php?name=MyName&married=not+single &male=yes HTTP/1.1Host: www.explainth.atUser-Agent: Mozilla/5.0 (Windows;en-GB; rv:1.8.0.11) Gecko/20070312 Firefox/1.5.0.11Accept: text/xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5Accept-Language: en-gb,en;q=0.5Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Connection: keep-aliveReferer: http://www.explainth.at/en/misc/httpreq.shtml

Embrace HTTP

ASP.NET Ecosystem

ASP.NET

SignalR

Services

SPAMVCWebForms

WebAPI

Sites

ASP.NET Web API (Hello World)

REpresentational State Transfer

REST is..

“An architectural style for building distributed

hypermedia systems.”

WSDL vs. RESTWSDL description of a web services types defined in <xsd:schema>simple messages parts of messages

interface specification operations of an interface input message output message

binding of interface to protocols & encoding description of the binding for each operation

service descriptionURI and binding to port

<definitions> <types></types> <message> <part></part> </message> <portType> <operation> <input> <output> </operation> </portType> <binding> <operation> </binding> <service> <port> </service></definitions>

From RPC to REST

* From ASP.NET MVC 4 and the Web API: Building a REST Service from Start to Finish book

URIs and Resources (Routing)

* From ASP.NET MVC 4 and the Web API: Building a REST Service from Start to Finish book

HTTP Verbs

* From ASP.NET MVC 4 and the Web API: Building a REST Service from Start to Finish book

“Hypermedia as the engine of application state” (HATEOAS)<?xml version="1.0" encoding="utf-8"?><Tasks>

<TaskInfo Id="1234" Status="Active" > <link rel="self" href="/api/tasks/1234" method="GET" /> <link rel="users" href="/api/tasks/1234/users" method="GET" /> <link rel="history" href="/api/tasks/1234/history" method="GET" /> <link rel="complete" href="/api/tasks/1234" method="DELETE" /> <link rel="update" href="/api/tasks/1234" method="PUT" /> </TaskInfo>

<TaskInfo Id="0987" Status="Completed" > <link rel="self" href="/api/tasks/0987" method="GET" /> <link rel="users" href="/api/tasks/0987/users" method="GET" /> <link rel="history" href="/api/tasks/0987/history" method="GET" /> <link rel="reopen" href="/api/tasks/0987" method="PUT" /> </TaskInfo>

</Tasks>

/api/tasks

“Hypermedia as the engine of application state” (HATEOAS)

* From ASP.NET MVC 4 and the Web API: Building a REST Service from Start to Finish book

The Advantages of REST over SOAP Simpler API for CRUD

Standardize Development methodology

Wide industry adoption, Ease of use

Smaller payloads than SOAP

Testability

RESTful

OData OData is a standardized protocol for

creating and consuming data APIs.

Query string options $Expand

/Customers(ALFKI)?$expand=Orders.Employees

$Orderby /Customers?$orderby=City desc,

CompanyName

$Skip /Customers?$skip=10

$Top /Orders?$orderby=TotalDue&$top=5

$Filter /Customers?$filter=City eq ‘London’

LINQ to URI /ds.svc/Customers

from c in Customers select c

/ds.svc/Customers('ALFKI') ( from c in Customers

where c.keyProperty == "ALFKI" select c ).First()

/ds.svc/Customers('ALFKI')/Address ( from c in Customers

where c.keyProperty == "ALFKI" select c.Address ).First()

/ds.svc/Customers('ALFKI')/Orders from c in Customers

from c2 in c.Orders where c.keyProperty == "ALFKI" select c2

OData

Help Page  ASP.NET and Web Tools 2012.2 Update

integrates help pages into the Web API project template.

Web API generated dynamically, using the IApiExplorer interface.

Adding a simple Test Client to ASP.NET Web API Help Page

Help Page

Format & Model Binding

Format & Model Binding

Serialization

Validation

DeserializationResponse

Controller / Action

Request HTTP/1.1 200 OK Content-Length: 95267 Content-Type: text/html | application/json Accept: text/html, application/xhtml+xml, application/xml

Media Formatters (Serialization) A media-type formatter is an object that

can: Read CLR objects from an HTTP message body.

Write CLR objects into an HTTP message body.

GlobalConfiguration.Configuration.Formatters

JSON Media-Type Formatter

Json.NET or DataContractJsonSerializer?

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; json.UseDataContractJsonSerializer = true;

JSON Media-Type Formatter

What Gets Serialized? "opt-out" approach

"opt-in" approach

public class Product{ public string Name { get; set; } public decimal Price { get; set; } [JsonIgnore] public int ProductCode { get; set; }}

[DataContract] public class Product{ [DataMember] public string Name { get; set; } [DataMember] public decimal Price { get; set; } // omitted by default public int ProductCode { get; set; }}

JSON Media-Type Formatter

Anonymous and Weakly-Typed Objects

public object Get() { return new { Name = "Alice", Age = 23, Pets = new List<string> { "Fido", "Polly", "Spot" } }; }

public void Post(JObject person) { string name = person["Name"].ToString(); int age = person["Age"].ToObject<int>(); }

XML Media-Type Formatter

DataContractSerializer or XmlSerializer?

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;

The XmlSerializer class supports a narrower set of types than DataContractSerializer, but gives more control over the resulting XML. Consider using XmlSerializer if you need to match an existing XML schema.

Custom Media Formatters Derives from BufferedMediaTypeFormater.

In the constructor, add the media types that the formatter supports.

To indicate which types the formatter can serialize, Override the methods: CanWriteType CanReadType WriteToStream

Use the Formatters property on the HttpConfiguration object to add a custom media type formatter.

Custom Media Formatters

Content Negotiation The primary mechanism for content

negotiation in HTTP are these request headers: Accept Accept-Charset Accept-Encoding Accept-Language

“the process of selecting the best representation for a given response when there are multiple representations available.” 

Content Negotiation Samplepublic HttpResponseMessage GetProduct(int id){ var product = new Product() { Id = id, Name = "Gizmo", Price = 1.99M };

IContentNegotiator negotiator = this.Configuration .Services.GetContentNegotiator();

ContentNegotiationResult result = negotiator.Negotiate( typeof(Product), this.Request, this.Configuration.Formatters);

if (result == null) { var response = new HttpResponseMessage(HttpStatusCode.NotAcceptable); throw new HttpResponseException(response)); }

return new HttpResponseMessage() { Content = new ObjectContent<Product>( product, // What we are serializing result.Formatter, // The media formatter result.MediaType.MediaType // The MIME type ) };}

Validations

Model Data Annotations Specify validation for individual fields in

the data model. System.ComponentModel.DataAnnotations

Provide both client and server validation checks with no additional coding required by you.

public class ProductMD{    [StringLength(50), Required]    public string Name { get; set; }                            [Range(0, 9999)]    public int Weight { get; set; }}

Validation Attributes Metadata Validation Attributes:

[Required] [Exclude] [DataType] [Range]

[MetadataTypeAttribute( typeof( Employee.EmployeeMetadata ) )]public partial class Employee} internal sealed class EmployeeMetadata } [StringLength(60)] [RoundtripOriginal] public string AddressLine { get; set; } }}

[StringLength(60)] [RegularExpression

] [AllowHtml] [Compare]

Web API Validation

public class ProductsController : ApiController{ public HttpResponseMessage Post(Product product) { if ( ModelState.IsValid ) { // Do something with the product (not shown). return new HttpResponseMessage(HttpStatusCode.OK); } else { return new HttpResponseMessage(HttpStatusCode.BadRequest); } }}

Custom Validation public class ModelValidationFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if (actionContext.ModelState.IsValid == false) { // Return the validation errors in the response body. var errors = new Dictionary<string, IEnumerable<string>>(); foreach ( var keyValue in actionContext.ModelState ) { errors[keyValue.Key] = keyValue.Value.Errors.Select(e => e.ErrorMessage); } actionContext.Response = actionContext .Request .CreateResponse(HttpStatusCode.BadRequest, errors); } } }

public class ModelValidationFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if (actionContext.ModelState.IsValid == false) { // Return the validation errors in the response body. var errors = new Dictionary<string, IEnumerable<string>>(); foreach ( var keyValue in actionContext.ModelState ) { errors[keyValue.Key] = keyValue.Value.Errors.Select(e => e.ErrorMessage); } actionContext.Response = actionContext .Request .CreateResponse(HttpStatusCode.BadRequest, errors); } } }

Custom Validation

protected void Application_Start() { // ... GlobalConfiguration .Configuration .Filters.Add(new ModelValidationFilterAttribute()); }

Custom Validation

Server-Side Message Handlers The Web API pipeline uses some built-in

message handlers: HttpServer gets the request from the host.

HttpRoutingDispatcher dispatches the request based on the route.

HttpControllerDispatcher sends the request to a Web API controller.

You can add custom handlers to the pipeline.

Custom Message Handlers

Self-Hosting

var config = new HttpSelfHostConfiguration("http://localhost:8080");

config.Routes.MapHttpRoute(    "API Default", "api/{controller}/{id}",     new { id = RouteParameter.Optional });

using (HttpSelfHostServer server = new HttpSelfHostServer(config)) {    server.OpenAsync().Wait();    Console.ReadLine(); }

Client Side

Client Side Frameworks for SPA

www.js-il.com

18.6.13

Thankseyalvardi.wordpress.com

Eyal VardiCEO E4D Solutions LTDMicrosoft MVP Visual C#blog: www.e4d.co.il

top related