Sei sulla pagina 1di 164

Rest:

List

Q1. What is REST? Ans. REST stands for Representational State Transfer. This is a protocol for exchanging data over a distributed environment. REST is an architectural style which treat each service as a resource and access data by HTTP protocol methods like GET, POST, PUT, and DELETE. REST-style architectures consist of clients and servers. Clients initiate requests to servers who process these requests and return responses based on these requests. These requests and responses are built around the transfer of representations of these resources.

Q2. Explain REST principle? Ans. REST is a set of principles that define how Web standards, such as HTTP and URIs, are supposed to be used. There are five important REST principle as given below – Addressable Resources- Each resource should be identified by a URI (unique identifier) Simple and Uniform Interfaces- REST is based on HTTP protocol so use HTTP GET, POST, PUT and DELETE method to perform actions. This make REST simple and uniform.

Representation Oriented- Representation of resources are exchanged. GET is used to return

a representation and PUT, POST passes representation to the server so that underlying

resources may change. Representation may be in many formats like XML, JSON etc. Communicate Stateless- An application may has state but there is no client session data stored on the server. Any session specific data should be held and maintained by the client and transferred to the server with each request as needed. Cacheable - Clients should be able to cache the responses for further use.

REST and SOAP? Ans. The difference between REST and SOAP is given below: SOAP REST SOAP stands for

Simple Object Access Protocol REST stands for REpresentational State Transfer. It is an XML based protocol built on the top of HTTP or sometimes TCP/IP, SMTP. REST is not a protocol but it is an architectural style i.e. resource-based architecture. DOT NET TRICKS TRAINING CENTER

B 64, Near SBI Bank, Sector 2 Noida, Metro Noida Sector 15, Uttar Pradesh (India)

www.dotnet-tricks.com, www.dotnettricks.com +91 98 71 749695, +91 120 426 5198

Page79

Training Highlights Learn from qualified and experienced professional Small batches to ensure personal attention Hands-on real application development Recorded session of your class Training course material Prepare yourself for interview and get great jobs

SOAP has specifications for both stateless and stateful implementation. REST is completely stateless. SOAP enforces message format as XML. REST does not enforces message format as XML or JSON. SOAP has a defined standard specification. For example, WS-Security is the specification for implementing security. It has no defined standard specifications. The SOAP message consists of an envelope which includes SOAP headers and body to store the actual information you want to send. REST uses the HTTP build-in headers (with a variety of media-types) to carry meta information and use the GET, POST, PUT and DELETE verbs to perform CRUD operations. SOAP uses interfaces and named operations to expose your service. REST uses URI and methods like (GET, PUT, POST, DELETE) to expose resources. Performance is slow as compared to REST. REST is fast as compared to SOAP.

-------------------------------------------------------------------------------------------------------------------

Fundamental:

Tttt

Q4. What is ASP.NET WEB API? Ans. ASP.NET WEB API is a framework for building HTTP services that can be consume by a broad range of clients including browsers, mobiles, iphone and tablets. It is very similar to ASP.NET MVC since it contains the MVC features such as routing, controllers, action results, filter, model binders, IOC container or dependency injection. But it is not a part of the MVC Framework. It is a part of the core ASP.NET platform and can be used with MVC and other types of Web applications like ASP.NET WebForms. It can also be used as a stand-alone Web services application.

ASP.NET WEB API features

1. It supports convention-based CRUD Actions since it works with HTTP verbs GET, POST,

PUT and DELETE.

2. Responses have an Accept header and HTTP status code.

3. Responses are formatted by WEB API’s MediaTypeFormatter into JSON, XML or whatever

format you want to add as a MediaTypeFormatter.

4. It may accepts and generates the content which may not be object oriented like images, PDF

files etc.

5. It has automatic support for OData. Hence by placing the new [Queryable] attribute on a

controller method that returns IQueryable, clients can use the method for OData query composition.

6. It can be hosted with in the applicaion or on IIS.

7. It also supports the MVC features such as routing, controllers, action results, filter, model

binders, IOC container or dependency injection that makes it more simple and robust.

Q5. Why to choose ASP.NET WEB API?

Ans. Today, a web-based application is not enough to reach it's customers. People are very smart, they are using iphone, mobile, tablets etc. devices in its daily life. These devices also have a lot of apps for making the life easy. Actually, we are moving from the web towards apps world. DOT NET TRICKS TRAINING CENTER B 64, Near SBI Bank, Sector 2 Noida, Metro Noida Sector 15, Uttar Pradesh (India) www.dotnet-tricks.com, www.dotnettricks.com +91 98 71 749695, +91 120 426 5198

Page80

Training Highlights Learn from qualified and experienced professional Small batches to ensure personal attention Hands-on real application development Recorded session of your class Training course material Prepare yourself for interview and get great jobs So, if you like to expose your service data to the browsers and as well as all these modern devices apps in fast and simple way, you should have an API which is compatible with browsers and all these devices. For example twitter, facebook and Google API for the web application and phone apps. WEB API is the great framework for exposing your data and service to different-different devices. Moreover WEB API is open source an ideal platform for building REST-ful services over the .NET Framework. Unlike WCF Rest service, it use the full featues of HTTP (like URIs, request/response headers, caching, versioning, various content formats) and you don't need to define any extra config settings for different devices unlike WCF Rest service.

Why to choose WEB API

1. If we need a Web Service and don’t need SOAP, then ASP.NET WEB API is best choice.

2. It is used to build simple, non-SOAP-based HTTP Services on top of existing WCF message

pipeline.

3. It doesn't have tedious and extensive configuration like WCF REST service.

4. Simple service creation with WEB API. With WCF REST Services, service creation is difficult.

5. It is only based on HTTP and easy to define, expose and consume in a REST-ful way.

6. It is light weight architecture and good for devices which have limited bandwidth like smart

phones.

7. It is open source.

WCF and WEB API and WCF REST and Web Service?

Ans.

such as Web Service, WCF and now WEB API. There are following differences among these four:

Web Service

.NET framework has a number of technologies that allow you to create HTTP services

1. It is based on SOAP and return data in XML form.

3.

It is not open source but can be consumed by any client that understands xml.

4. It can be hosted only on IIS.

DOT NET TRICKS TRAINING CENTER

B 64, Near SBI Bank, Sector 2 Noida, Metro Noida Sector 15, Uttar Pradesh (India) www.dotnet-tricks.com, www.dotnettricks.com +91 98 71 749695, +91 120 426 5198

Page81

Training Highlights Learn from qualified and experienced professional Small batches to ensure personal attention Hands-on real application development Recorded session of your class Training course material Prepare yourself for interview and get great jobs WCF

1. It is also based on SOAP and return data in XML form.

2. It is the evolution of the web service (ASMX) and support various protocols like TCP, HTTP,

HTTPS, Named Pipes, MSMQ.

3. The main issue with WCF is, its tedious and extensive configuration.

4. It is not open source but can be consumed by any client that understands xml.

5. It can be hosted with in the application or on IIS or using window service.

WCF Rest

1. To use WCF as WCF Rest service you have to enable webHttpBindings.

2. It support HTTP GET and POST verbs by [WebGet] and [WebInvoke] attributes respectively.

3. To enable other HTTP verbs you have to do some configuration in IIS to accept request of

that particular verb on .svc files

4. Passing data through parameters using a WebGet needs configuration. The UriTemplate

must be specified

5. It support XML, JSON and ATOM data format.

WEB API

1. This is the new framework for building HTTP services with easy and simple way.

2. WEB API is open source an ideal platform for building REST-ful services over the .NET

Framework.

3. Unlike WCF Rest service, it use the full features of HTTP (like URIs, request/response

headers, caching, versioning, various content formats)

4. It also supports the MVC features such as routing, controllers, action results, filter, model

binders, IOC container or dependency injection, unit testing that makes it more simple and robust.

5. It can be hosted with in the application or on IIS.

6. It is light weight architecture and good for devices which have limited bandwidth like smart

phones.

7. Responses are formatted by WEB API’s MediaTypeFormatter into JSON, XML or whatever

format you want to add as a MediaTypeFormatter.

WCF and WEB API?

Ans. The following points help you to choose between WCF and WEB API:

1. Choose WCF when you want to create a service that should support special scenarios such

as one way messaging, message queues, duplex communication etc.

2. Choose WCF when you want to create a service that can use fast transport channels when

available, such as TCP, Named Pipes, or maybe even UDP (in WCF 4.5), and you also want to support HTTP when all other transport channels are unavailable.

3. Choose WEB API when you want to create resource-oriented services over HTTP that can

use the full features of HTTP (like URIs, request/response headers, caching, versioning, various content formats).

4. Choose WEB API when you want to expose your service to a broad range of clients including

browsers, mobiles, iphone and tablets. DOT NET TRICKS TRAINING CENTER

B 64, Near SBI Bank, Sector 2 Noida, Metro Noida Sector 15, Uttar Pradesh (India)

www.dotnet-tricks.com, www.dotnettricks.com +91 98 71 749695, +91 120 426 5198

Page82

Training Highlights Learn from qualified and experienced professional Small batches to ensure personal attention Hands-on real application development Recorded session of your class Training course material Prepare yourself for interview and get great jobs

ASP.NET MVC and ASP.NET WEB API?

Ans. There are following differences between ASP.NET MVC and WEB API:

1. ASP.NET MVC is used to create web applications that return both views and data but

ASP.NET WEB API is used to create full blown HTTP services with easy and simple way that returns only data not view.

2. WEB API helps to build REST-ful services over the .NET Framework and it also support

