Microsoft
/web
ASP.NET Web API
Phan Minh Luân -
DTH216012
Phan Kim Ngân –
DTH216039
Ngô Huy Phúc –
DTH216092
Nội dung
ASP.NET Web API là gì và tại sao lại sử dụng?
Tổng quan về Rest & Soap
Basic Web API Structure (cấu trúc cơ bản WEB
API)
Web API Routing & Actions (định tuyến và
hành động)
Validation ( Xác thực)
Odata
Content Negotiation ( đàm phán nội dung)
Http Client
ASP.NET Web API
ASP.NET Web API là một khuôn khổ để xây
dựng HTTP trong nền tảng .NET Framework.
WCF Tập trung vào tính linh hoạt của truyền
tải.
WebAPI Tập trung vào HTTP
Build Richer Apps
Reach More Clients
Reach more clients ( tiếp cận nhiều khách
hàng )
Client appropriate format ( định dạng phù hợp
với khách hàng)
Embrace http
Use http as an application protocol
Amazon has both Rest and Soap based
services and 85% of the usage is Rest based.
SOAP
A specification
Rest
A set of architectural principal
Resource Oriented Architecture
Resources
Their names(URIs)
Uniform Intercace
Asmx
Ws*
Wcf
Wcf 3.5
Wcf rest starter kit
Wcf Rest service
ASP.Net Web API
Web API - 1 slide
public class ValueController : ApiController
{
// GET <controller>
public string Get()
{
return "Demo result at " +
DateTime.Now.ToString();
}
}
protected void Application_Start(object sender, EventArgs e)
{
GlobalConfiguration.Configuration.Routes.Add("default", new
HttpRoute("{controller}"));
Demo
Sample Read-only Model and Controller
public class Person
Step 1: {
public int Id { get; set; }
Create a Model public string Name { get; set; }
}
public class PersonController :
Step 2: ApiController
{
Make an API Controller List<Person> _people;
public PersonController()
{
_people = new List<Person>();
_people.AddRange(new Person[]
{
new Person { Id = 1, Name =
"Chuck Norris" },
new Person { Id = 2, Name =
"David Carradine" },
new Person { Id = 3, Name =
"Bruce Lee" }
});
}
}
Microsoft /
®
web
Read-only Controller Actions to return data
// GET /api/person
Step 3: public IEnumerable<Person> Get()
{
Return everything return _people;
}
// GET /api/person/5
Step 4: public Person Get(int id)
{
Return one item return _people.First(x => x.Id ==
id);
}
Microsoft /
®
web
Routing a Web API Using Global.asax.cs
public static void
Routing: RegisterRoutes(RouteCollection routes)
{
Familiar syntax, routes.MapHttpRoute(
conventional approach name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id =
RouteParameter.Optional }
);
}
Microsoft /
®
web
Routing and Actions
Web API uses the HTTP method, not the URI
path, to select the action.
To determine which action to invoke, the
framework uses a routing table.
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id =
RouteParameter.Optional }
);
If no route matches, the client receives a 404
error.
Custom name mapping to http actions.
[HttpGet]
public Product FindProduct(id) {}
or can override the action name by using
the ActionName attribute.
api/products/thumbnail/id
[HttpGet]
[ActionName("Thumbnail")]
public HttpResponseMessage
GetThumbnailImage(int id);
To prevent a method from getting invoked as
an action, use the NonAction attribute.
// Not an action method.
[NonAction]
public string GetPrivateData() { ... }
Exception Handling
By default, most exceptions are translated into an HTTP response with
status code 500, Internal Server Error.
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent(string.Format("No product with ID
= {0}", id)),
}
throw new HttpResponseException(resp);
}
return item;
}
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Date: Thu, 09 Aug 2012 23:27:18 GMT
Content-Length: 51
{
"Message": “No product with id = 12 not
found"
}
You can customize how Web API handles exceptions by
writing an exception filter.
public class NotImplExceptionFilterAttribute :
ExceptionFilterAttribute
{
public override void
OnException(HttpActionExecutedContext context)
{
if (context.Exception is NotImplementedException)
{
context.Response = new
HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}
There are several ways to register a Web API
exception filter:
By action
By controller
Globally
[NotImplExceptionFilter]
GlobalConfiguration.Configuration.Filters.Add(
new
ProductStore.NotImplExceptionFilterAttribute());
Validation
public class Product
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public decimal Price { get; set; }
[Range(0,999)]
public double Weight { get; set; }
}
if (ModelState.IsValid)
{
return new
HttpResponseMessage(HttpStatusCode.OK);
}
else
{
return new
HttpResponseMessage(HttpStatusCode.BadRe
quest);
}
public class ModelValidationFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ModelState.IsValid == false)
{
var errors = new Dictionary<string, IEnumerable<string>>();
foreach (KeyValuePair<string, ModelState> keyValue in
actionContext.ModelState)
{
errors[keyValue.Key] = keyValue.Value.Errors.Select(e =>
e.ErrorMessage);
}
actionContext.Response =
actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors);
}
}
}
HTTP/1.1 400 Bad Request
Server: ASP.NET Development Server/10.0.0.0
Date: Fri, 20 Jul 2012 21:42:18 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 239
Connection: Close
{
"product": [
"Required property 'Name' not found in JSON. Line 1, position 18."
],
"product.Name": [
"The Name field is required."
],
"product.Weight": [
"The field Weight must be between 0 and 999."
]
}
GlobalConfiguration.Configuration.Filters.Add(
new ModelValidationFilterAttribute());
[ModelValidationFilter]
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
[JsonIgnore]
public int ProductCode { get; set; } //
omitted
}
[DataContract]
public class Product
{
[DataMember]
public string Name { get; set; }
[DataMember]
public decimal Price { get; set; }
public int ProductCode { get; set; } //
omitted by default
}
OData
http://localhost/Products?$orderby=Na
me
The EnableQuerySupport method enables
query options gloablly for any controller
action that returns anIQueryable type.
To enable only for specific action/controller
[Queryable]
IQueryable<Product> Get() {}
Option Description
:
Filters the results, based on a
$filter
Boolean condition.
Tells the server to include the total
count of matching entities in the
$inlinecount
response. (Useful for server-side
paging.)
$orderby Sorts the results.
$skip Skips the first n results.
$top Returns only the first n the results.
http://localhost/odata/Products?
$orderby=Category,Price desc
[Queryable(PageSize=10)]
public IQueryable<Product> Get()
{
return products.AsQueryable();
}
[Queryable(AllowedQueryOptions=
AllowedQueryOptions.Skip |
AllowedQueryOptions.Top)]
Demo
Content Negotiation
The process of selecting the best
representation for a given response when
there are multiple representations available.
Accept:
Accept-Charset:
Accept-Language:
Accept-Encoding:
HttpClient
HttpClient is a modern HTTP client for ASP.NET
Web API. It provides a flexible and extensible
API for accessing all things exposed through
HTTP.
HttpClient is the main class for sending and
receiving HttpRequestMessages and
HttpResponseMessages.
Task based pattern
Same HttpClient instance can be used for
multiple URIs even from different domains.
Demo
Self Reading
Authentication and Authorization
Extensibility
Tracing and Debugging
Thanks