The ASP. NET Web API displays entity Link-related aspects, apilink

Source: Internet
Author: User

The ASP. NET Web API displays entity Link-related aspects, apilink

 

Sometimes, when we request an object from the server, we want to return the following format:

 

Links :[
Href: http: // localhost: 8901/api/user/diaries/2013-08-17,
Rel: "self ",
Method: "GET ",
IsTemplated: false
],
CurrentDate: "2013-08-17"

 

First, a Link-related class is abstracted:

 

public class LinkModel{    public stirng Href{get;set;}    public stirng Rel{get;set;}    public string Method{get;set;}    public bool IsTemplated{get;set;}}

 

Put it in a view model:

 

Public class DiaryModel {// storage and model-related Links public ICollection <LinkModel> Links {get; set;} public DateTime CurrentDate {get; set ;}} public class Diary {public int Id {get; set;} public DateTime CurrentDate {get; set ;}}

 

ModelFactory is used to convert the view model and the domain model.

 

Public class ModelFactory {private UrlHelper _ urlHelper; public ModelFactory (HttpRequestMessage request) {_ urlHelper = new UrlHelper (request );} // convert the domain model to the view Model public DiaryModel Create (Diary d) {return new DiaryModel () {Links = new List <LinkModel> {CreateLink (_ urlHelper. link ("Diaryis", new {diaryid = d. currentDate. toString ("yyyy-MM-dd")}), "self") ;}, CurrentDate = d. currentDate} public LinkMode L CreateLink (string href, string rel, string method = "GET", bool isTemplated = false) {return new LinkModel () {Href = href, Rel = rel, Method = method, isTemplated = isTemplated }}// the view model is converted to the public Diary Parse (DiaryModel model) {try {var entity = new Diary (); var selfLink = model. links. where (l => l. rel = "self "). firstOrDefault (); if (selfLink! = Null &&! String. isNullOrWhiteSpace (selfLink. href) {// retrieve the primary key var Uri = new uri (selfLink. href); entity. id = int. parse (uri. segments. last ();} entity. currentDate = model. currentDate; return entity;} catch (Exception ex ){}}}

 

Diaries controller, routing:

 

//api/user/diaries//api/user/diaries/2001-01-01config.Routes.MapHttpRoute(    name: "Diaries",    routeTemplate: "api/user/diaries/{dairyid}",    defaults: new {controller="diaries", diaryid=RouteParameter.Optional})

 

In this way, send the http: // localhost: 8901/api/user/diaries/2013-08-17 GET request on the client and GET the following response:

 

Links :[
Href: http: // localhost: 8901/api/user/diaries/2013-08-17,
Rel: "self ",
Method: "GET ",
IsTemplated: false
],
CurrentDate: "2013-08-17"

In the actions related to the returned page, you can also return the related Link section.

First define a base class controller:

 

Public abstract class BaseController: ApiController {ICountingKsRepository _ repo; ModelFactory _ modelFactory; public BaseController (ICountingKsRepository repo) {_ repo = repo; // it is a bit late to write in the constructor, you must wait for the instantiate _ modelFactory to have a value // _ modelFactory = new ModelFactory (this. request);} protected ModelFactory TheModelFactory {get {if (_ modelFactory = null) {_ modelFactory = new ModelFactory (this. request, TheRepository);} return _ modelFactory;} protected ICountingsRepository thereappsitory {get {return _ repo ;}}}

 

It can be seen that it is a good habit to encapsulate the common part into the base class controller, and then the base class controller subclass obtains some aspects through the attribute.

To the specific controller:

 

Public class FoodsController: BaseController {ICountingKsRepoisotry _ repo; ModelFactory _ modelFactory; public FoodsController (ICountingKsRepository repo): base (repo) {} const int PAGE_SIZE = 50; public object Get (bool includeMeasures = true, int page = 0) {IQueryable <Food> query; if (includeMeausres) {query = TheRepository. getAllFoodsWithMeausres ();} else {query = TheRepository. getAllFoods ();} // Calculate the total var baseQuery = query. orderBy (f => f. description); // using System. web. http. routing var helper = new UrlHelper (Request); var links = new List <LinkModel> (); if (page> 0) {links. add (TheModelFactory. createLink (helper. link ("Food", new {page = page-1}, "prevPage");} if (page <totalPages-1) {links. add (TheModelFactory. createLink (helper. link ("Food", new {page = page + 1}, "nextPage "));}/ /Save the url of the previous and next pages. // var prevUrl = page> 0? Helper. Link ("Food", new {page = page-1}): ""; // var nextUrl = page> 0? Helper. link ("Food", new {page = page + 1}): ""; // total output var totalCount = baseQuery. count (); var totalPages = Math. ceiling (double) totalCount/PAGE_SIZE); var result = baseQuery. skip (PAGE_SIZE * page ). take (PAGE_SIZE ). toList (). select (f => TheModelFactory. foodFromDomainToView (f); // It is convenient for the client to receive return new {TotalCount = totalCount, TotalPages = totalPages, Result = result, Links = links // PrevPageUrl = prevUrl, // NextPageUrl = nextUrl,} public FoodModel Get (int foodid) {return TheModelFactory. foodFromDomainToView (TheRepository. getFood (foodid ));}}

 

Client request: localhost: 8901/api/nutrition/foods

{
TotalCount: 800,
TotalPages: 151,
Links :[
{
Href: http: // localhost: 8901/api/nutrition/foods? Page = 1,
Rel: "prevPage ",
Method: "GET ",
IsTemplated: false,
},
{
Href: http: // localhost: 8901/api/nutrition/foods? Page = 2,
Rel: "nextPage ",
Method: "GET ",
IsTemplated: false
}
],
Result: [...]
}


In addition, the serialization process can be controlled.

In the LinkModel View:

 

public class LinkModel{    public stirng Href{get;set;}    public stirng Rel{get;set;}    public string Method{get;set;}    public bool IsTemplated{get;set;}}

 

I may not want IsTemplated to be displayed. How can I achieve this in the serialization process?

-- Use the jsonFormatter. SerializerSettings. Converts attribute to control the display mode of serialized json data.

In WebApiConfig. cs:

 

var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault();jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNameContractResolver();jsonFormatter.SerializerSettings.Converts(new LinkModelConverter());

 

The LinkModelConverter class must inherit the JsonConverter class.

 

public class LinkModelConverter : JsonConverter{    public override bool CanConvert(Type objectType)    {        return objectType.Equals(typeof(LinkModel));    }        public override object ReadJson(JsonReader reader, Type object)    {        return reader.Value;    }        public override void WriteJson(JsonWriter wrtier, object value)    {        var model = value as LinkModel;        if(model != null)        {            wirter.WriteStartObject();                        writer.WirteProeprtyName("href");            writer.WriteValue(model.Href);                        writer.WriteProeprtyName("rel");            writer.WriteValue(model.Rel);                        if(!model.Method.Equals("GET",StringComparison.ordinalIgnoreCase))            {                writer.WritePropertyName("method");                writer.WriteValue(model.Method);            }                        if(model.IsTemplated)            {                writer.WriterPropertyName("isTemplated");                writer.WriteValue(model.IsTemplated);            }                        writer.WriteEndObject();        }    }}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.