content-negotiation(it's about deciding the best response format data that could be acceptable by the client. it could be JSON,XML,ATOM or other formatted data), self-hosting which are not

in

MVC.

3.

WEB API also takes care of returning data in particular format like JSON, XML or any other

based upon the Accept header in the request and you don't worry about that. MVC only return data in JSON format using JsonResult.

4. In WEB API the request are mapped to the actions based on HTTP verbs but in MVC it is

mapped to actions name.

5. ASP.NET WEB API is new framework and part of the core ASP.NET framework. The model

binding, filters, routing and others MVC features exist in WEB API are different from MVC and exists in the new System.Web.Http assembly. In MVC, these features exist within System.Web.Mvc. Hence WEB API can also be used with ASP.NET and as a stand-alone service layer.

6.

You can mix WEB API and MVC controller in a single project to handle advanced AJAX

requests which may return data in JSON, XML or any others format and building a full blown HTTP service. Typically, this will be called WEB API self-hosting.

7. When you have mixed MVC and WEB API controller and you want to implement the

authorization then you have to create two filters one for MVC and another for WEB API since both are different.

8. Moreover, WEB API is light weight architecture and except the web application it can also be

used with smart phone apps.

Q9. Can you return view by using WEB API method?

Ans. Unlike ASP.NET MVC, WEB API is used to return only data. The data can be string, JSON, XML, Text etc. It cannot return View like ASP.NET MVC. DOT NET TRICKS TRAINING CENTER

B 64, Near SBI Bank, Sector 2 Noida, Metro Noida Sector 15, Uttar Pradesh (India)

www.dotnet-tricks.com, www.dotnettricks.com +91 98 71 749695, +91 120 426 5198

Page83

Training Highlights Learn from qualified and experienced professional Small batches to ensure personal attention Hands-on real application development Recorded session of your class Training course material Prepare yourself for interview and get great jobs

Q10. Can you change WEB API action name like ASP.NET MVC? Ans. Like ASP.NET MVC, you can also change WEB API action name by using ActionName attribute as given below: [HttpGet] [ActionName("GetProducts")] public IEnumerable<Product> ProductList() { return db.Products.AsEnumerable(); }

Restrict a WEB API action method Q11. Can you restrict a WEB API action method to be invoked only by HTTP GET, POST, PUT or DELETE? Ans. Like ASP.NET MVC, you can also restrict WEB API action method to be invoked only by a specific HTTP request by applying HttpGet or HttpPost or HttpPut or HttpDelete attribute.

If you want to restrict an action method for HTTP Get request only then decorate it with HttpGet action method selector attribute as given below: [HttpGet] public IEnumerable<Product> ProductList() { return db.Products.AsEnumerable(); }

Q12. How to call WEB API in ASP.NET MVC? Ans. ASP.NET WEB API can be called by using HttpClient and WEB API address as given below: public class ProductController : Controller { HttpClient Client = new HttpClient(); Uri BaseAddress = new Uri("http://localhost:131/"); public ActionResult Index() { Client.BaseAddress = BaseAddress; HttpResponseMessage response =

Client.GetAsync("productservice/GetProducts").Result; if (response.IsSuccessStatusCode) { var data = response.Content.ReadAsAsync<IEnumerable<Product>>().Result; return View(data); } return View(); } } DOT NET TRICKS TRAINING CENTER B 64, Near SBI Bank, Sector 2 Noida, Metro Noida Sector 15, Uttar Pradesh (India) www.dotnet-tricks.com, www.dotnettricks.com +91 98 71 749695, +91 120 426 5198

Page84

Training Highlights Learn from qualified and experienced professional Small batches to ensure personal attention Hands-on real application development Recorded session of your class Training course material Prepare yourself for interview and get great jobs

---------------------------------------------------------------------------------------------------------------------------

Routing:

Aaaaa

Q13. How ASP.NET WEB API routing is different from ASP.NET MVC routing? Ans. ASP.NET MVC and ASP.NET WEB API both use routing to monitor incoming request and

at least one route is defined in order to function. The difference between these two routing is given below:

1. In WEB API route pattern {action} parameter is optional but you can include an {action}

parameter. In ASP.NET MVC {action} parameter is mandatory.

2. The action methods defined in the API controller must either have the HTTP action verbs

(GET, POST, PUT, DELETE) attribute or have one of the HTTP action verbs as a prefix for the actions methods name. In ASP.NET MVC, by default an action method can be called by HTTP GET or POST verbs and for using others HTTP verbs you need to defined as an attribute.

3. Unlike ASP.NET MVC, Web API can receive only one complex type as a parameter.

Q14. How to enable Attribute Routing in ASP.NET WEB API2? Ans. Enabling attribute routing in your ASP.NET WEB API2 is simple, just add a call to MapHttpAttributeRoutes() method with in Register() method of WebApiConfig.cs file. public static class WebApiConfig { public static void Register(HttpConfiguration config) { //enabling attribute routing config.MapHttpAttributeRoutes(); } } You can also combine attribute routing with convention-based routing. public static class WebApiConfig { public static void Register(HttpConfiguration config) { //enabling attribute routing config.MapHttpAttributeRoutes(); // Convention-based routing. config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }

Q15. How to define attribute routing in ASP.NET WEB API2?

Ans. Like ASP.NET MVC5, you can also define attribute routing in WEB API2 at controller level and action level as shown below:

DOT NET TRICKS TRAINING CENTER

B 64, Near SBI Bank, Sector 2 Noida, Metro Noida Sector 15, Uttar Pradesh (India)

www.dotnet-tricks.com, www.dotnettricks.com +91 98 71 749695, +91 120 426 5198

Page85

Training Highlights

Learn from qualified and experienced professional Small batches to ensure personal attention Hands-on real application development Recorded session of your class Training course material Prepare yourself for interview and get great jobs

1. Controller level routing – You can define routes at controller level which apply to all actions

within the controller unless a specific route is added to an action. [RoutePrefix("Service/User")] public class UserController : ApiController { //GET route: api/User public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } [Route("{id}")] //GET route: Service/User/1 public string Get(int id) { return "value"; } [Route("")] //POST route: Service/User/ public void Post([FromBody]string value) { } }

2. Action level routing – You can define routes at action level which apply to a specific action

with in the controller. public class UserController : ApiController { //GET route: api/User public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; }

[Route("Service/User/{id}")] //GET route: Service/User/1 public string Get(int id) { return "value"; } [Route("Service/User/")] //POST route: Service/User/ public void Post([FromBody]string value) { } } DOT NET TRICKS TRAINING CENTER

B 64, Near SBI Bank, Sector 2 Noida, Metro Noida Sector 15, Uttar Pradesh (India)

---------------------------------------------------------------------------------------------------------------------

Swatch QA Web API

http://www.dotnet-tricks.com/Tutorial/webapi/VG9K040413-What-is-Web-API-and-why-to-use-it-

?.html

-- WebAPI

1. What is web API, why we u How to create and how to consume using server side and ajaxse

what is use it.

2. advantages over others

3. verbs

4. Routing

6.

Cors baisc token authentication

7. How to create and how to consume using server side and ajax.

8. What is RestFull

What is Web API and why to use it ? Asp.Net Web API is a framework for building HTTP services that can be consumed by a broad range of clients including browsers, mobiles, iphone and tablets. It is very similar to ASP.NET

MVC since it contains the MVC features such as routing, controllers, action results, filter, model binders, IOC container or dependency injection. But it is not a part of the MVC Framework. It is

a part of the core ASP.NET platform and can be used with MVC and other types of Web

applications like Asp.Net WebForms. It can also be used as an stand-alone Web services application.

Why Asp.Net Web API (Web API) ? Today, a web-based application is not enough to reach it's customers. People are very smart, they are using iphone, mobile, tablets etc. devices in its daily life. These devices also have a lot of apps for making the life easy. Actually, we are moving from the web towards apps world. So, if you like to expose your service data to the browsers and as well as all these modern devices apps in fast and simple way, you should have an API which is compatible with browsers and all these devices. For example twitter,facebook and Google API for the web application and phone apps.

Web API is the great framework for exposing your data and service to different-different

devices. Moreover Web API is open source an ideal platform for building REST-ful services over the .NET Framework. Unlike WCF Rest service, it use the full featues of HTTP (like URIs, request/response headers, caching, versioning, various content formats) and you don't need to define any extra config settings for different devices unlike WCF Rest service. Web API Features

It supports convention-based CRUD Actions since it works with HTTP verbs GET,POST,PUT and DELETE. Responses have an Accept header and HTTP status code. Responses are formatted by Web API’s MediaTypeFormatter into JSON, XML or whatever format you want to add as a MediaTypeFormatter.

It may accepts and generates the content which may not be object oriented like images, PDF files etc.

It has automatic support for OData. Hence by placing the new [Queryable] attribute on a

controller method that returns IQueryable, clients can use the method for OData query composition.

It can be hosted with in the applicaion or on IIS.

It also supports the MVC features such as routing, controllers, action results, filter, model binders, IOC container or dependency injection that makes it more simple and robust.

Why to choose Web API ?

If we need a Web Service and don’t need SOAP, then ASP.Net Web API is best choice. It is Used to build simple, non-SOAP-based HTTP Services on top of existing WCF message pipeline. It doesn't have tedious and extensive configuration like WCF REST service. Simple service creation with Web API. With WCF REST Services, service creation is difficult. It is only based on HTTP and easy to define, expose and consume in a REST-ful way. It is light weight architecture and good for devices which have limited bandwidth like smart phones. It is open source.

-------------------------------------------------------------------------------------------------------------

WCF and Web API and WCF REST and Web Service The .Net framework has a number of technologies that allow you to create HTTP services such as Web Service, WCF and now Web API. There are a lot of articles over the internet which may describe to whom you should use. Now a days, you have a lot of choices to build HTTP services on .NET framework. In this article, I would like to share my opinion with you over Web Service, WCF and now Web API. For more information about Web API refers

What is Web API and why to use it ?. Web Service It is based on SOAP and return data in XML form. It support only HTTP protocol. It is not open source but can be consumed by any client that understands xml. It can be hosted only on IIS. WCF It is also based on SOAP and return data in XML form. It is the evolution of the web service(ASMX) and support various protocols like TCP, HTTP, HTTPS, Named Pipes, MSMQ. The main issue with WCF is, its tedious and extensive configuration. It is not open source but can be consumed by any client that understands xml. It can be hosted with in the applicaion or on IIS or using window service. WCF Rest To use WCF as WCF Rest service you have to enable webHttpBindings. It support HTTP GET and POST verbs by [WebGet] and [WebInvoke] attributes respectively. To enable other HTTP verbs you have to do some configuration in IIS to accept request of that particular verb on .svc files Passing data through parameters using a WebGet needs configuration. The UriTemplate must be specified It support XML, JSON and ATOM data format. Web API This is the new framework for building HTTP services with easy and simple way. Web API is open source an ideal platform for building REST-ful services over the .NET Framework.

Unlike WCF Rest service, it use the full featues of HTTP (like URIs, request/response headers, caching, versioning, various content formats) It also supports the MVC features such as routing, controllers, action results, filter, model binders, IOC container or dependency injection, unit testing that makes it more simple and robust. It can be hosted with in the application or on IIS. It is light weight architecture and good for devices which have limited bandwidth like smart phones. Responses are formatted by Web API’s MediaTypeFormatter into JSON, XML or whatever format you want to add as a MediaTypeFormatter.

To whom choose between WCF or WEB API Choose WCF when you want to create a service that should support special scenarios such as one way messaging, message queues, duplex communication etc. Choose WCF when you want to create a service that can use fast transport channels when available, such as TCP, Named Pipes, or maybe even UDP (in WCF 4.5), and you also want to support HTTP when all other transport channels are unavailable. Choose Web API when you want to create a resource-oriented services over HTTP that can use the full features of HTTP (like URIs, request/response headers, caching, versioning, various content formats). Choose Web API when you want to expose your service to a broad range of clients including browsers, mobiles, iphone and tablets. What do you think? I hope, you have got when to use WCF, Web API and Web Service. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

-------------------------------------------------------------------------------------------------------------

ASP.NET MVC and ASP.NET Web API While developing your web application using MVC, many developers got confused when to use Web API, since MVC framework can also return JSON data by using JsonResult and can also handle simple AJAX requests. In previous article, I have explained the Difference between WCF and Web API and WCF REST and Web Service and when to use Web API over others services. In this article, you will learn when to use Web API with MVC.

Asp.Net Web API VS Asp.Net MVC Asp.Net MVC is used to create web applications that returns both views and data but Asp.Net Web API is used to create full blown HTTP services with easy and simple way that returns only data not view. Web API helps to build REST-ful services over the .NET Framework and it also support content-negotiation(it's about deciding the best response format data that could be acceptable by the client. it could be JSON,XML,ATOM or other formatted data), self hosting which are not in MVC.

Web API also takes care of returning data in particular format like JSON,XML or any other based upon the Accept header in the request and you don't worry about that. MVC only return data in JSON format using JsonResult. In Web API the request are mapped to the actions based on HTTP verbs but in MVC it is mapped to actions name. Asp.Net Web API is new framework and part of the core ASP.NET framework. The model binding, filters, routing and others MVC features exist in Web API are different from MVC and exists in the new System.Web.Http assembly. In MVC, these featues exist with in System.Web.Mvc. Hence Web API can also be used with Asp.Net and as a stand alone service layer. You can mix Web API and MVC controller in a single project to handle advanced AJAX requests which may return data in JSON, XML or any others format and building a full blown HTTP service. Typically, this will be called Web API self hosting. When you have mixed MVC and Web API controller and you want to implement the authorization then you have to create two filters one for MVC and another for Web API since boths are different. Moreover, Web API is light weight architecture and except the web application it can also be used with smart phone apps.

-------------------------------------------------------------------------------------------------------------

Pass javascript complex object to ASP.NET Web Api and MVC ASP.NET Web API is one of the most powerful recent addition to ASP.NET framework. Sometimes, you have to post a form data using jQuery-JSON to Web API or MVC method, which have so many input fields. Passing each and every input field data as a separate parameter is not good practice, even when you have a strongly typed-view. The best practice is, pass a complex type object for all the input fields to the server side to remove complexity.

-------------------------------------------------------------------------------------------------------------

Comparing Asp.Net Web API Routing and Asp.Net MVC Routing

As you know, Routing is a pattern matching system that monitor the incoming request and figure out what to do with that request. A URL pattern is matched against the routes patterns defined in the Route dictionary in an Order and the first match wins. This means the first route which successfully matches a controller, action, and action parameters defined in the URL will call into the specified controller and action. Asp.Net MVC application and Asp.Net Web API must have at least one route defined in order to function. Hence, Visual Studio templates defined for MVC and Web API must have a default route. Now let's understand the difference between Asp.Net MVC and Asp.Net Web API. Default Route Pattern The default route pattern for a Web API Project is defined as follows- config.Routes.MapHttpRoute( name: "DefaultApi", //route name routeTemplate: "api/{controller}/{id}", //route pattern

defaults: new { id = RouteParameter.Optional } //parameter default values );

The literal api at the beginning of the Web API route pattern, makes it distinct from the standard MVC route. This is not mandatory but it is a good convention to differ Web API route from MVC route. In Web API route pattern {action} parameter is optional but you can include an {action} parameter. Also, the action methods defined on the controller must be have an HTTP action verb as a prefix to the method name in order to work. So, you can also define the route for Web API as follows- config.Routes.MapHttpRoute( name: "DefaultApi",//route name routeTemplate: "api/{controller}/{action}/{id}",//route pattern defaults: new { id = RouteParameter.Optional }//parameter default values ); The default route pattern for an Asp.Net MVC Project is defined as follows- routes.MapRoute( name: "Default", //route name url: "{controller}/{action}/{id}", //route pattern defaults: new

{

controller = "Home", action = "Index", id = UrlParameter.Optional } //parameter default values );

As you have seen there is no literal before at the beginning of the Asp.Net MVC route pattern but you can add if you wish. Route Processing In Web API route processing the URLs map to a controller, and then to the action which matches the HTTP verb of the request and the most parameters of the request is selected. The Action methods defined in the API controller must either have the HTTP action verbs (GET, POST, PUT, DELETE) or have one of the HTTP action verbs as a prefix for the Actions methods name as given below- public class ValuesController : ApiController

{

// GET api/

public IEnumerable Get()

{

return new string[] { "value1", "value2" };

}

// GET api//5

public string Get(int id)

{

return "value";

}

// POST api/

public void Post([FromBody]string value)

{

}

// PUT api//5

public void Put(int id, [FromBody]string value)

{

}

// DELETE api//5

public void Delete(int id)

{

}

}

// OR You can also defined above API Controller as Verb Prefix public class ValuesController : ApiController

{

// GET api/values

public IEnumerable GetValues()

{

return new string[] { "value1", "value2" };

}

// GET api/values/5

public string GetValues(int id)

{

return "value";

}

// POST api/values

public void PostValues([FromBody]string value)

{

}

// PUT api/values/5

public void PutValues(int id, [FromBody]string value)

{

}

// DELETE api/values/5

public void DeleteValues(int id)

{

}

}

In Asp.Net MVC route processing the URLs map to a controller, and then to the action which matches the HTTP verb of the request and the most parameters of the request is selected. The

Action methods defined in the MVC controller do not have HTTP action verbs as a prefix for the Actions methods but they have name like as normal method as shown below- public class HomeController : Controller

{

// GET: /Home/Index

public ActionResult Index() //method - Index

{

// To Do:

return View();

}

// Post: /Home/Index [HttpPost]

public ActionResult Index(LoginModel model, string id)

{

// To Do:

return View();

}

}

In MVC, by default HTTP verb is GET for using others HTTP verbs you need defined as an attribute but in Web API you need to define as an method's name prefix.

-------------------------------------------------------------------------------------------------------------

Verbs:

List

Post The POST verb is most-often utilized to **create** new resources. In particular, it's used to create subordinate resources. That is, subordinate to some other (e.g. parent) resource. In other words, when creating a new resource, POST to the parent and the service takes care of associating the new resource with the parent, assigning an ID (new resource URI), etc. On successful creation, return HTTP status 201, returning a Location header with a link to the newly-created resource with the 201 HTTP status. POST is neither safe nor idempotent. It is therefore recommended for non-idempotent resource requests. Making two identical POST requests will most-likely result in two resources containing the same information.

Get The HTTP GET method is used to **read** (or retrieve) a representation of a resource. In the “happy” (or non-error) path, GET returns a representation in XML or JSON and an HTTP response code of 200 (OK). In an error case, it most often returns a 404 (NOT FOUND) or 400 (BAD REQUEST).

According to the design of the HTTP specification, GET (along with HEAD) requests are used only to read data and not change it. Therefore, when used this way, they are considered safe. That is, they can be called without risk of data modification or corruption—calling it once has the same effect as calling it 10 times, or none at all. Additionally, GET (and HEAD) is idempotent, which means that making multiple identical requests ends up having the same result as a single request. Do not expose unsafe operations via GET—it should never modify any resources on the server.

PUT PUT is most-often utilized for **update** capabilities, PUT-ing to a known resource URI with the request body containing the newly-updated representation of the original resource. However, PUT can also be used to create a resource in the case where the resource ID is chosen by the client instead of by the server. In other words, if the PUT is to a URI that contains the value of a non-existent resource ID. Again, the request body contains a resource representation. Many feel this is convoluted and confusing. Consequently, this method of creation should be used sparingly, if at all. Alternatively, use POST to create new resources and provide the client-defined ID in the body representation—presumably to a URI that doesn't include the ID of the resource (see POST below). On successful update, return 200 (or 204 if not returning any content in the body) from a PUT. If using PUT for create, return HTTP status 201 on successful creation. A body in the response is optional—providing one consumes more bandwidth. It is not necessary to return a link via a Location header in the creation case since the client already set the resource ID. PUT is not a safe operation, in that it modifies (or creates) state on the server, but it is idempotent. In other words, if you create or update a resource using PUT and then make that same call again, the resource is still there and still has the same state as it did with the first call. If, for instance, calling PUT on a resource increments a counter within the resource, the call is no longer idempotent. Sometimes that happens and it may be enough to document that the call is not idempotent. However, it's recommended to keep PUT requests idempotent. It is strongly recommended to use POST for non-idempotent requests.

PATCH PATCH is used for **modify** capabilities. The PATCH request only needs to contain the changes to the resource, not the complete resource. This resembles PUT, but the body contains a set of instructions describing how a resource currently residing on the server should be modified to produce a new version. This means that the PATCH body should not just be a modified part of the resource, but in some kind of patch language like JSON Patch or XML Patch. PATCH is neither safe nor idempotent. However, a PATCH request can be issued in such a way as to be idempotent, which also helps prevent bad outcomes from collisions between two PATCH requests on the same resource in a similar time frame. Collisions from multiple PATCH requests may be more dangerous than PUT collisions because some patch formats need to operate from a known base-point or else they will corrupt the resource. Clients using this kind of

patch application should use a conditional request such that the request will fail if the resource has been updated since the client last accessed the resource. For example, the client can use a strong ETag in an If-Match header on the PATCH request.

DELETE DELETE is pretty easy to understand. It is used to **delete** a resource identified by a URI. On successful deletion, return HTTP status 200 (OK) along with a response body, perhaps the representation of the deleted item (often demands too much bandwidth), or a wrapped response (see Return Values below). Either that or return HTTP status 204 (NO CONTENT) with no response body. In other words, a 204 status with no body, or the JSEND-style response and HTTP status 200 are the recommended responses. HTTP-spec-wise, DELETE operations are idempotent. If you DELETE a resource, it's removed.

Repeatedly calling DELETE on that resource ends up the same: the resource is gone. If calling DELETE say, decrements a counter (within the resource), the DELETE call is no longer idempotent. As mentioned previously, usage statistics and measurements may be updated while still considering the service idempotent as long as no resource data is changed. Using POST for non-idempotent resource requests is recommended. There is a caveat about DELETE idempotence, however. Calling DELETE on a resource a second time will often return a 404 (NOT FOUND) since it was already removed and therefore is no longer findable. This, by some opinions, makes DELETE operations no longer idempotent, however, the end-state of the resource is the same. Returning a 404 is acceptable and communicates accurately the status of the call.

------------------

Following up after the earlier post titled Using HTTP Status Codes correctly in your REST Web API, here is one on using the HTTP Verbs from the W3C spec in the "right way" to have a clean REST Web API. Just like the HTTP status codes, there are many more verbs in the HTTP standard that, although they are in theory OK to use for your Web API, you can get by with just a few that helps to keep your API simple, and self-explanatory to its clients.

The full list of HTTP verbs from the spec can be found HERE, but we are going to focus on how to interpret the verbs and the actions that should be executed for each on in the context of a well-defined REST Web API. In the table there is also the result set that standard clients expect when they make requests with such VERBs. To better understand their proper use, we'll use a sample resource endpoint called Users, where the (you guessed it) "Users" of our app are exposed via our Web API.

Resource Sample

DELETE (aka delete) PATCH (aka partial update)

api/users Action

Batch Update the users only with the attributes present in the request

Return List of users

Code

GET (aka Read)

POST (aka insert)

Creates a user

PUT (aka update)

Batch Update Errors out

Gets a list of users

New user

No payload, only HTTP Status Code Error HTTP Status

No payload, only HTTP Status Code

api/users/123 Action Gets a single user

user

Return Single user

Errors out

Updates the user

Deletes the

Partially updates the user only with the attributes present in the request

Error HTTP Status Code

Updated user No payload, only HTTP

Status Code

Updated full user object

-------------

Using HTTP Methods (GET, POST, PUT, etc.) in Web API December 6th, 2015 asp.net · tutorials · web-api · http

My group has been studying ASP.NET Web API for a major project we're working on, and part

of learning about this tech stack is studying how HTTP works, which has been a nice refresher

for us. A couple of my teammates asked me to clarify the HTTP Methods (e.g. GET, POST, PUT, DELETE, etc) we were going to use for specific actions, and I wanted to learn more about them. Hence, this post. Come along with us as we learn about HTTP methods (also called verbs) and discuss how and when to use them in our Web API projects!

What Are HTTP Methods?

Whenever a client submits a request to a server, part of that request is an HTTP method, which

is what the client would like the server to do with the specified resource. HTTP methods

represent those requested actions. For example, some commonly-used HTTP methods will retrieve data from a server, submit data to a server for processing, delete an item from the server's data store, etc. For a more general overview of HTTP, see Tutorials Point's article.

Selecting The Appropriate Method

A large portion of application functionality can be summed up in the acronym CRUD, which

stands for Create, Read, Update, Delete. There are four HTTP methods that correspond to these actions, one for each, like so:

C

- Create - POST

R

- Read - GET

U

- Update - PUT

D

- Delete - DELETE

So, in a given app, you might have the following action:

public IHttpActionResult Add(string title)

{

//Creates a Movie based on the Title return Ok();

}

We can tell from the name of the action (and, let's be real, the comment) that this action is supposed to create a movie. So we should use the POST verb on this action, like so:

[HttpPost]

public IHttpActionResult Add(string title)

{

//Creates a Movie based on the Title return Ok();

}

If you need a particular action to support more than one HTTP method, you can use the [AcceptVerbs] attribute:

[AcceptVerbs("POST", "PUT")]

public IHttpActionResult Add(string title)

{

//Creates a Movie based on the Title return Ok();

}

For the majority of applications, GET, POST, PUT, and DELETE should be all the HTTP methods you need to use. However, there are a few other methods we could utilize if the need arises.

HEAD: This is identical to a GET request, but only returns the headers for the response, not the response body. Theoretically faster, commonly used for checking to see if a particular resources exists or can be accessed. OPTIONS: Returns the HTTP methods supported by the server for the specified URL. PATCH: Submits a partial modification to a resource. If you only need to update one field for the resource, you may want to use the PATCH method. POST vs PUT

POST and PUT are very similar in that they both send data to the server that the server will need to store somewhere. Technically speaking, you could use either for the Create or Update scenarios, and in fact this is rather common. The difference lies in the details.

PUT is idempotent. What this means is that if you make the same request twice using PUT, with the same parameters both times, the second request will have no effect. This is why PUT is generally used for the Update scenario; calling Update more than once with the same parameters doesn't do anything more than the first call did.

By contrast, POST is not idempotent; making the same call using POST with same parameters each time will cause two different things to happen, hence why POST is commonly used for the Create scenario (submitting two identical items to a Create method should create two entries in the data store).

(It should be noted that, strictly speaking, HTTP does not force PUT to be idempotent, so you can implement your server to use PUT in a non-idempotent way. However, doing so is liable to cause a horde of angry server admins to show up at your desk and beat you with ethernet cables. Don't say I didn't warn you.)

Default HTTP Methods

If we do not assign an explicit HTTP method to a controller action, what method(s) does that action accept? Let's imagine we have a Web API controller like so:

public class MovieController : ApiController

{

/// <summary> /// Returns all movies. /// </summary>

/// <returns>A JSON list of all movies.</returns> [Route("movies/all")] public IHttpActionResult All()

{

List<Movie> movies = new List<Movie>()

{

new Movie()

{

Id = 1, Title = "Up", ReleaseDate = new DateTime(2009,5,29), RunningTimeMinutes = 96

},

new Movie()

{

Id = 2, Title = "Toy Story", ReleaseDate = new DateTime(1995, 11, 19), RunningTimeMinutes = 81

},

new Movie()

{

Id = 3, Title = "Big Hero 6", ReleaseDate = new DateTime(2014, 11, 7), RunningTimeMinutes = 102

}

};

return Ok(movies);

}

}

We can tell by looking at the code that this should be a GET action, since it is returning data. However, we're not explicitly saying that GET should be used (there's no [HttpGet] attribute). So, what method(s) will this action accept? Let's see what Postman can tell us.

It should be a GET action, so let's try to hit this action with a GET request.

Well, that didn't work, we get back a 405 Method Not Allowed status. Why were we not able to use the GET method?

The algorithm ASP.NET uses to calculate the "default" method for a given action goes like this:

If there is an attribute applied (via [HttpGet], [HttpPost], [HttpPut], [AcceptVerbs], etc), the action will accept the specified HTTP method(s). If the name of the controller action starts the words "Get", "Post", "Put", "Delete", "Patch", "Options", or "Head", use the corresponding HTTP method. Otherwise, the action supports the POST method. We're falling in to the #3 condition here: the action name All() doesn't contain any of the key words and we didn't specify an action, so this action will only support POST. Sure enough, guess what Postman shows for a POST action?

Obviously, this is not what we want. We're getting data from the server using a POST method, and this (while not technologically prevented) is not what these HTTP methods were designed for.

We could solve this problem in two ways. The first would be to add the [HttpGet] attribute to the method. The second would be to rename the method to GetAll(); the existence of the word "Get" at the start of the method tells ASP.NET to accept a GET HTTP method on this action. My personal preference is to always explicitly state which HTTP method is accepted by any action, like so:

public class MovieController : ApiController

{

/// <summary> /// Returns all movies.

/// </summary> /// <returns>A JSON list of all movies.</returns> [Route("movies/all")]

[HttpGet] //Always explicitly state the accepted HTTP method public IHttpActionResult All()

{

//Get movies return Ok(movies);

}

}

-------------------------------------------------------------------------------------------------------------

What is REST? REST stands for Representational state transfer which essentially refers to a style of web architecture that has many underlying characteristics and governs the behavior of clients and servers.

What can use a REST API? REST API lets you interact with Parse from anything that can send an HTTP request. See Parse REST Definition for examples of this.

What is meant by the term “RESTful API”? Conforming to the REST constraints is generally referred to as being “RESTful” An API can be considered “RESTful” if it has the following features (not a complete list just the main ones):

Client–server – The client handles the front end the server handles the backend and can both be replaced independently of each other. Stateless – No client data is stored on the server between requests and session state is stored on the client. Cacheable – Clients can cache response (just like browsers caching static elements of a web page) to improve performance. Complying with these constraints, and thus conforming to the REST architectural style enables any kind of distributed hypermedia system to have desirable emergent properties, such as performance, scalability, simplicity, modifiability, visibility, portability, and reliability. A common trend I have seen is to use absolute urls for RESTful APIs which are meaningful.

What is REST ? REST stands for REpresentational State Transfer. REST is web standards based architecture and uses HTTP Protocol for data communication. It revolves around resource where every component is a resource and a resource is accessed by a common interface using HTTP standard methods. REST was first introduced by Roy Fielding in 2000.

In REST architecture, a REST Server simply provides access to resources and REST client accesses and presents the resources. Here each resource is identified by URIs/ global IDs. REST uses various representations to represent a resource like text, JSON and XML. Now a days JSON is the most popular format being used in web services.

HTTP Methods Following well known HTTP methods are commonly used in REST based architecture. GET - Provides a read only access to a resource. PUT - Used to create a new resource. DELETE - Used to remove a resource. POST - Used to update a existing resource or create a new resource. OPTIONS - Used to get the supported operations on a resource.

RESTFul Web Services A web service is a collection of open protocols and standards used for exchanging data between applications or systems. Software applications written in various programming languages and running on various platforms can use web services to exchange data over computer networks like the Internet in a manner similar to inter-process communication on a

single computer. This interoperability (e.g., between Java and Python, or Windows and Linux applications) is due to the use of open standards. Web services based on REST Architecture are known as RESTful web services. These web services use HTTP methods to implement the concept of REST architecture. A RESTful web service usually defines a URI, Uniform Resource Identifier a service, provides resource representation such as JSON and set of HTTP Methods. Creating RESTFul Web Service

Sr. No.HTTP Method URI

Operation

Operation Type

1

GET

/UserService/users

Get list of users

Read Only

2

GET

/UserService/users/1 Get User with Id 1

Read Only

3

PUT

/UserService/users/2 Insert User with Id 2

Idempotent

4

POST /UserService/users/2 Update User with Id 2 N/A

5

DELETE

/UserService/users/1 Delete User with Id 1 Idempotent

6

OPTIONS

/UserService/users

List the supported operations in web serviceRead

Only

The “RESTful” Client Server Architecture HTTP, for example, has a very rich vocabulary in terms of verbs (or “methods”), URIs, Internet media types, request and response codes, etc. REST uses these existing features of the HTTP protocol, and thus allows existing layered proxy and gateway components to perform additional functions on the network such as HTTP caching and security enforcement.

RESTful Web Services (API)

A RESTful web service (also called a RESTful web API) is a web service implemented using

HTTP and the principles of REST. It is a collection of resources, with four defined aspects:

the base URI for the web service, such as http://example.com/resources/

the Internet media type of the data supported by the web service. This is often XML but can be any other valid Internet media type provided that it is a valid hypertext standard. the set of operations supported by the web service using HTTP methods (e.g., GET, PUT, POST, or DELETE).

It is a collection of resources, with four defined aspects:

the base URI for the web service, such as http://example.com/resources/ the Internet media type of the data supported by the web service. This is often JSON, XML or YAML but can be any other valid Internet media type. the set of operations supported by the web service using HTTP methods (e.g., POST, GET, PUT or DELETE). The API must be hypertext driven.[11] Popular REST API Request Formats REST XML-RPC SOAP Also see: The Main Differences Between SOAP and REST APIs

Popular REST API Response Formats I work mostly with JSON it seems to be the most popular for jQuery developers, for obvious reasons.

Do I need an API key to access a REST API? Most API’s have a request limit and might ask you to provide an API key (which you may have created an application with them). Data sensitive APIs will require you to authenticate and the most popular method is Open Authentication also known as oAuth. I’ve touched briefly on this before on How Twitter oAuth works. Won’t go into oAuth here.

Example is Google Translate requires your API Key in a GET request.

https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY&source=en&targe

t=de&q=Hello%20world

So is it a REST API or just an API? Well to decide this you will have to stufy the documentation and determine if the API satisfies the criterion to qualify it to be RESTful. The Atom API is a good example of one that truely qualifies it to be RESTful.

-----------------------------------------------------------------------------------------------------------

Authentication & Authorization

http://www.codeproject.com/Articles/1005485/RESTful-Day-sharp-Security-in-Web-APIs-Basic

-----------------------------------------------------------------------------------------------------------

Routing

Routing in ASP.NET Web API

This article describes how ASP.NET Web API routes HTTP requests to controllers.

If you are familiar with ASP.NET MVC, Web API routing is very similar to MVC routing. The main difference is that Web API uses the HTTP method, not the URI path, to select the action. You can also use MVC-style routing in Web API. This article does not assume any knowledge of ASP.NET MVC.

Routing Tables

In ASP.NET Web API, a controller is a class that handles HTTP requests. The public methods of the controller are called action methods or simply actions. When the Web API framework receives a request, it routes the request to an action.

To determine which action to invoke, the framework uses a routing table. The Visual Studio project template for Web API creates a default route:

routes.MapHttpRoute( name: "API Default", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }

); This route is defined in the WebApiConfig.cs file, which is placed in the App_Start directory:

For more information aboout the WebApiConfig class, see Configuring ASP.NET Web API .

If you self-host Web API, you must set the routing table directly on the HttpSelfHostConfiguration object. For more information, see Self-Host a Web API.

Each entry in the routing table contains a route template. The default route template for Web API is "api/{controller}/{id}". In this template, "api" is a literal path segment, and {controller} and {id} are placeholder variables.

When the Web API framework receives an HTTP request, it tries to match the URI against one of the route templates in the routing table. If no route matches, the client receives a 404 error. For example, the following URIs match the default route:

/api/contacts

/api/contacts/1

/api/products/gizmo1

However, the following URI does not match, because it lacks the "api" segment:

/contacts/1

Note: The reason for using "api" in the route is to avoid collisions with ASP.NET MVC routing. That way, you can have "/contacts" go to an MVC controller, and "/api/contacts" go to a Web API controller. Of course, if you don't like this convention, you can change the default route table.

Once a matching route is found, Web API selects the controller and the action:

To find the controller, Web API adds "Controller" to the value of the {controller} variable. To find the action, Web API looks at the HTTP method, and then looks for an action whose name begins with that HTTP method name. For example, with a GET request, Web API looks

for an action that starts with "Get

applies only to GET, POST, PUT, and DELETE methods. You can enable other HTTP methods by using attributes on your controller. We’ll see an example of that later. Other placeholder variables in the route template, such as {id}, are mapped to action parameters. Let's look at an example. Suppose that you define the following controller:

",

such as "GetContact" or "GetAllContacts". This convention

public class ProductsController : ApiController

{

public void GetAllProducts() { } public IEnumerable<Product> GetProductById(int id) { } public HttpResponseMessage DeleteProduct(int id){ }

}

Here are some possible HTTP requests, along with the action that gets invoked for each:

HTTP Method URI Path Action Parameter

GET api/products GetAllProducts (none)

GET

DELETE api/products/4 DeleteProduct 4 POST api/products (no match) Notice that the {id} segment of the URI, if present, is mapped to the id parameter of the action. In this example, the controller defines two GET methods, one with an id parameter and one with no parameters.

api/products/4 GetProductById 4

Also, note that the POST request will fail, because the controller does not define a "Post method.

"

Routing Variations

The previous section described the basic routing mechanism for ASP.NET Web API. This section describes some variations.

HTTP Methods

Instead of using the naming convention for HTTP methods, you can explicitly specify the HTTP method for an action by decorating the action method with the HttpGet, HttpPut, HttpPost, or HttpDelete attribute.

In the following example, the FindProduct method is mapped to GET requests:

public class ProductsController : ApiController

{

[HttpGet] public Product FindProduct(id) {}

}

To allow multiple HTTP methods for an action, or to allow HTTP methods other than GET, PUT, POST, and DELETE, use the AcceptVerbs attribute, which takes a list of HTTP methods.

public class ProductsController : ApiController

{

 

[AcceptVerbs("GET", "HEAD")] public Product FindProduct(id) { }

// WebDAV method [AcceptVerbs("MKCOL")] public void MakeCollection() { }

}

Routing by Action NameWith the default routing template, Web API uses the HTTP method to select the action. However, you can also create a route where the action name is included in the URI:

routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional }

);

In this route template, the {action} parameter names the action method on the controller. With this style of routing, use attributes to specify the allowed HTTP methods. For example, suppose your controller has the following method:

public class ProductsController : ApiController

{

[HttpGet] public string Details(int id);

}

In this case, a GET request for “api/products/details/1” would map to the Details method. This style of routing is similar to ASP.NET MVC, and may be appropriate for an RPC-style API.

You can override the action name by using the ActionName attribute. In the following example, there are two actions that map to "api/products/thumbnail/id. One supports GET and the other supports POST:

public class ProductsController : ApiController

{

[HttpGet] [ActionName("Thumbnail")] public HttpResponseMessage GetThumbnailImage(int id);

[HttpPost] [ActionName("Thumbnail")] public void AddThumbnailImage(int id);

}

Non-Actions

To prevent a method from getting invoked as an action, use the NonAction attribute. This signals to the framework that the method is not an action, even if it would otherwise match the routing rules.

// Not an action method. [NonAction]

public string GetPrivateData() {

----------------------

Routing and Action Selection in ASP.NET Web API By Mike Wasson|July 27, 2012 502 of 536 people found this helpful Print

This article describes how ASP.NET Web API routes an HTTP request to a particular action on

a controller.

}

For a high-level overview of routing, see Routing in ASP.NET Web API.

This article looks at the details of the routing process. If you create a Web API project and find that some requests don’t get routed the way you expect, hopefully this article will help.

Routing has three main phases:

Matching the URI to a route template. Selecting a controller. Selecting an action. You can replace some parts of the process with your own custom behaviors. In this article, I describe the default behavior. At the end, I note the places where you can customize the behavior.

Route Templates

A route template looks similar to a URI path, but it can have placeholder values, indicated with

curly braces:

"api/{controller}/public/{category}/{id}" When you create a route, you can provide default values for some or all of the placeholders:

defaults: new { category = "all" } You can also provide constraints, which restrict how a URI segment can match a placeholder:

constraints: new { id = @"\d+" }

The framework tries to match the segments in the URI path to the template. Literals in the template must match exactly. A placeholder matches any value, unless you specify constraints. The framework does not match other parts of the URI, such as the host name or the query parameters. The framework selects the first route in the route table that matches the URI.

// Only matches if "id" is one or more digits.

There are two special placeholders: "{controller}" and "{action}".

"{controller}" provides the name of the controller. "{action}" provides the name of the action. In Web API, the usual convention is to omit "{action}". Defaults

If you provide defaults, the route will match a URI that is missing those segments. For example:

routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{category}",

defaults: new { category = "all" }

); The URI "http://localhost/api/products" matches this route. The "{category}" segment is assigned the default value "all".

Route Dictionary

If the framework finds a match for a URI, it creates a dictionary that contains the value for each

placeholder. The keys are the placeholder names, not including the curly braces. The values are taken from the URI path or from the defaults. The dictionary is stored in the IHttpRouteData object.

During this route-matching phase, the special "{controller}" and "{action}" placeholders are treated just like the other placeholders. They are simply stored in the dictionary with the other values.

A default can have the special value RouteParameter.Optional. If a placeholder gets assigned

this value, the value is not added to the route dictionary. For example:

routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{category}/{id}", defaults: new { category = "all", id = RouteParameter.Optional }

); For the URI path "api/products", the route dictionary will contain:

controller: "products" category: "all" For "api/products/toys/123", however, the route dictionary will contain:

controller: "products" category: "toys" id: "123" The defaults can also include a value that does not appear anywhere in the route template. If the route matches, that value is stored in the dictionary. For example:

routes.MapHttpRoute( name: "Root", routeTemplate: "api/root/{id}", defaults: new { controller = "customers", id = RouteParameter.Optional }

);

If

the URI path is "api/root/8", the dictionary will contain two values:

controller: "customers" id: "8" Selecting a Controller

Controller selection is handled by the IHttpControllerSelector.SelectController method. This method takes an HttpRequestMessage instance and returns an HttpControllerDescriptor. The default implementation is provided by the DefaultHttpControllerSelector class. This class uses a straightforward algorithm:

Look in the route dictionary for the key "controller". Take the value for this key and append the string "Controller" to get the controller type name. Look for a Web API controller with this type name. For example, if the route dictionary contains the key-value pair "controller" = "products", then the controller type is "ProductsController". If there is no matching type, or multiple matches, the framework returns an error to the client.

For step 3, DefaultHttpControllerSelector uses the IHttpControllerTypeResolver interface to get the list of Web API controller types. The default implementation of IHttpControllerTypeResolver returns all public classes that (a) implement IHttpController, (b) are not abstract, and (c) have a name that ends in "Controller".

Action Selection

After selecting the controller, the framework selects the action by calling the IHttpActionSelector.SelectAction method. This method takes an HttpControllerContext and returns an HttpActionDescriptor.

The default implementation is provided by the ApiControllerActionSelector class. To select an action, it looks at the following:

The HTTP method of the request. The "{action}" placeholder in the route template, if present. The parameters of the actions on the controller. Before looking at the selection algorithm, we need to understand some things about controller actions.

Which methods on the controller are considered "actions"? When selecting an action, the framework only looks at public instance methods on the controller. Also, it excludes "special name" methods (constructors, events, operator overloads, and so forth), and methods inherited from the ApiController class.

HTTP Methods. The framework only chooses actions that match the HTTP method of the request, determined as follows:

You can specify the HTTP method with an attribute: AcceptVerbs, HttpDelete, HttpGet, HttpHead, HttpOptions, HttpPatch, HttpPost, or HttpPut. Otherwise, if the name of the controller method starts with "Get", "Post", "Put", "Delete", "Head", "Options", or "Patch", then by convention the action supports that HTTP method. If none of the above, the method supports POST. Parameter Bindings. A parameter binding is how Web API creates a value for a parameter. Here is the default rule for parameter binding:

Simple types are taken from the URI. Complex types are taken from the request body. Simple types include all of the .NET Framework primitive types, plus DateTime, Decimal, Guid, String, and TimeSpan. For each action, at most one parameter can read the request body.

It is possible to override the default binding rules. See WebAPI Parameter binding under the hood.

With that background, here is the action selection algorithm.

Create a list of all actions on the controller that match the HTTP request method. If the route dictionary has an "action" entry, remove actions whose name does not match this value. Try to match action parameters to the URI, as follows:

For each action, get a list of the parameters that are a simple type, where the binding gets the parameter from the URI. Exclude optional parameters. From this list, try to find a match for each parameter name, either in the route dictionary or in the URI query string. Matches are case insensitive and do not depend on the parameter order. Select an action where every parameter in the list has a match in the URI. If more that one action meets these criteria, pick the one with the most parameter matches. Ignore actions with the [NonAction] attribute. Step #3 is probably the most confusing. The basic idea is that a parameter can get its value either from the URI, from the request body, or from a custom binding. For parameters that come from the URI, we want to ensure that the URI actually contains a value for that parameter, either in the path (via the route dictionary) or in the query string.

For example, consider the following action:

public void Get(int id) The id parameter binds to the URI. Therefore, this action can only match a URI that contains a value for "id", either in the route dictionary or in the query string.

Optional parameters are an exception, because they are optional. For an optional parameter, it's OK if the binding can't get the value from the URI.

Complex types are an exception for a different reason. A complex type can only bind to the URI through a custom binding. But in that case, the framework cannot know in advance whether the parameter would bind to a particular URI. To find out, it would need to invoke the binding. The goal of the selection algorithm is to select an action from the static description, before invoking any bindings. Therefore, complex types are excluded from the matching algorithm.

After the action is selected, all parameter bindings are invoked.

Summary:

The action must match the HTTP method of the request. The action name must match the "action" entry in the route dictionary, if present. For every parameter of the action, if the parameter is taken from the URI, then the parameter name must be found either in the route dictionary or in the URI query string. (Optional parameters and parameters with complex types are excluded.) Try to match the most number of parameters. The best match might be a method with no parameters. Extended Example

Routes:

routes.MapHttpRoute( name: "ApiRoot", routeTemplate: "api/root/{id}", defaults: new { controller = "products", id = RouteParameter.Optional }

); routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }

);

Controller:

public class ProductsController : ApiController

{

public IEnumerable<Product> GetAll() {} public Product GetById(int id, double version = 1.0) {} [HttpGet] public void FindProductsByName(string name) {} public void Post(Product value) {} public void Put(int id, Product value) {}

}

HTTP request:

GET http://localhost:34701/api/products/1?version=1.5&details=1 Route Matching

The URI matches the route named "DefaultApi". The route dictionary contains the following entries:

controller: "products" id: "1" The route dictionary does not contain the query string parameters, "version" and "details", but these will still be considered during action selection.

Controller Selection

From the "controller" entry in the route dictionary, the controller type is ProductsController.

Action Selection

The HTTP request is a GET request. The controller actions that support GET are GetAll, GetById, and FindProductsByName. The route dictionary does not contain an entry for "action", so we don’t need to match the action name.

Next, we try to match parameter names for the actions, looking only at the GET actions.

Action Parameters to Match GetAll none GetById "id" FindProductsByName"name" Notice that the version parameter of GetById is not considered, because it is an optional parameter.

The GetAll method matches trivially. The GetById method also matches, because the route dictionary contains "id". The FindProductsByName method does not match.

The GetById method wins, because it matches one parameter, versus no parameters for GetAll. The method is invoked with the following parameter values:

id = 1 version = 1.5 Notice that even though version was not used in the selection algorithm, the value of the parameter comes from the URI query string.

Extension Points

Web API provides extension points for some parts of the routing process.

Interface Description IHttpControllerSelector

IHttpControllerTypeResolver Gets the list of controller types. The DefaultHttpControllerSelector chooses the controller type from this list. IAssembliesResolver Gets the list of project assemblies. The IHttpControllerTypeResolver interface uses this list to find the controller types.

Selects the controller.

IHttpControllerActivator

IHttpActionSelector

IHttpActionInvoker

To provide your own implementation for any of these interfaces, use the Services collection on the HttpConfiguration object:

Creates new controller instances. Selects the action. Invokes the action.

var config = GlobalConfiguration.Configuration;

config.Services.Replace(typeof(IHttpControllerSelector), new MyControllerSelector(config));

-------------------

Attribute Routing in ASP.NET Web API 2 By Mike Wasson|January 20, 2014 1292 of 1425 people found this helpful Print Routing is how Web API matches a URI to an action. Web API 2 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API. For example, you can easily create URIs that describe hierarchies of resources.

The earlier style of routing, called convention-based routing, is still fully supported. In fact, you can combine both techniques in the same project.

This topic shows how to enable attribute routing and describes the various options for attribute routing. For an end-to-end tutorial that uses attribute routing, see Create a REST API with Attribute Routing in Web API 2.

Why Attribute Routing? Enabling Attribute Routing Adding Route Attributes Route Prefixes Route Constraints Optional URI Parameters and Default Values

Route Names

Route Order

Prerequisites

Visual Studio 2013 or Visual Studio Express 2013

Alternatively, use NuGet Package Manager to install the necessary packages. From the Tools menu in Visual Studio, select Library Package Manager, then select Package Manager Console. Enter the following command in the Package Manager Console window:

Install-Package Microsoft.AspNet.WebApi.WebHost

Why Attribute Routing?

The first release of Web API used convention-based routing. In that type of routing, you define one or more route templates, which are basically parameterized strings. When the framework receives a request, it matches the URI against the route template. (For more information about convention-based routing, see Routing in ASP.NET Web API.

One advantage of convention-based routing is that templates are defined in a single place, and the routing rules are applied consistently across all controllers. Unfortunately, convention-based routing makes it hard to support certain URI patterns that are common in RESTful APIs. For example, resources often contain child resources: Customers have orders, movies have actors, books have authors, and so forth. It’s natural to create URIs that reflect these relations:

/customers/1/orders

This type of URI is difficult to create using convention-based routing. Although it can be done, the results don’t scale well if you have many controllers or resource types.

With attribute routing, it’s trivial to define a route for this URI. You simply add an attribute to the controller action:

[Route("customers/{customerId}/orders")] public IEnumerable<Order> GetOrdersByCustomer(int customerId) { Here are some other patterns that attribute routing makes easy.

API versioning

}

In this example, “/api/v1/products” would be routed to a different controller than

“/api/v2/products”.

/api/v1/products

/api/v2/products

Overloaded URI segments

In this example, “1” is an order number, but “pending” maps to a collection.

/orders/1

/orders/pending

Mulitple parameter types

In this example, “1” is an order number, but “2013/06/16” specifies a date.

/orders/1

/orders/2013/06/16

Enabling Attribute Routing

To enable attribute routing, call MapHttpAttributeRoutes during configuration. This extension method is defined in the System.Web.Http.HttpConfigurationExtensions class.

using System.Web.Http;

namespace WebApplication

{

 

public static class WebApiConfig

{

public static void Register(HttpConfiguration config)

{

// Web API routes config.MapHttpAttributeRoutes();

// Other Web API configuration not shown.

}

}

}

Attribute routing can be combined with convention-based routing. To define convention-based routes, call the MapHttpRoute method.

public static class WebApiConfig

{

public static void Register(HttpConfiguration config)

{

// Attribute routing. config.MapHttpAttributeRoutes();

// Convention-based routing. config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }

);

}

}

For more information about configuring Web API, see Configuring ASP.NET Web API 2 .

Note: Migrating From Web API 1

Prior to Web API 2, the Web API project templates generated code like this:

protected void Application_Start()

{

// WARNING - Not compatible with attribute routing. WebApiConfig.Register(GlobalConfiguration.Configuration);

}

If attribute routing is enabled, this code will throw an exception. If you upgrade an existing Web API project to use attribute routing, make sure to update this configuration code to the following:

protected void Application_Start()

{

// Pass a delegate to the Configure method. GlobalConfiguration.Configure(WebApiConfig.Register);

}

For more information, see Configuring Web API with ASP.NET Hosting.

Adding Route Attributes

Here is an example of a route defined using an attribute:

public class OrdersController : ApiController

{

 

[Route("customers/{customerId}/orders")] [HttpGet] public IEnumerable<Order> FindOrdersByCustomer(int customerId) {

}

}

The string "customers/{customerId}/orders" is the URI template for the route. Web API tries to match the request URI to the template. In this example, "customers" and "orders" are literal segments, and "{customerId}" is a variable parameter. The following URIs would match this template:

http://localhost/customers/1/orders

http://localhost/customers/bob/orders

http://localhost/customers/1234-5678/orders

You can restrict the matching by using constraints, described later in this topic.

Notice that the "{customerId}" parameter in the route template matches the name of the customerId parameter in the method. When Web API invokes the controller action, it tries to bind the route parameters. For example, if the URI is http://example.com/customers/1/orders, Web API tries to bind the value "1" to the customerId parameter in the action.

A URI template can have several parameters:

[Route("customers/{customerId}/orders/{orderId}")] public Order GetOrderByCustomer(int customerId, int orderId) {

Any controller methods that do not have a route attribute use convention-based routing. That way, you can combine both types of routing in the same project.

}

HTTP Methods

Web API also selects actions based on the HTTP method of the request (GET, POST, etc). By default, Web API looks for a case-insensitive match with the start of the controller method name. For example, a controller method named PutCustomers matches an HTTP PUT request.

You can override this convention by decorating the mathod with any the following attributes:

[HttpDelete] [HttpGet] [HttpHead] [HttpOptions] [HttpPatch] [HttpPost] [HttpPut] The following example maps the CreateBook method to HTTP POST requests.

[Route("api/books")] [HttpPost] public HttpResponseMessage CreateBook(Book book) {

}

For all other HTTP methods, including non-standard methods, use the AcceptVerbs attribute, which takes a list of HTTP methods.

// WebDAV method [Route("api/books")] [AcceptVerbs("MKCOL")] public void MakeCollection() { } Route Prefixes

Often, the routes in a controller all start with the same prefix. For example:

public class BooksController : ApiController

{

 

[Route("api/books")] public IEnumerable<Book> GetBooks() {

}

[Route("api/books/{id:int}")] public Book GetBook(int id) {

}

[Route("api/books")] [HttpPost] public HttpResponseMessage CreateBook(Book book) {

}

}

You can set a common prefix for an entire controller by using the [RoutePrefix] attribute:

[RoutePrefix("api/books")]

public class BooksController : ApiController

{

 

// GET api/books [Route("")] public IEnumerable<Book> Get() {

}

// GET api/books/5 [Route("{id:int}")] public Book Get(int id) {

}

// POST api/books [Route("")] public HttpResponseMessage Post(Book book) {

}

}

Use a tilde (~) on the method attribute to override the route prefix:

[RoutePrefix("api/books")]

public class BooksController : ApiController

{

// GET /api/authors/1/books [Route("~/api/authors/{authorId:int}/books")] public IEnumerable<Book> GetByAuthor(int authorId) {

//

}

}

The route prefix can include parameters:

[RoutePrefix("customers/{customerId}")]

public class OrdersController : ApiController

{

 

// GET customers/1/orders [Route("orders")] public IEnumerable<Order> Get(int customerId) {

}

}

Route Constraints

Route constraints let you restrict how the parameters in the route template are matched. The general syntax is "{parameter:constraint}". For example:

[Route("users/{id:int}"] public User GetUserById(int id) {

}

[Route("users/{name}"] public User GetUserByName(string name) {

Here, the first route will only be selected if the "id" segment of the URI is an integer. Otherwise, the second route will be chosen.

}

The following table lists the constraints that are supported.

Constraint Description Example

alpha Matches uppercase or lowercase Latin alphabet characters (a-z, A-Z) {x:alpha} bool Matches a Boolean value. {x:bool} datetime Matches a DateTime value. {x:datetime} decimal Matches a decimal value. {x:decimal} double Matches a 64-bit floating-point value.{x:double}

float

Matches a 32-bit floating-point value.{x:float}

guid

Matches a GUID value.

{x:guid}

int Matches a 32-bit integer value. {x:int}

length Matches a string with the specified length or within a specified range of lengths.

{x:length(6)}

{x:length(1,20)}

long

Matches a 64-bit integer value.

{x:long}

max

Matches an integer with a maximum value. {x:max(10)}

maxlength

min

minlength

Matches a string with a maximum length.

{x:maxlength(10)}

Matches an integer with a minimum value.

{x:min(10)}

Matches a string with a minimum length.

{x:minlength(10)}

range

Matches an integer within a range of values.{x:range(10,50)}

regex

Matches a regular expression.

{x:regex(^\d{3}-\d{3}-\d{4}$)}

Notice that some of the constraints, such as "min", take arguments in parentheses. You can apply multiple constraints to a parameter, separated by a colon.

[Route("users/{id:int:min(1)}")]

public User GetUserById(int id) {

}

Custom Route Constraints

You can create custom route constraints by implementing the IHttpRouteConstraint interface. For example, the following constraint restricts a parameter to a non-zero integer value.

public class NonZeroConstraint : IHttpRouteConstraint

{

public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)

{

object value;

if (values.TryGetValue(parameterName, out value) && value != null)

{

long longValue;

if (value is long)

{

longValue = (long)value; return longValue != 0;

}

string valueString = Convert.ToString(value, CultureInfo.InvariantCulture); if (Int64.TryParse(valueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out longValue))

{

return longValue != 0;

}

}

return false;

}

}

The following code shows how to register the constraint:

public static class WebApiConfig

{

 

public static void Register(HttpConfiguration config)

{

var constraintResolver = new DefaultInlineConstraintResolver(); constraintResolver.ConstraintMap.Add("nonzero", typeof(NonZeroConstraint));

config.MapHttpAttributeRoutes(constraintResolver);

}

}

Now you can apply the constraint in your routes:

[Route("{id:nonzero}")] public HttpResponseMessage GetNonZero(int id) {

You can also replace the entire DefaultInlineConstraintResolver class by implementing the IInlineConstraintResolver interface. Doing so will replace all of the built-in constraints, unless your implementation of IInlineConstraintResolver specifically adds them.

}

Optional URI Parameters and Default Values

You can make a URI parameter optional by adding a question mark to the route parameter. If a route parameter is optional, you must define a default value for the method parameter.

public class BooksController : ApiController

{

 

[Route("api/books/locale/{lcid:int?}")] public IEnumerable<Book> GetBooksByLocale(int lcid = 1033) {

}

}

In this example, /api/books/locale/1033 and /api/books/locale return the same resource.

Alternatively, you can specify a default value inside the route template, as follows:

public class BooksController : ApiController

{

 

[Route("api/books/locale/{lcid:int=1033}")]

public IEnumerable<Book> GetBooksByLocale(int lcid) {

}

}

This is almost the same as the previous example, but there is a slight difference of behavior when the default value is applied.

In the first example ("{lcid?}"), the default value of 1033 is assigned directly to the method parameter, so the parameter will have this exact value. In the second example ("{lcid=1033}"), the default value of "1033" goes through the model-binding process. The default model-binder will convert "1033" to the numeric value 1033. However, you could plug in a custom model binder, which might do something different. (In most cases, unless you have custom model binders in your pipeline, the two forms will be equivalent.)

Route Names

In Web API, every route has a name. Route names are useful for generating links, so that you can include a link in an HTTP response.

To specify the route name, set the Name property on the attribute. The following example shows how to set the route name, and also how to use the route name when generating a link.

public class BooksController : ApiController

{

[Route("api/books/{id}", Name="GetBookById")] public BookDto GetBook(int id)

{

// Implementation not shown

}

[Route("api/books")]

public HttpResponseMessage Post(Book book)

{

// Validate and add book to database (not shown)

var response = Request.CreateResponse(HttpStatusCode.Created);

// Generate a link to the new book and set the Location header in the response. string uri = Url.Link("GetBookById", new { id = book.BookId }); response.Headers.Location = new Uri(uri); return response;

}

}

Route Order

When the framework tries to match a URI with a route, it evaluates the routes in a particular order. To specify the order, set the RouteOrder property on the route attribute. Lower values are evaluated first. The default order value is zero.

Here is how the total ordering is determined:

Compare the RouteOrder property of the route attribute. Look at each URI segment in the route template. For each segment, order as follows:

Literal segments. Route parameters with constraints. Route parameters without constraints. Wildcard parameter segments with constraints. Wildcard parameter segments without constraints. In the case of a tie, routes are ordered by a case-insensitive ordinal string comparison (OrdinalIgnoreCase) of the route template. Here is an example. Suppose you define the following controller:

[RoutePrefix("orders")]

public class OrdersController : ApiController

{

 

[Route("{id:int}")] // constrained parameter public HttpResponseMessage Get(int id) {

}

[Route("details")] // literal public HttpResponseMessage GetDetails() {

}

[Route("pending", RouteOrder = 1)] public HttpResponseMessage GetPending() {

 

}

[Route("{customerName}")] // unconstrained parameter public HttpResponseMessage GetByCustomer(string customerName) {

}

[Route("{*date:datetime}")] // wildcard public HttpResponseMessage Get(DateTime date) {

}

}

These routes are ordered as follows.

orders/details orders/{id} orders/{customerName} orders/{*date} orders/pending Notice that "details" is a literal segment and appears before "{id}", but "pending" appears last because the RouteOrder property is 1. (This example assumes there are no customers named

"details" or "pending". In general, try to avoid ambiguous routes. In this example, a better route template for GetByCustomer is "customers/{customerName}" )

------------------------

Create a REST API with Attribute Routing in ASP.NET Web API 2 By Mike Wasson|June 26, 2013 568 of 625 people found this helpful Print Web API 2 supports a new type of routing, called attribute routing. For a general overview of attribute routing, see Attribute Routing in Web API 2. In this tutorial, you will use attribute routing to create a REST API for a collection of books. The API will support the following actions:

Action Example URI

Get a list of all books. /api/books

Get a book by ID.

Get the details of a book.

Get a list of books by genre. /api/books/fantasy

Get a list of books by publication date. /api/books/date/2013/02/16 (alternate form) Get a list of books by a particular author.

All methods are read-only (HTTP GET requests).

/api/books/1

/api/books/1/details

/api/books/date/2013-02-16

/api/authors/1/books

For the data layer, we'll use Entity Framework. Book records will have the following fields:

ID Title Genre Publication date Price Description AuthorID (foreign key to an Authors table) For most requests, however, the API will return a subset of this data (title, author, and genre). To get the complete record, the client requests /api/books/{id}/details.

Prerequisites

Visual Studio 2013 or Visual Studio Express 2013

Create the Visual Studio Project

Start by running Visual Studio. From the File menu, select New and then select Project.

In the Templates pane, select Installed Templates and expand the Visual C# node. Under Visual C#, select Web. In the list of project templates, select ASP.NET MVC 4 Web Application. Name the project "BooksAPI".

In the New ASP.NET Project dialog, select the Empty template. Under “Add folders and core references for”, select the Web API checkbox. Click Create Project.

This creates a skeleton project that is configured for Web API functionality.

Domain Models

Next, add classes for domain models. In Solution Explorer, right-click the Models folder. Select Add, then select Class. Name the class Author.

Replace the code in Author.cs with the following:

using System.ComponentModel.DataAnnotations;

namespace BooksAPI.Models

{

public class Author

{

public int AuthorId { get; set; } [Required] public string Name { get; set; }

}

}

Now add another class named Book.

using System; using System.ComponentModel.DataAnnotations;

using System.ComponentModel.DataAnnotations.Schema;

namespace BooksAPI.Models

{

public class Book

{

public int BookId { get; set; } [Required] public string Title { get; set; } public decimal Price { get; set; } public string Genre { get; set; } public DateTime PublishDate { get; set; } public string Description { get; set; } public int AuthorId { get; set; } [ForeignKey("AuthorId")] public Author Author { get; set; }

}

}

Add a Web API Controller

In this step, we'll add a Web API controller that uses Entity Framework as the data layer.

Press CTRL+SHIFT+B to build the project. Entity Framework uses reflection to discover the properties of the models, so it requires a compiled assembly to create the database schema.

In Solution Explorer, right-click the Controllers folder. Select Add, then select Controller.

In the Add Scaffold dialog, select “Web API 2 Controller with read/write actions, using Entity Framework.”

In the Add Controller dialog, for Controller name, enter "BooksController". Select the "Use async controller actions" checkbox. For Model class, select "Book". (If you don’t see the Book class listed in the dropdown, make sure that you built the project.) Then click the “<New data

context

>”

button.

Click Add in the New Data Context dialog.

Click Add in the Add Controller dialog. The scaffolding adds a class named BooksController that defines the API controller. It also adds a class named BooksAPIContext in the Models folder, which defines the data context for Entity Framework.

Seed the Database

From the Tools menu, select Library Package Manager, and then select Package Manager Console.

In the Package Manager Console window, enter the following command:

enable-migrations This command creates a Migrations folder and adds a new code file named Configuration.cs. Open this file and add the following code to the Configuration.Seed method.

protected override void Seed(BooksAPI.Models.BooksAPIContext context)

{

context.Authors.AddOrUpdate(new Author[] { new Author() { AuthorId = 1, Name = "Ralls, Kim" }, new Author() { AuthorId = 2, Name = "Corets, Eva" }, new Author() { AuthorId = 3, Name = "Randall, Cynthia" }, new Author() { AuthorId = 4, Name = "Thurman, Paula" } });

context.Books.AddOrUpdate(new Book[] { new Book() { BookId = 1, Title= "Midnight Rain", Genre = "Fantasy", PublishDate = new DateTime(2000, 12, 16), AuthorId = 1, Description = "A former architect battles an evil sorceress.", Price = 14.95M },

new Book() { BookId = 2, Title = "Maeve Ascendant", Genre = "Fantasy", PublishDate = new DateTime(2000, 11, 17), AuthorId = 2, Description = "After the collapse of a nanotechnology society, the young" + "survivors lay the foundation for a new society.", Price = 12.95M },

new Book() { BookId = 3, Title = "The Sundered Grail", Genre = "Fantasy", PublishDate = new DateTime(2001, 09, 10), AuthorId = 2, Description = "The two daughters of Maeve battle for control of England.", Price = 12.95M },

new Book() { BookId = 4, Title = "Lover Birds", Genre = "Romance", PublishDate = new DateTime(2000, 09, 02), AuthorId = 3, Description = "When Carla meets Paul at an ornithology conference, tempers fly.", Price = 7.99M },

new Book() { BookId = 5, Title = "Splish Splash", Genre = "Romance", PublishDate = new DateTime(2000, 11, 02), AuthorId = 4, Description = "A deep sea diver finds true love 20,000 leagues beneath the sea.", Price = 6.99M},

});

}

In the Package Manager Console window, type the following commands.

add-migration Initial

update-database These commands create a local database and invoke the Seed method to populate the database.

Add DTO Classes

If you run the application now and send a GET request to /api/books/1, the response looks similar to the following. (I added indentation for readability.)

{

"BookId": 1, "Title": "Midnight Rain", "Genre": "Fantasy", "PublishDate": "2000-12-16T00:00:00", "Description": "A former architect battles an evil sorceress.", "Price": 14.95, "AuthorId": 1, "Author": null

}

Instead, I want this request to return a subset of the fields. Also, I want it to return the author's name, rather than the author ID. To accomplish this, we'll modify the controller methods to return a data transfer object (DTO) instead of the EF model. A DTO is an object that is designed only to carry data.

In Solution Explorer, right-click the project and select Add | New Folder. Name the folder "DTOs". Add a class named BookDto to the DTOs folder, with the following definition:

namespace BooksAPI.DTOs

{

public class BookDto

{

public string Title { get; set; } public string Author { get; set; } public string Genre { get; set; }

}

}

Add another class named BookDetailDto.

using System;

namespace BooksAPI.DTOs

{

public class BookDetailDto

{

public string Title { get; set; } public string Genre { get; set; } public DateTime PublishDate { get; set; } public string Description { get; set; } public decimal Price { get; set; } public string Author { get; set; }

}

}

Next, update the BooksController class to return BookDto instances. We'll use the Queryable.Select method to project Book instances to BookDto instances. Here is the updated code for the controller class.

using BooksAPI.DTOs; using BooksAPI.Models; using System; using System.Data.Entity; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using System.Web.Http; using System.Web.Http.Description;

namespace BooksAPI.Controllers

{

public class BooksController : ApiController

{

private BooksAPIContext db = new BooksAPIContext();

// Typed lambda expression for Select() method.

private static readonly Expression<Func<Book, BookDto>> AsBookDto =

x => new BookDto

{

Title = x.Title, Author = x.Author.Name, Genre = x.Genre

};

// GET api/Books

public IQueryable<BookDto> GetBooks()

{

return db.Books.Include(b => b.Author).Select(AsBookDto);

}

// GET api/Books/5 [ResponseType(typeof(BookDto))]

public async Task<IHttpActionResult> GetBook(int id)

{

BookDto book = await db.Books.Include(b => b.Author) .Where(b => b.BookId == id) .Select(AsBookDto) .FirstOrDefaultAsync();

if (book == null)

{

return NotFound();

}

return Ok(book);

}

protected override void Dispose(bool disposing)

{

 

db.Dispose();

base.Dispose(disposing);

}

}

}

I deleted the PutBook, PostBook, and DeleteBook methods, because they aren't needed for this tutorial.

Now if you run the application and request /api/books/1, the response body should look like this:

{"Title":"Midnight Rain","Author":"Ralls, Kim","Genre":"Fantasy"} Add Route Attributes

Next, we'll convert the controller to use attribute routing. First, add a RoutePrefix attribute to the controller. This attribute defines the initial URI segments for all methods on this controller.

[RoutePrefix("api/books")]

public class BooksController : ApiController

{

// Then add [Route] attributes to the controller actions, as follows:

[Route("")]

public IQueryable<BookDto> GetBooks()

{

//

}

[Route("{id:int}")]

[ResponseType(typeof(BookDto))]

public async Task<IHttpActionResult> GetBook(int id)

{

//

}

The route template for each controller method is the prefix plus the string specified in the Route attribute. For the GetBook method, the route template includes the parameterized string "{id:int}", which matches if the URI segment contains an integet value.

Method Route Template Example URI GetBooks "api/books" http://localhost/api/books GetBook "api/books/{id:int}" http://localhost/api/books/5 Get Book Details

To get book details, the client will send a GET request to /api/books/{id}/details, where {id} is the ID of the book.

Add the following method to the BooksController class.

[Route("{id:int}/details")]

[ResponseType(typeof(BookDetailDto))]

public async Task<IHttpActionResult> GetBookDetail(int id)

{

var book = await (from b in db.Books.Include(b => b.Author) where b.AuthorId == id select new BookDetailDto

{

Title = b.Title, Genre = b.Genre, PublishDate = b.PublishDate, Price = b.Price, Description = b.Description, Author = b.Author.Name }).FirstOrDefaultAsync();

if (book == null)

{

return NotFound();

}

return Ok(book);

}

If you request /api/books/1/detail, the response looks like this:

{

"Title": "Midnight Rain", "Genre": "Fantasy", "PublishDate": "2000-12-16T00:00:00", "Description": "A former architect battles an evil sorceress.", "Price": 14.95, "Author": "Ralls, Kim"

}

Get Books By Genre

To get a list of books in a specific genre, the client will send a GET request to /api/books/genre, where genre is the name of the genre. (For example, /get/books/fantasy.)

Add the following method to BooksController.

[Route("{genre}")]

public IQueryable<BookDto> GetBooksByGenre(string genre)

{

return db.Books.Include(b => b.Author) .Where(b => b.Genre.Equals(genre, StringComparison.OrdinalIgnoreCase)) .Select(AsBookDto);

}

Here we are defining a route that contains a {genre} parameter in the URI template. Notice that Web API is able to distinguish these two URIs and route them to different methods:

/api/books/1

/api/books/fantasy

That's because the GetBook method includes a constraint that the "id" segment must be an integer value:

[Route("{id:int}")]

public BookDto GetBook(int id)

{

//

}

If you request /api/books/fantasy, the response looks like this:

[ { "Title": "Midnight Rain", "Author": "Ralls, Kim", "Genre": "Fantasy" }, { "Title": "Maeve Ascendant", "Author": "Corets, Eva", "Genre": "Fantasy" }, { "Title": "The Sundered Grail", "Author": "Corets, Eva", "Genre": "Fantasy" } ]

Get Books By Author

To get a list of a books for a particular author, the client will send a GET request to /api/authors/id/books, where id is the ID of the author.

Add the following method to BooksController.

[Route("~api/authors/{authorId}/books")]

public IQueryable<BookDto> GetBooksByAuthor(int authorId)

{

return db.Books.Include(b => b.Author) .Where(b => b.AuthorId == authorId) .Select(AsBookDto);

}

This example is interesting because "books" is treated a child resource of "authors". This pattern is quite common in RESTful APIs.

The tilde (~) in the route template overrides the route prefix in the RoutePrefix attribute.

Get Books By Publication Date

To get a list of books by publication date, the client will send a GET request to /api/books/date/yyyy-mm-dd, where yyyy-mm-dd is the date.

Here is one way to do this:

[Route("date/{pubdate:datetime}")]

public IQueryable<BookDto> GetBooks(DateTime pubdate)

{

return db.Books.Include(b => b.Author) .Where(b => DbFunctions.TruncateTime(b.PublishDate) == DbFunctions.TruncateTime(pubdate)) .Select(AsBookDto);

}

The {pubdate:datetime} parameter is constrained to match a DateTime value. This works, but it's actually more permissive than we'd like. For example, these URIs will also match the route:

/api/books/date/Thu, 01 May 2008

/api/books/date/2000-12-16T00:00:00

There's nothing wrong with allowing these URIs. However, you can restrict the route to a particular format by adding a regular-expression constraint to the route template:

[Route("api/books/date/{pubdate:datetime:regex(\\d{4}-\\d{2}-\\d{2})}")]

public IQueryable<BookDto> GetBooks(DateTime pubdate)

{

//

}

Now only dates in the form "yyyy-mm-dd" will match. Notice that we don't use the regex to validate that we got a real date. That is handled when Web API tries to convert the URI segment into a DateTime instance. An invalid date such as '2012-47-99' will fail to be converted, and the client will get a 404 error.

You can also support a slash separator (/api/books/date/yyyy/mm/dd) by adding another [Route] attribute with a different regex.

[Route("date/{pubdate:datetime:regex(\\d{4}-\\d{2}-\\d{2})}")]

[Route("date/{*pubdate:datetime:regex(\\d{4}/\\d{2}/\\d{2})}")] // new public IQueryable<BookDto> GetBooks(DateTime pubdate)

{

}

//

There is a subtle but important detail here. The second route template has a wildcard character (*) at the start of the {pubdate} parameter:

{*pubdate:

This tells the routing engine that {pubdate} should match the rest of the URI. By default, a template parameter matches a single URI segment. In this case, we want {pubdate} to span several URI segments:

}

/api/books/date/2013/06/17

Controller Code

Here is the complete code for the BooksController class.

using BooksAPI.DTOs; using BooksAPI.Models; using System; using System.Data.Entity; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using System.Web.Http; using System.Web.Http.Description;

namespace BooksAPI.Controllers

{

[RoutePrefix("api/books")]

public class BooksController : ApiController

{

private BooksAPIContext db = new BooksAPIContext();

// Typed lambda expression for Select() method.

private static readonly Expression<Func<Book, BookDto>> AsBookDto = x => new BookDto

{

Title = x.Title, Author = x.Author.Name, Genre = x.Genre

};

// GET api/Books [Route("")] public IQueryable<BookDto> GetBooks()

{

return db.Books.Include(b => b.Author).Select(AsBookDto);

}

// GET api/Books/5 [Route("{id:int}")] [ResponseType(typeof(BookDto))]

public async Task<IHttpActionResult> GetBook(int id)

{

BookDto book = await db.Books.Include(b => b.Author) .Where(b => b.BookId == id) .Select(AsBookDto) .FirstOrDefaultAsync(); if (book == null)

{

return NotFound();

}

return Ok(book);

}

[Route("{id:int}/details")]

[ResponseType(typeof(BookDetailDto))]

public async Task<IHttpActionResult> GetBookDetail(int id)

{

 

var book = await (from b in db.Books.Include(b => b.Author) where b.AuthorId == id select new BookDetailDto

{

Title = b.Title, Genre = b.Genre, PublishDate = b.PublishDate, Price = b.Price, Description = b.Description, Author = b.Author.Name }).FirstOrDefaultAsync();

if (book == null)

{

return NotFound();

}

return Ok(book);

}

[Route("{genre}")]

public IQueryable<BookDto> GetBooksByGenre(string genre)

{

return db.Books.Include(b => b.Author) .Where(b => b.Genre.Equals(genre, StringComparison.OrdinalIgnoreCase)) .Select(AsBookDto);

}

[Route("~api/authors/{authorId}/books")]

public IQueryable<BookDto> GetBooksByAuthor(int authorId)

{

return db.Books.Include(b => b.Author) .Where(b => b.AuthorId == authorId) .Select(AsBookDto);

}

[Route("date/{pubdate:datetime:regex(\\d{4}-\\d{2}-\\d{2})}")]

[Route("date/{*pubdate:datetime:regex(\\d{4}/\\d{2}/\\d{2})}")]

public IQueryable<BookDto> GetBooks(DateTime pubdate)

{

return db.Books.Include(b => b.Author) .Where(b => DbFunctions.TruncateTime(b.PublishDate) == DbFunctions.TruncateTime(pubdate)) .Select(AsBookDto);

}

protected override void Dispose(bool disposing)

{

 

db.Dispose();

base.Dispose(disposing);

}

}

}

--------------------------

Routing Basics in ASP.NET Web API

John Atten, 22 Aug 2013 CPOL

4.82 (18 votes) Rate this:

This post covers the most basic and fundamental concepts of routing as applied to the ASP.NET Web API framework.

I210-and-I57-interchange-by-Rob-Reiring-320

As noted in Routing Basics in ASP.NET MVC, routing in ASP.NET Web API is functionally very similar to the standard MVC routing. Understanding the MVC routing model will provide most of what you need to know to leverage that knowledge against the Web API framework, so long as you keep in mind the key differences between the two.

The differences between the two are largely dictated by the different consumption models driving each type of application.

Image by Ron Reiring

Important note: This post covers the most basic and fundamental concepts of routing as applied to the ASP.NET Web API framework. The target audience are those with little or no familiarity with routing in general, or who may be looking to understand the most basic differences between routing in ASP.NET MVC and Web API.

If you have little to no knowledge of MVC routing, you may want to review my post on MVC routing basics first.

In my next post, having covered the fundamentals, I will examine route customization.

Web API Configuration Files How Routing Works for Web API The Default Web API Route Template Action Method Selection Web API and Action Naming What Have We Learned? Other Posts You May Find Useful Web API and MVC – Two Separate Frameworks

Because the Web API grew (in part) out of the efforts of the ASP.NET MVC team, and because the default Web API project template in Visual Studio is bundled up inside an MVC application, it is easy to think that the Web API framework is some kind of subset of the MVC framework. In fact, the two inter-operate together very well, but that is by design. They are, in fact, separate frameworks which adhere to some common architectural patterns.

Instead of paraphrasing the overview of Web API and the architectural goals of the project, I will let the MVC team do so, because honestly, they know better than I do! from the most helpful book Professional ASP.NET MVC 4 authored by (mostly) the MVC team:

"ASP.NET MVC excels at accepting form data and generating HTML; ASP.NET Web API excels at accepting and generating structured data like JSON and XML." MVC has flirted with providing structured data support (with JsonResult and the JSON value provider), but it still fell short in several ways that are important to API programmers, including:

Dispatching to actions based on HTTP verbs rather than action names Accepting and generating content which may not necessarily be object oriented (not only XML, but also content like images, PDF files, or VCARDs Content type negotiation, which allows the developer to both accept and genereate structured content independent of its wire representation Hosting outside of the ASP.NET runtime stack and IIS web server, something which WCF has been unable to do for years The Web API team went to great lengths to try to allow you to leverage your existing ASP.NET experience with controllers, actions, filters, model binders, dependency injection, and the like. Many of these same concepts appear in Web API in very similar forms, which make applications that combine MVC and Web API seem very well integrated."

As noted above, one of the key differences between MVC and Web API is that Web API returns an appropriate representation of the model object as a result. A related difference is that Web API performs content type negotiation in response to incoming requests, and attempts to return the proper content type (JSON in response to an incoming request specifying JSON as the preferred content resource representation, for example).

Suffice it to say that Web API is an effort to create a mechanism for the efficient exchange of data and other content using HTTP. This effort is reflected in the architecture of the framework, and results in some of the differences in routing between the two frameworks.

Web API Route Configuration Files

The default Visual Studio Web API project template is rather large, as it incorporates a complete MVC project as well. The resulting project has some pretty cool features, including automatic documentation for the API you build (that is the purpose of the MVC site contained in the project), but also presents a rather bloated project file, with a large number of folders and dependencies.

NOTE: To see how to create a stripped-down Web API project template in Visual Studio, see Creating a Clean, Minimal-Footprint ASP.NET WebAPI Project with VS 2012 and ASP.NET MVC 4

As with a standard MVC project, the route configuration is called from the Global.asx file. However, in this standard Web API project, there exists both a RouteConfig class, and a WebApiConfig class, both in the Application_Start folder:

Global.asx File and the WebApiConfig File in a Typical MVC Project:

StandardWebApiTemplateProject

The RouteConfig.cs file here is the same as in any MVC project, and sets up routes for the MVC framework. The WebApiConfig.cs file is where our Web API routing configuration happens. However, if we open the file, it looks pretty familiar:

The WebApiConfig Class and MapHttpRoute Method:

Hide

using System; using System.Collections.Generic; using System.Linq; using System.Web.Http;

Copy Code

namespace StandardWebApiTemplateProject

{

 

public static class WebApiConfig

{

public static void Register(HttpConfiguration config)

{

 

config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }

);

 

}

}

}

There are a few important differences here, though. First, notice that in the using statements at the top of the file, there are no references toSystem.Web.Mvc but instead, we find a reference to System.Web.Http. That's because the Web API team re-created the routing functionality in a library with no dependencies on ASP.NET or MVC. Also notice that instead of calling Routes.MapRoutes as in the MVC RouteConfig class, we instead call Config.Routes.MapHttpRoutes.

And, as we can see, the default route template for Web API looks a little different.

How Routing Works for Web API

Unlike ASP.NET MVC, the Web API routing convention routes incoming requests to a specific controller, but by default simply matches the HTTP verb of the request to an action method whose name begins with that verb. Recall the default MVC route configuration:

The Default MVC Route Template:

Hide

{controller}/{action}/{id} In contrast, the default Web API route template looks like this:

Copy Code

The Default Web API Route Template:

Hide

api/{controller}/{id} The literal api at the beginning of the Web API route template above makes it distinct from the standard MVC route. Also, it is a good convention to include as part of an API route a segment that lets the consumer know they are accessing an API instead of a standard site.

Copy Code

Also notice that unlike the familiar MVC route template, the Web API template does not specify an {action} route parameter. This is because, as we mentioned earlier, the Web API framework will by default map incoming requests to the appropriate action based upon the HTTP verb of the request.

Consider the following typical Web API Controller:

WebApi Controller from Default Visual Studio WebApi Template

Hide

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http;

Shrink

Copy Code

namespace StandardWebApiTemplateProject.Controllers

{

public class ValuesController : ApiController

{

// GET api/values

public IEnumerable<string> Get()

{

return new string[] { "value1", "value2" };

}

// GET api/values/5

public string Get(int id)

{

return "value";

}

// POST api/values

public void Post([FromBody]string value)

{

}

// PUT api/values/5

public void Put(int id, [FromBody]string value)

{

}

// DELETE api/values/5

public void Delete(int id)

{

}

}

}

First, take note that Web API controllers do not inherit from System.Web.Mvc.Controller, but instead from System.Web.Http.Controller. Again, we are working with a familiar, but distinct library.

Of particular note, however, are the default method names (the example above is what is created as part of the default VS 2012 project template). Again, without specifying a specific method using an {action} route parameter, the Web API framework determines the appropriate route based on the HTTP verb of the incoming request, and calls the proper method accordingly.

The following incoming URL, included as part of an HTTP GET message, would map to the first Get() method as defined in the controller above:

Example URL With No ID Parameter

Hide

http://mydomain/values/ Similarly, this URL, also as part of an HTTP GET request, would map to the second Get(id) method:

Copy Code

Example URL Including ID Parameter

Hide

http://mydomain/values/5

We could, however, modify our controller thusly, and the routing would still work without modification:

Copy Code

Modifications to the ValuesController Class:

Hide

// GET api/values

public IEnumerable<string> GetValues()

{

Copy Code

return new string[] { "value1", "value2" };

}

// GET api/values/5

public string GetValue(int id)

{

return "value";

}

// POST api/values

public void PostValue([FromBody]Book value)

{

}

// PUT api/values/5

public void PutValue(int id, [FromBody]string value)

{

}

// DELETE api/values/5

public void DeleteValue(int id)

{

Note that we retained the HTTP action verb as a prefix to all of our method names. Under these circumstances, the unmodified route parameter will still work just fine. When per convention, no {action} route parameter is specified, the Web API framework again appends the "Controller" suffix to the value provided for the {controller} parameter, and then scans the project for a suitably named class (in this case, one which derives from ApiController).

Action Method Selection

Once the proper controller class is selected, the framework examines the HTTP action verb of the request, and searches the class for method names with a matching prefix.

In order to determine the proper method, the framework then examines the additional URL parameters and attempts to match them with method arguments by name (case insensitive). The method with the most matching arguments will be selected.

An item to note here. Unlike in MVC, in Web API complex types are not allowed as part of the URL. Complex types must be placed in the body of the HTTP message. Also, there can be one, and only one such complex type in the message body.

In evaluating parameter matches against method arguments, any complex types and URL query strings are disregarded when searching for a match.

Web API and Action Naming

We can modify our default Web API route to include an {action} route parameter, in which case selection will occur similar to that in MVC. However, action methods defined on our controller still need to include the proper HTTP action verb prefix, and incoming URLs must use the full method name.

If we modify our default route thusly, adding an {action} parameter:

The Modified WebApiConfig Class and MapHttpRoute Method:

Hide

using System; using System.Collections.Generic; using System.Linq; using System.Web.Http;

Copy Code

namespace StandardWebApiTemplateProject

{

 

public static class WebApiConfig

{

public static void Register(HttpConfiguration config)

{

 

config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional }

);

 

}

}

}

To see how this works, consider the incoming URL:

Hide

http://mydomain/values/5

This will no longer work. If we wish to make a request of our modified ValuesController now, we would need to submit:

Copy Code

Hide

http://mydomain/values/GetValue/5

Review of the Basics for Web API Routing

Copy Code

The routing convention for Web API is to route URLs to a controller, and then to the action which matches the HTTP verb of the request message. Action methods on the controller must either match the HTTP action verb, or at least include the action verb as a prefix for the method name. The default route template for a Web API Project is {controller}/{id} where the {id} parameter is optional. Web API route templates may optionally include an {action} parameter. However, the action methods defined on the controller must be named with the proper HTTP action verb as a prefix in order for the routing to work. In matching incoming HTTP messages to controllers, the Web API framework identifies the proper controller by appending the literal "Controller" to the value of the {controller} route parameter, then scans the project for a class matching that name. Actions are selected from the controller by considering the non-complex route parameters, and matching them by name to the arguments of each method which matches the HTTP verb of the request. The method which matches the most parameters is selected. Unlike MVC, URLs in Web API cannot contain complex types. Complex types must be placed in the HTTP message body. There may be one, and only one complex type in the body of an HTTP message. That was Pretty Darn Basic. What Next?

The above represents a very simple overview of the Web API routing basics, focusing on the

default configurations and conventions. In the next post we will examine more advanced routing considerations, and route customization.

---------------------

Exploring routing in Web API MORE LIKE THIS mvc 6 New features in MVC 6 Female executive at laptop with code flying out of screen woman Top 10 new features in ASP.Net 5 web api performance Improving Web API performance on IDG Answers I am original owner of ipod touch but I let my friend use it and her cousin

Routing in Web Api Routing in Web Api

Take advantage of routing in Web API to have more control over the URIs for performing the HTTP operations

InfoWorld | Jun 30, 2015 Like this article? thumbsup 0 thumbsdown

RELATED TOPICS

Application Development .Net COMMENTS ASP.Net Web API is a lightweight framework used for building stateless HTTP services. You can use Web API to design and implement RESTful services that run on HTTP. REST is an architectural style -- a set of constraints used to implement stateless services. Web API has already become the technology of choice for building light weight HTTP services. In this post, I'll present a discussion on how routing works in Web API.

collage with gears machine data Review: 6 machine learning clouds

Amazon, Microsoft, Databricks, Google, HPE, and IBM machine learning toolkits run the gamut

in breadth,

READ NOW When you create a Web API project in Visual Studio, you would observe that a MVC project is created as well. Similar to ASP.Net MVC the routing configuration in a Web API project is invoked from the Global.asax file. A Web API project stores the configuration information in the RouteConfig and WebApiConfig classes -- both of these are present in the Application_Start folder. Similar to a MVC project you would observe a RouteConfig.cs file created in the App_Start folder in your solution.

A controller in Web API is responsible for handling HTTP requests. The public methods of the

controller are known as action methods. As soon as a request is received, the Web API runtime routes the request to the appropriate action to handle the request. Now, in order to determine which action should be invoked, the Web API runtime takes advantage of a routing table. In contrast to a typical ASP.Net MVC application, the Web API runtime routes the incoming requests to the appropriate controller by matching the HTTP verb of the request to the appropriate action method.

With ASP.Net 5 (to be released soon as part of Visual Studio 2015), there is a unified core framework -- you have a single outing framework, a single model binding framework, and a one-filter pipeline. You now have one unified core for ASP.Net MVC, ASP.Net Web API, and ASP.Net Web Pages. So, there's now only one type of a controller to handle requests: it's common to your ASP.Net MVC, ASP.Net Web API, and ASP.Net applications.

The default MVC route template looks like this:

{controller}/{action}/{id}

In contrast, the default Web API route looks like this:

api/{controller}/{id}

The default route created when you create a new Web API project in Visual Studio looks like this:

public static class WebApiConfig

{

public static void Register(HttpConfiguration config)

{

config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}",

defaults: new { id = RouteParameter.Optional } );

}

}

Note how the default route is prefixed by "api". It is a good practice to define the routes of your Web API application by prefixing them with "api" to make them distinct from the standard MVC route. On a different note, when you look at the default route for a Web API project, you wouldn't see the "{action}" route parameter -- the Web API runtime maps requests to the appropriate actions based on the HTTP verb of the requests.

However, you can modify the Web API route definition to include an "{action}" parameter. The following code snippet illustrates how the modified WebApiConfig class looks like.

public static class WebApiConfig

{

public static void Register(HttpConfiguration config)

{

config.Routes.MapHttpRoute( name: "DefaultApi",

routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } );

}

}

Now that you have specified "{action}" as part of the route, you need to specify the action when invoking the WebAPI method. Consider the following URL: http://idgservice/authors/1

In this URL, idgservice is the name of the domain where the WebAPI has been hosted, authors is the controller name, and 1 is passed as a parameter. However, this wouldn't work if you have defined "{action}" in your route definition. You would need to explicitly mention the action name when calling your WebAPI this this case. Here's the correct URL that includes the action name as part of the URL: http://idgservice/authors/GetAuthorDetails/1

Note that the action name in the above URL is GetAuthorDetails and has been mentioned as part of the modified URL.

You can also specify the HTTP method for an action using the HttpGet, HttpPut, HttpPost, or HttpDelete attribute. The code snippet given below illustrates how this can be achieved:

public class AuthorsController : ApiController

{

[HttpGet]

public Author GetAuthor(id) {}

}

If you would like to allow multiple HTTP methods for an action, you can take advantage of the AcceptVerbs attribute as shown below:

public class ProductsController : ApiController

{

[AcceptVerbs("GET", "HEAD")]

public Author GetAuthor(id) { }

}

RESOURCES

Salesforce App Cloud Solution Center

WHITE PAPER

Industry Report Provides Key Insights for Cloud Migration SEE ALL Search Resources Go You can also override the action using the ActionName attribute as shown in the code snippet given below:

public class AuthorsController : ApiController

{

[HttpGet]

[ActionName("AuthorDetails")]

public Author GetAuthor(id) {}

}

Note that you can also prevent a method from being invoked as an action by leveraging the NonAction attribute as shown below. public class AuthorsController : ApiController

{

[HttpGet]

[NonAction]

public Boolean ValidateLogin(id) {}

}

---------------------------

Practical Use of ASP.NET Web API Attribute Routing in an MVC application Posted by: Mahesh Sabnis , on 8/26/2014, in Category ASP.NET MVC Views: 34488 Tweet Abstract: In ASP.NET Web API 2 a feature called Attribute Routing was introduced. This article demonstrates uses of the Attribute Routing in an ASP.NET MVC and Knockout.js application. ASP.NET MVC is now widely used for web development on the .NET platform. It can be easily be integrated with the client-side JavaScript Frameworks and Libraries. The framework has incrementally progressed from one version to the other. In the latest stable release of MVC 5 and WEB API 2 a relatively new feature named ‘Attribute Routing’ was introduced. This feature provides more control over the URIs in ASP.NET WebAPI for performing HTTP Operations. In earlier versions of WEB API we had conventional routing and separate action methods for Http GET,POST, PUT and DELETE which made it challenging to define action methods for similar Http operations (like multiple Http GET actions). In WEB API 2 with the advantage of the attribute routing, we can have multiple similar actions in the same API controller class.

Useful .NET and JavaScript Tools to improve your Productivity. Try for Free.

Note: This article shows uses of the Attribute Routing in WEB API 2. You can take an overview of the other features on WebAPI in What's New in ASP.NET Web API 2.0 .

To understand the context better, check a previous article of mine titled Customizing ASP.NET Web API Routing for the User Defined methods in ApiController class to understand the challenges of having similar Http actions in a previous version of WEB API, v1.0.

Practical need of attribute routing in ASP.NET WEB API 2.0

Consider a scenario where you need to retrieve the Sales information of each Sales Agent in each Territory. In the database, the Sales table has references of AgentId and TerritoryId as shown here:

webapi-db-relations

The above design clearly specifies that Sales is a logical child of Agent and Territory (and Product). This means if we need to access Sales data with logical combinations of Agent and the Territory using HTTP, then the URL can be really complex. For e.g. if we want to retrieve Sales data based on AgentId for a specific Territory then the expected URL will be as below:

Agent/1/AND/Territory/1 or Agent/1/OR/Territory/1,

In the earlier version, implementing such a complex URL in WEB API (v1.0) actions was difficult. In WEB API 2, attribute routing can be applied as seen below:

[Route(Agent/1/AND/Territory/1)]

Using WEB API 2 in an ASP.NET MVC Application

In this ASP.NET MVC application, we will be using WEB API 2, EntityFramework, jQuery and Knockout.js.

Step 1: Open Visual Studio 2013 and create a new Empty ASP.NET MVC Application, name it as ‘MVC_FIlteringData_WEBAPI’. In the App_Data Folder of the application, add a new SQL Server Database of the name ‘Company’ and create the following tables:

CREATE TABLE [dbo].[Agent] (

);

[AgentId] INT

[AgentName] VARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([AgentId] ASC)

IDENTITY (1, 1) NOT NULL,

CREATE TABLE [dbo].[Territory] (

);

[TerritoryId] INT

[TerritoryName] VARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([TerritoryId] ASC)

IDENTITY (1, 1) NOT NULL,

CREATE TABLE [dbo].[Product] (

);

[ProductId] INT

[ProductName] VARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([ProductId] ASC)

IDENTITY (1, 1) NOT NULL,

CREATE TABLE [dbo].[Sales] (

[SalesRecordId] INT IDENTITY (1, 1) NOT NULL,

[AgentId]

INT NOT NULL,

[TerritoryId]

INT NOT NULL,

[ProductId]

INT NOT NULL,

[Quantity]

INT NOT NULL,

PRIMARY KEY CLUSTERED ([SalesRecordId] ASC), FOREIGN KEY ([AgentId]) REFERENCES [dbo].[Agent] ([AgentId]), FOREIGN KEY ([TerritoryId]) REFERENCES [dbo].[Territory] ([TerritoryId]), FOREIGN KEY ([ProductId]) REFERENCES [dbo].[Product] ([ProductId])

); Step 2: In the project, in the Models folder, add the ADO.NET EF and select the Company database created above. After the completion of the wizard of EntityFramework, the mapping will be displayed as seen here:

webapi-db-relations

Step 3: In the Models folder add a new class:

public class SalesInfo

{

public int SalesRecordId { get; set; } public string AgentName { get; set; } public string TerritoryName { get; set; } public string ProductName { get; set; } public int Quantity { get; set; }

}

The above class is an arrangement for specifying the format of sales data returned to the client.

Step 4: In the Controllers folder add a new Empty WEB API 2 controller of the name ‘SalesInfoAPIController’. In the controller add the following code:

using MVC_FIlteringData.Models; using System.Collections.Generic; using System.Linq; using System.Web.Http;

namespace MVC_FIlteringData.Controllers

{

public class SalesInfoAPIController : ApiController

{

CompanyEntities ctx;

public SalesInfoAPIController()

{

ctx = new CompanyEntities();

}

[Route("Agents")]

public IEnumerable<Agent> GetAgents()

{

List<Agent> Agents = new List<Agent>();

var result = (from a in ctx.Agents select new { AgentId = a.AgentId, AgentName = a.AgentName }).ToList();

foreach (var item in result)

{

Agents.Add(new Agent() {AgentId = item.AgentId,AgentName = item.AgentName });

}

return Agents;

}

[Route("Territories")]

public IEnumerable<Territory> GetTerritories()

{

List<Territory> Territories = new List<Territory>();

var result = (from a in ctx.Territories select new

{

TerritoryId = a.TerritoryId, TerritoryName = a.TerritoryName }).ToList();

foreach (var item in result)

{

Territories.Add(new Territory() {TerritoryId = item.TerritoryId, TerritoryName = item.TerritoryName });

}

return Territories;

}

[Route("SalesInfo")]

public IEnumerable<SalesInfo> GetSales()

{

List<SalesInfo> Sales = new List<SalesInfo>();

var result = from s in ctx.Sales select new { SalesRecordId = s.SalesRecordId, AgentId = s.AgentId, TerritoryId = s.TerritoryId, ProductId = s.ProductId, Quantity = s.Quantity

};

foreach (var item in result)

{

Sales.Add(new SalesInfo()

{

SalesRecordId = item.SalesRecordId, AgentName = ctx.Agents.Where(id=>id.AgentId==item.AgentId).First().AgentName, TerritoryName = ctx.Territories.Where(id=>id.TerritoryId==item.TerritoryId).First().TerritoryName, ProductName = ctx.Products.Where(id=>id.ProductId==item.ProductId).First().ProductName, Quantity = item.Quantity

}

});

return Sales;

}

/// <summary> /// The Method works with Multiple Parameters in the URL /// Here filter parameter is 'AND' or 'OR' /// </summary> /// <param name="agentId"></param> /// <param name="filter"></param> /// <param name="territoryId"></param> /// <returns></returns> [Route("Agents/{agentId}/{filter}/Territories/{territoryId}")] public IEnumerable<SalesInfo> GetSales(int agentId,string filter,int territoryId)

{

List<SalesInfo> Sales = new List<SalesInfo>(); filter = filter.ToUpper();

switch (filter)

{

case "AND":

var result1 = from s in ctx.Sales

where s.AgentId == agentId && s.TerritoryId == territoryId select new

{

SalesRecordId = s.SalesRecordId, AgentId = s.AgentId, TerritoryId = s.TerritoryId, ProductId = s.ProductId, Quantity = s.Quantity

};

foreach (var item in result1)

{

Sales.Add(new SalesInfo()

{

SalesRecordId = item.SalesRecordId, AgentName = ctx.Agents.Where(id => id.AgentId == item.AgentId).First().AgentName, TerritoryName = ctx.Territories.Where(id => id.TerritoryId == item.TerritoryId).First().TerritoryName, ProductName = ctx.Products.Where(id => id.ProductId == item.ProductId).First().ProductName, Quantity = item.Quantity

}

});

break; case "OR":

var result2 = from s in ctx.Sales

where s.AgentId == agentId || s.TerritoryId == territoryId select new

{

SalesRecordId = s.SalesRecordId, AgentId = s.AgentId, TerritoryId = s.TerritoryId, ProductId = s.ProductId,

Quantity = s.Quantity

};

foreach (var item in result2)

{

Sales.Add(new SalesInfo()

{

SalesRecordId = item.SalesRecordId, AgentName = ctx.Agents.Where(id => id.AgentId == item.AgentId).First().AgentName, TerritoryName = ctx.Territories.Where(id => id.TerritoryId == item.TerritoryId).First().TerritoryName, ProductName = ctx.Products.Where(id => id.ProductId == item.ProductId).First().ProductName, Quantity = item.Quantity

}

}

});

break;

return Sales;

}

}

}

The above implementation is very important; the API controller class has all action methods for HTTP GET operations. All the GET actions are differentiated using the Route Attributes applied on them.

· The method ‘GetAgents()’ is applied with Route Attribute as [Route(“Agents”)], so the Url for the method will be:

http://server/WebSite/Agents

· One of the major advantages of the Attribute Routing is the support provided for

multi-parameters passed to the action method. In the above class, the method GetSales() accepts 3 parameters of name agentId, filter and territoryId which are of the type int, string, int respectively. The Routing for this method is defined using

[Route("Agents/{agentId}/{filter}/Territories/{territoryId}")]

In the above route, the input parameters for the method are defined using the ‘{}’ expressions. The Url for the GetSales() will look as below:

http://server/WebSite/Agents/1/AND/Territories/1

Here agentid is 1, filter is ‘AND’ and territoryId is 1. This means that for the specific AgentId, and for a specific TerritoryId, the data will be retrieved based upon the filter value like All, AND, OR.

As per the Attribute Route applied on actions of the API controller class, the URL for action will be as below:

Method Name

Attribute Route

URL

GetAgents()

[Route(Agents)]

http://Server/WebSite/Agents

GetTerritories()

[Route(Territories)]

http://Server/WebSite/Territories

GetSales()

[Route(SalesInfo)]

http://Server/WebSite/SalesInfo

GetSales()

[Route("Agents/{agentId}/{filter}/Territories/{territoryId}")]

http://Server/WebSites/Agents/1

/OR/Territories/1

Note: Filter can be ‘AND’, ‘All’, etc.

To support and enable the Attribute Routing for ASP.NET WEB API 2, the Register method from the WebApiConfig class has been used as follows:

public static class WebApiConfig

{

 

public static void Register(HttpConfiguration config)

{

// Web API configuration and services

// Web API routes config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }

);

}

}

Step 5: Using the Index Action method of the Home Controller, add a new Empty View in the project. In this Index.cshtml add the following html:

<table id="tbl1"> <tr> <td> Agent </td> <td> <select id="lstagents"></select> </td> <td> Filter </td> <td> <select id="lstoption">

</select>

</td>

<td>

Territory

</td>

<td> <select id="lstterritories"></select> </td> </tr> </table> <div></div>

<table class="clstable"> <thead> <tr> <th class="clstable">SalesRecordId</th> <th class="clstable">AgentName</th> <th class="clstable">TerritoryName</th> <th class="clstable">ProductName</th> <th class="clstable">Quantity</th> </tr> </thead> <tbody> <tr> <td class="clstable"> <span></span></td> <td class="clstable"> <span></span></td> <td class="clstable"> <span></span></td> <td class="clstable"> <span></span></td> <td class="clstable"> <span></span></td> </tr> </tbody> </table> Step 6: For this application to consume the WEB APIs, we will be using jQuery and Knockout libraries. I am using Knockout because of it’s excellent databinding features. Add these libraries in the project using NuGet Package Manager. In the Index.cshtml add the script references for jQuery and Knockout.js and styles as shown here:

<script src="~/Scripts/jquery-2.1.1.min.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script>

<style type="text/css"> .clstable{ border:double;

}

</style>

<script type="text/javascript"> var ViewModel = function (){

var self = this;

//Observable Arrays for Agents, Territories, Sales and Filters

self.Agents = ko.observableArray([]); self.Territories = ko.observableArray([]); self.Sales = ko.observableArray([]); self.FilterOptions = ko.observableArray([ "All", "AND", "OR"

]);

//Observable declaration for Selected Agent, Territory and Filters

self.SelectedAgent = ko.observable(); self.SelectedTerritory = ko.observable(); self.SelectedFilter = ko.observable();

var filter;

loadagents();

loadterritories();

//The Function used to Load Agents function loadagents() { $.ajax({ url: "/Agents", type: "GET" }).done(function (resp) { ko.utils.arrayForEach(resp, function (item) { self.Agents.push({AgentId:item.AgentId,AgentName:item.AgentName});

}); }).error(function (err) { alert("Error " + err.status + " " + err.statusText);

});

}

//The Function used to Load Terrotories function loadterritories() { $.ajax({ url: "/Territories", type: "GET" }).done(function (resp) {

ko.utils.arrayForEach(resp, function (item) {

self.Territories.push({TerritoryId:item.TerritoryId,TerritoryName:item.TerritoryName}); }); }).error(function (err) { alert("Error " + err.status + " " + err.statusText);

}

});

self.SelectedAgent.subscribe(function (val) {

if (self.SelectedTerritory() !== 'undefined') { loadSalesData(val, filter, self.SelectedTerritory());

}

else { alert("Please Select the Territory Name");

}

});

self.SelectedTerritory.subscribe(function (val) {

if (self.SelectedAgent() !== 'undefined') { loadSalesData(self.SelectedAgent(),filter,val);

}

else { alert("Please Select the Agent Name");

}

});

self.SelectedFilter.subscribe(function (v) { filter = v;

loadSalesData(self.SelectedAgent(), filter, self.SelectedTerritory());

});

//Function to load Sales Information //If the filter is 'All' the complete Sales information will be loaded //Else the Sales information based upon 'AND' and 'OR' condition combination of the

//Agent and territory will be loaded function loadSalesData(agentId,filter,territoryId) { var url; if (filter === 'All') { url = "/SalesInfo";

}

else { url = "/Agents/" + agentId + "/" + filter + "/Territories/" + territoryId;

}

$.ajax({ url: url, type:"GET" }).done(function (resp) { self.Sales(resp); }).error(function (err) { alert("Error " + err.status + " " + err.statusText);

});

}

}; ko.applyBindings(new ViewModel()); </script> In the above JavaScript, the ViewModel code has the following specification:

· The code defines observable arrays for storing Agents, Territories, Sales and Filter Options. The FilterOptions observable array defines search conditions e.g. ALL, will return all sales records, whereas AND and OR return sales records based upon the logical conditions of Agent and Territory.

· Functions ‘loadagents()’ and ‘loadterritories()’ will make call to WEB API and retrieve the respective data from the server which will be pushed in the respective observable array.

· Function ‘loadSalesData()’ accepts agentId, filter and territoryId as input parameters. If the

filter is ‘All’ then all sales data will be retrieved using ‘/SalesInfo’ URL. If the value of the filter is either ‘AND’ or ‘OR’ then the URL will be formed based upon the ‘AND’ or ‘OR’ combination of agentId and territoryId and the sales data will be fetched.

Step 7: Since we have used Knockout library, we need to bind the Observables and ObservableArray to HTML UI as below:

<table id="tbl1">

<tr>

<td> Agent </td> <td> <select id="lstagents" data-bind="options:Agents,optionsCaption:'Choose Agent Name',value:SelectedAgent,optionsText:'AgentName',optionsValue:'AgentId'"></select> </td> <td> Filter </td> <td> <select id="lstoption" data-bind="options:FilterOptions,value:SelectedFilter">

</select> </td> <td> Territory </td> <td> <select id="lstterritories" data-bind="options:Territories,optionsCaption:'Choose Territory Name',value:SelectedTerritory,optionsText:'TerritoryName',optionsValue:'TerritoryId'"></select> </td> </tr> </table> <div></div>

<table class="clstable"> <thead> <tr> <th class="clstable">SalesRecordId</th> <th class="clstable">AgentName</th> <th class="clstable">TerritoryName</th> <th class="clstable">ProductName</th> <th class="clstable">Quantity</th> </tr> </thead> <tbody data-bind="foreach:Sales"> <tr> <td class="clstable"> <span data-bind="text:SalesRecordId"></span></td> <td class="clstable"> <span data-bind="text:AgentName"></span></td> <td class="clstable"> <span data-bind="text:TerritoryName"></span></td> <td class="clstable"> <span data-bind="text:ProductName"></span></td> <td class="clstable"> <span data-bind="text:Quantity"></span></td>

</tr> </tbody> </table> In the above code, the html < select > element is bound with the ObservableArray using ‘options’ binding, the value binding is set to the Observable declared in the ViewModel. The optionsText and optionsValue corresponds to the selectedtext and selectedvalue from the < select > element.

Step 8: Run the application and the result will be as seen here:

When the page is loaded, it will show all records from sales because the filter is set to value ‘All’ and the result will be as seen here:

filter-all

Select the AgentName and the TerritoryName from the List and change the Filter to ‘AND’, the result will be as below:

sales-record-knockout-webapi

The above screenshot shows the sale by Agent Deepak in Maharashtra Territory.

Change the filter to OR, the result will be as below:

filter-all

Conclusion: The Attribute Routing provided with ASP.NET WEB API 2 makes it easy to define

clear URLs with multiple parameter for action methods. The major advantage here is that in one API controller class, we can have multiple methods of same types (multiple HTTP Get etc.)

---------------------------------

This is the 3rd post in a series of ASP.NET MVC 4 Tutorials. The first two posts were on ASP.NET MVC 4 Bundling and Minification and ASP.NET MVC 4 Entity Framework and Data Migrations. In this tutorial I want to briefly look at the new Web API integration in ASP.NET MVC 4. Web API introduces a new route for API calls as well as an ApiController that responds to Get, Post, Put, and Delete requests from REST Clients. Web API introduces formatters that can do content negotiation via XML, JSON, etc. as well as provides better customization of the response using HttpResponseMessage.

ASP.NET MVC 4 introduces several new project types after you initially pick that you want to develop an ASP.NET MVC 4 Web Application. One of those application types is the new Web API Project.

ASP.NET MVC 4 Web API Project

If you choose the Web API Project, a new Web API Controller Class is created for you to provide an example of responding to Get, Post, Put, and Delete requests for your API.

public class ValuesController : ApiController {

// GET /api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" };

}

// GET /api/values/5 public string Get(int id) { return "value";

}

// POST /api/values public void Post(string value) {}

// PUT /api/values/5 public void Put(int id, string value) {}

// DELETE /api/values/5 public void Delete(int id) {}

}

With the Web API Project you will also notice a new API specific route added to the RouteTable in Global.asax.cs.

routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }

); Running the project and navigating to ~/api/values will display a list of the values in XML Format. I removed the XML namespacing to keep things simple.

<ArrayOfString>

<string>value1</string>

<string>value2</string>

</ArrayOfString> If you change the Accept Header so that you will only accept JSON, the same controller action will send the values via JSON instead.

["value1","value2"]

Creating a new Web API Controller Class is as simple as using the Add Controller Recipe in ASP.NET MVC 4 and choosing the Empty API controller Tempate

Web API Controller Class in ASP.NET MVC 4

Or, you could just create one via Add Item which has a new Web API Controller Class as an option.

I created a simple ProductsController that handles all the CRUD options for products in a mythical e-commerce website.

public class ProductsController : ApiController { private readonly IRepository<Product> _repository;

public ProductsController(IRepository<Product> repository) { _repository = repository;

}

public IEnumerable<Product> Get() { return _repository.Queryable();

}

public Product Get(int id) { var product = _repository.Get(id);

if (product == null) throw new HttpResponseException(HttpStatusCode.NotFound);

return product;

}

public HttpResponseMessage<Product> Post(Product product) { _repository.Add(product);

var response = new HttpResponseMessage<Product> (product, HttpStatusCode.Created);

response.Headers.Location = new Uri(Request.RequestUri, Url.Route(null, new {id = product.Id}));

return response;

}

public Product Put(int id, Product product) { var existingProduct = _repository.Get(id);

if (existingProduct == null) throw new HttpResponseException(HttpStatusCode.NotFound);

_repository.Save(product);

return product;

}

public HttpResponseMessage Delete(int id) { _repository.Delete(id);

return new HttpResponseMessage(HttpStatusCode.NoContent);

}

}

You can see that in some instances I am just returning a Product and in other instances I am returning a more informational HttpResponseMessage. For example, in the case of the Post of a new Product, I need to tell the REST Client the new location of the newly added product in the header. In other actions I am also throwing a HttpResponseException if the resource requested is not found. Validation, Logging, and other concerns are being done in various ActionFilters just like in your normal ASP.NET MVC Projects. Try to pull those cross-cutting concerns out of the main logic as much as possible.

If you want to enable various paging and querying of products you can make a slight change to the Get ApiController Action and return an IQueryable<Product> as opposed to IEnumerable<Product>.

public IQueryable<Product> Get() { return _repository.Queryable();

}

Now from your browser you can add paging, filtering, sorting, and other options to shape the data. Here is an example call that does paging and sorting.

api/products?$skip=2&$top=2&$orderby=Title

The XML Response by the browser is:

<ArrayOfProduct> <Product>

<Id>3</Id>

<Title>RipStik</Title>

<Price>69.00</Price>

</Product> <Product>

<Id>4</Id>

<Title>Shred Sled</Title>

<Price>49.00</Price>

</Product> </ArrayOfProduct> Or the JSON Response:

[{"Id":3,"Price":69.00,"Title":"RipStik"},

{"Id":4,"Price":49.00,"Title":"Shred Sled"}] ASP.NET Web API integration with ASP.NET MVC 4 is really slick. Now you can easily create an API for your website using the new ApiController Base Class to respond to REST Clients.

---------------------------------------------------------------------------------------------------------

**Authentication and Authorization Authentication and Authorization in ASP.NET Web API By Mike Wasson|November 27, 2012 889 of 983 people found this helpful Print You've created a web API, but now you want to control access to it. In this series of articles, we'll look at some options for securing a web API from unauthorized users. This series will cover both authentication and authorization.

Authentication is knowing the identity of the user. For example, Alice logs in with her username and password, and the server uses the password to authenticate Alice. Authorization is deciding whether a user is allowed to perform an action. For example, Alice has permission to get a resource but not create a resource. The first article in the series gives a general overview of authentication and authorization in ASP.NET Web API. Other topics describe common authentication scenarios for Web API.

Thanks to the people who reviewed this series and provided valuable feedback: Rick Anderson, Levi Broderick, Barry Dorrans, Tom Dykstra, Hongmei Ge, David Matson, Daniel Roth, Tim Teebken.

Authentication

Web API assumes that authentication happens in the host. For web-hosting, the host is IIS, which uses HTTP modules for authentication. You can configure your project to use any of the authentication modules built in to IIS or ASP.NET, or write your own HTTP module to perform custom authentication.

When the host authenticates the user, it creates a principal, which is an IPrincipal object that represents the security context under which code is running. The host attaches the principal to the current thread by setting Thread.CurrentPrincipal. The principal contains an associated Identity object that contains information about the user. If the user is authenticated, the Identity.IsAuthenticated property returns true. For anonymous requests, IsAuthenticated returns false. For more information about principals, see Role-Based Security.

HTTP Message Handlers for Authentication

Instead of using the host for authentication, you can put authentication logic into an HTTP message handler. In that case, the message handler examines the HTTP request and sets the principal.

When should you use message handlers for authentication? Here are some tradeoffs:

An HTTP module sees all requests that go through the ASP.NET pipeline. A message handler only sees requests that are routed to Web API. You can set per-route message handlers, which lets you apply an authentication scheme to a specific route. HTTP modules are specific to IIS. Message handlers are host-agnostic, so they can be used with both web-hosting and self-hosting. HTTP modules participate in IIS logging, auditing, and so on. HTTP modules run earlier in the pipeline. If you handle authentication in a message handler, the principal does not get set until the handler runs. Moreover, the principal reverts back to the previous principal when the response leaves the message handler. Generally, if you don't need to support self-hosting, an HTTP module is a better option. If you need to support self-hosting, consider a message handler.

Setting the Principal

If your application performs any custom authentication logic, you must set the principal on two places:

Thread.CurrentPrincipal. This property is the standard way to set the thread's principal in .NET. HttpContext.Current.User. This property is specific to ASP.NET. The following code shows how to set the principal:

private void SetPrincipal(IPrincipal principal)

{

Thread.CurrentPrincipal = principal; if (HttpContext.Current != null)

{

HttpContext.Current.User = principal;

}

}

For web-hosting, you must set the principal in both places; otherwise the security context may become inconsistent. For self-hosting, however, HttpContext.Current is null. To ensure your code is host-agnostic, therefore, check for null before assigning to HttpContext.Current, as shown.

Authorization

Authorization happens later in the pipeline, closer to the controller. That lets you make more granular choices when you grant access to resources.

Authorization filters run before the controller action. If the request is not authorized, the filter returns an error response, and the action is not invoked. Within a controller action, you can get the current principal from the ApiController.User property. For example, you might filter a list of resources based on the user name, returning only those resources that belong to that user.

Using the [Authorize] Attribute

Web API provides a built-in authorization filter, AuthorizeAttribute. This filter checks whether the user is authenticated. If not, it returns HTTP status code 401 (Unauthorized), without invoking the action.

You can apply the filter globally, at the controller level, or at the level of inidivual actions.

Globally: To restrict access for every Web API controller, add the AuthorizeAttribute filter to the global filter list:

public static void Register(HttpConfiguration config)

{

config.Filters.Add(new AuthorizeAttribute());

}

Controller: To restrict access for a specific controller, add the filter as an attribute to the controller:

// Require authorization for all actions on the controller.

[Authorize]

public class ValuesController : ApiController

{

 

public HttpResponseMessage Get(int id) {

}

public HttpResponseMessage Post() {

}

}

Action: To restrict access for specific actions, add the attribute to the action method:

public class ValuesController : ApiController

{

 

public HttpResponseMessage Get() {

}

// Require authorization for a specific action. [Authorize] public HttpResponseMessage Post() {

}

}

Alternatively, you can restrict the controller and then allow anonymous access to specific actions, by using the [AllowAnonymous] attribute. In the following example, the Post method is restricted, but the Get method allows anonymous access.

[Authorize]

public class ValuesController : ApiController

{

 

[AllowAnonymous] public HttpResponseMessage Get() {

}

public HttpResponseMessage Post() {

}

}

In the previous examples, the filter allows any authenticated user to access the restricted methods; only anonymous users are kept out. You can also limit access to specific users or to users in specific roles:

// Restrict by user:

[Authorize(Users="Alice,Bob")]

public class ValuesController : ApiController

{

}

// Restrict by role:

[Authorize(Roles="Administrators")]

public class ValuesController : ApiController

{

}

The AuthorizeAttribute filter for Web API controllers is located in the System.Web.Http namespace. There is a similar filter for MVC controllers in the System.Web.Mvc namespace, which is not compatible with Web API controllers.

Custom Authorization Filters

To write a custom authorization filter, derive from one of these types:

AuthorizeAttribute. Extend this class to perform authorization logic based on the current user and the user’s roles. AuthorizationFilterAttribute. Extend this class to perform synchronous authorization logic that is not necessarily based on the current user or role. IAuthorizationFilter. Implement this interface to perform asynchronous authorization logic; for example, if your authorization logic makes asynchronous I/O or network calls. (If your authorization logic is CPU-bound, it is simpler to derive from AuthorizationFilterAttribute, because then you don’t need to write an asynchronous method.) The following diagram shows the class hierarchy for the AuthorizeAttribute class.

Authorization Inside a Controller Action

In some cases, you might allow a request to proceed, but change the behavior based on the principal. For example, the information that you return might change depending on the user’s role. Within a controller method, you can get the current principle from the ApiController.User property.

public HttpResponseMessage Get()

{

if (User.IsInRole("Administrators"))

{

}

//

}

-----------------------

Token Based Authentication in Web API 2 By Rajeev Ranjan on Jan 01, 2015

This article explains the OWIN OAuth 2.0 Authorization and how to implement an OAuth 2.0 Authorization server using the OWIN OAuth middleware.

150.4k

12

facebook twitter linkedIn google Plus Reddit expand Download 100% FREE Spire Office APIs Introduction

This article explains the OWIN OAuth 2.0 Authorization and how to implement an OAuth 2.0 Authorization server using the OWIN OAuth middleware.

The OAuth 2.0 Authorization framwork is defined in RFC 6749. It enables third-party applications to obtain limited access to HTTP services, either on behalf of a resource owner by producing a desired effect on approval interaction between the resource owner and the HTTP service or by allowing the third-party application to obtain access on its own behalf.

Now let us talk about how OAuth 2.0 works. It supports the following two (2) different authentication variants:

Three-Legged Two-Legged Three-Legged Approach: In this approach, a resource owner (user) can assure a third-party client (mobile applicant) about the identity, using a content provider (OAuthServer) without sharing any credentials to the third-party client.

Two-Legged Approach: This approach is known as a typical client-server approach where the client can directly authenticate the user with the content provider.

Multiple classes are in OAuth Authorization

OAuth Authorization can be done using the following two classes:

IOAuthorizationServerProvider

OAuthorizationServerOptions

IOAuthorizationServerProvider

It extends the abstract AuthenticationOptions from Microsoft.Owin.Security and is used by the core server options such as:

Enforcing HTTPS Error detail level Token expiry

Endpoint paths We can use the IOAuthorizationServerProvider class to control the security of the data contained in the access tokens and authorization codes. System.Web will use machine key data protection, whereas HttpListener will rely on the Data Protection Application Programming Interface (DPAPI). We can see the various methods in this class.

IOAuthAuthorizationServerProvider

OAuthorizationServerOptions

IOAuthAuthorizationServerProvider is responsible for processing events raised by the authorization server. Katana ships with a default implementation of IOAuthAuthorizationServerProvider called OAuthAuthorizationServerProvider. It is a very simple starting point for configuring the authorization server, since it allows us to either attach individual event handlers or to inherit from the class and override the relevant method directly. We can see the various methods in this class.

OAuthAuthorizationServerOptions

From now we can start to learn how to build an application having token-based authentication.

Step 1

Open the Visual Studio 2013 and click New Project.

Step 2

Select the Console based application and provide a nice name for the project.

NewProject

Step 3

Create a Token class and Add some Property.

public class Token

{

[JsonProperty("access_token")] public string AccessToken { get; set; }

[JsonProperty("token_type")] public string TokenType { get; set; }

[JsonProperty("expires_in")]

public int ExpiresIn { get; set; }

[JsonProperty("refresh_token")] public string RefreshToken { get; set; }

}

Step 4 Create a startup class and use the IOAuthorizationServerProvider class as well as the OAuthorizationServerOptions class and set the dummy password and username. I have also set the default TokenEndpoint and TokenExpire time.

public class Startup

{

public void Configuration(IAppBuilder app)

{

var oauthProvider = new OAuthAuthorizationServerProvider

{

 

OnGrantResourceOwnerCredentials = async context =>

{

if (context.UserName == "rranjan" && context.Password == "password@123")

{

var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType); claimsIdentity.AddClaim(new Claim("user", context.UserName)); context.Validated(claimsIdentity); return;

}

context.Rejected();

},

OnValidateClientAuthentication = async context =>

{

string clientId; string clientSecret;

if (context.TryGetBasicCredentials(out clientId, out clientSecret))

{

if (clientId == "rajeev" && clientSecret == "secretKey")

{

context.Validated();

}

}

}

};

var oauthOptions = new OAuthAuthorizationServerOptions

{

AllowInsecureHttp = true,

TokenEndpointPath = new PathString("/accesstoken"), Provider = oauthProvider, AuthorizationCodeExpireTimeSpan= TimeSpan.FromMinutes(1),

AccessTokenExpireTimeSpan=TimeSpan.FromMinutes(3),

SystemClock= new SystemClock()

}; app.UseOAuthAuthorizationServer(oauthOptions); app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

var config = new HttpConfiguration(); config.MapHttpAttributeRoutes(); app.UseWebApi(config);

}

}

Step 5

Add a controller inherited from API controller.

[Authorize]

public class TestController : ApiController

{

[Route("test")]

public HttpResponseMessage Get()

{

return Request.CreateResponse(HttpStatusCode.OK, "hello from a secured resource!");

}

}

Step 6

Now check the authorization on the basis of the token, so in the Program class validate it.

static void Main()

{

string baseAddress = "http://localhost:9000/";

// Start OWIN host

using (WebApp.Start<Startup>(url: baseAddress))

{

var client = new HttpClient(); var response = client.GetAsync(baseAddress + "test").Result; Console.WriteLine(response);

Console.WriteLine();

var authorizationHeader =

Convert.ToBase64String(Encoding.UTF8.GetBytes("rajeev:secretKey"));

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationHeader);

var form = new Dictionary<string, string>

{

{"grant_type", "password"}, {"username", "rranjan"}, {"password", "password@123"},

};

var tokenResponse = client.PostAsync(baseAddress + "accesstoken", new FormUrlEncodedContent(form)).Result; var token = tokenResponse.Content.ReadAsAsync<Token>(new[] { new JsonMediaTypeFormatter() }).Result;

Console.WriteLine("Token issued is: {0}", token.AccessToken);

Console.WriteLine();

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken); var authorizedResponse = client.GetAsync(baseAddress + "test").Result; Console.WriteLine(authorizedResponse); Console.WriteLine(authorizedResponse.Content.ReadAsStringAsync().Result);

}

Console.ReadLine();

}

Output

When all the authentication of username and password is not correct then it doesn't generate the token. authorizationWebAPI

When the Authentication is passed we get success and we get a token.

successTokenWebAPI

Summary

In this article we have understand the token-based authentication in Web API 2. I hope you will like it.

-------------------------------------------------------------------------------------------------------------

Cors:

List

Enabling Cross-Origin Requests in ASP.NET Web API 2 By Mike Wasson|July 15, 2014 801 of 897 people found this helpful Print Browser security prevents a web page from making AJAX requests to another domain. This restriction is called the same-origin policy, and prevents a malicious site from reading sentitive data from another site. However, sometimes you might want to let other sites call your web API.

Cross Origin Resource Sharing (CORS) is a W3C standard that allows a server to relax the same-origin policy. Using CORS, a server can explicitly allow some cross-origin requests while rejecting others. CORS is safer and more flexible than earlier techniques such as JSONP. This tutorial shows how to enable CORS in your Web API application.

Software versions used in the tutorial

Introduction Create the WebService Project Create the WebClient Project Enable CORS in Web API How CORS Works Scope Rules for [EnableCors] Set the Allowed Origins Set the Allowed HTTP Methods Set the Allowed Request Headers Set the Allowed Response Headers Passing Credentials in Cross-Origin Requests Custom CORS Policy Providers Browser Support Introduction

This tutorial demonstrates CORS support in ASP.NET Web API. We’ll start by creating two ASP.NET projects – one called “WebService”, which hosts a Web API controller, and the other called “WebClient”, which calls WebService. Because the two applications are hosted at different domains, an AJAX request from WebClient to WebService is a cross-origin request.

What is "Same Origin"?

Two URLs have the same origin if they have identical schemes, hosts, and ports. (RFC 6454)

These two URLs have the same origin:

http://example.com/foo.html http://example.com/bar.html These URLs have different origins than the previous two:

http://example.net - Different domain http://example.com:9000/foo.html - Different port https://example.com/foo.html - Different scheme http://www.example.com/foo.html - Different subdomain Internet Explorer does not consider the port when comparing origins.

Create the WebService Project

This section assumes you already know how to create Web API projects. If not, see Getting Started with ASP.NET Web API.

Start Visual Studio and create a new ASP.NET Web Application project. Select the Empty project template. Under “Add folders and core references for”, select the Web API checkbox. Optionally, select the "Host in Cloud" option to deploy the app to Mircosoft Azure. Microsoft offers free web hosting for up to 10 websites in a free Azure trial account.

Add a Web API controller named TestController with the following code:

using System.Net.Http; using System.Web.Http;

namespace WebService.Controllers