ASP.NET Web API中展示实体Link相关的方面
有时候,向服务端请求一个实体,我们希望返回如下的格式:
links: [
href: http://localhost:8901/api/user/diaries/2013-08-17,
rel: "self",
method: "GET",
isTemplated: false
],
currentDate:"2013-08-17"
首先抽象出一个与Link相关的类:
public class LinkModel {public stirng Href{get;set;}public stirng Rel{get;set;}public string Method{get;set;}public bool IsTemplated{get;set;} }
再放到某个视图模型中:
public class DiaryModel {//存储和模型相关的链接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用来实现视图模型和领域模型之间的转化。
public class ModelFactory {private UrlHelper _urlHelper;public ModelFactory(HttpRequestMessage request){_urlHelper = new UrlHelper(request);}//领域模型转换成视图模型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 LinkModel CreateLink(string href, string rel, string method = "GET", bool isTemplated = false){return new LinkModel(){Href = href,Rel = rel,Method = method,IsTemplated = isTemplated}}//视图模型转换成领域模型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)){//从Uri中取出主键var uri = new Uri(selfLink.Href);entity.Id = int.Parse(uri.Segments.Last());}entity.CurrentDate = model.CurrentDate;return entity;}catch(Exception ex){}} }
Diaries这个controller略,路由方面:
//api/user/diaries //api/user/diaries/2001-01-01 config.Routes.MapHttpRoute(name: "Diaries",routeTemplate: "api/user/diaries/{dairyid}",defaults: new {controller="diaries", diaryid=RouteParameter.Optional} )
这样,在客户端发出 http://localhost:8901/api/user/diaries/2013-08-17 GET请求,得到如下的响应:
links: [
href: http://localhost:8901/api/user/diaries/2013-08-17,
rel: "self",
method: "GET",
isTemplated: false
],
currentDate:"2013-08-17"
在返回分页相关的action中,也可以返回相关的Link部分。
先定义一个基类控制器:
public abstract class BaseController : ApiController {ICountingKsRepository _repo;ModelFactory _modelFactory;public BaseController(ICountingKsRepository repo){_repo = repo;//写在构造函数里的话有点迟,必须等实例化_modelFactory才有值//_modelFactory = new ModelFactory(this.Request); }protected ModelFactory TheModelFactory{get{if(_modelFactory == null){_modelFactory = new ModelFactory(this.Request, TheRepository);}return _modelFactory;}}protected ICountingsRepository TheRepoisitory{get{return _repo;}} }
可见,把共同的部分封装到基类控制器中是很好的习惯,然后基类控制器的子类通过属性获取一些方面。
再到具体的控制器:
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();}//方便统计总数var baseQuery = query.OrderBy(f =>f.Description);//using System.Web.Http.Routingvar 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"));}//把上一页和下一页的url保存下来//var prevUrl = page > 0 ? helper.Link("Food", new {page = page - 1}) : "";//var nextUrl = page > 0 ? helper.Link("Food", new {page = page + 1}) : "";//输出总数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));//方便客户端接收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));} }
客户端请求: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: [...]
}
另外,还可以控制序列化过程。
在LinkModel这个视图中:
public class LinkModel {public stirng Href{get;set;}public stirng Rel{get;set;}public string Method{get;set;}public bool IsTemplated{get;set;} }
在显示的时候,可能不想让IsTemplated显示出来,如何在序列化的过程中做到呢?
--通过jsonFormatter.SerializerSettings.Converts属性,用来控制序列化为json数据时的显示方式。
在WebApiConfig.cs中:
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNameContractResolver(); jsonFormatter.SerializerSettings.Converts(new LinkModelConverter());
而LinkModelConverter类需要继承JsonConverter类。
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();}} }
转载于:https://www.cnblogs.com/darrenji/p/5144162.html
ASP.NET Web API中展示实体Link相关的方面相关推荐
- 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...
- (四)Asp.net web api中的坑-【api的返回值】
(四)Asp.net web api中的坑-[api的返回值] 原文:(四)Asp.net web api中的坑-[api的返回值] void无返回值 IHttpActionResult HttpRe ...
- ASP.NET Web API中的参数绑定总结
ASP.NET Web API中的action参数类型可以分为简单类型和复杂类型. HttpResponseMessage Put(int id, Product item) id是int类型,是简单 ...
- 【ASP.NET Web API教程】5.5 ASP.NET Web API中的HTTP Cookie
5.5 HTTP Cookies in ASP.NET Web API 5.5 ASP.NET Web API中的HTTP Cookie 本文引自:http://www.asp.net/web-api ...
- ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...
- ASP.NET Web API中实现版本
一般来说,api 接口是提供给其他系统或是其他公司使用,不能随意频繁的变更.然而,需求和业务不断变化,接口和参数也会发生相应的变化.如果直接对原来的接口进行修改,势必会影响线其他系统的正常运行.这就必 ...
- 监控系统简介(二):使用 App Metrics 在 ASP.NET Web API 中记录指标
回顾 在<监控系统简介:使用 Prometheus 与 Grafana>一文中,我们了解了什么是监控系统,Prometheus 这一监控工具及它提供的数据类型.PromQL 以及 Graf ...
- ASP.NET Web API中实现版本的几种方式
在ASP.NET Web API中,当我们的API发生改变,就涉及到版本问题了.如何实现API的版本呢? 1.通过路由设置版本 最简单的一种方式是通过路由设置,不同的路由,不同的版本,不同的contr ...
- 在ASP.NET Web API中使用OData的Action和Function
本篇体验OData的Action和Function功能.上下文信息参考"ASP.NET Web API基于OData的增删改查,以及处理实体间关系".在本文之前,我存在的疑惑包括: ...
最新文章
- 使用Crypto++的AES GCM对称加密
- 【Error】InterfaceError (0, '')
- 如何从PostgreSQL json中提取数组
- Apache ZooKeeper - JMX监控 ZooKeeper 的运行状态
- 【密码学】CSP的概念
- 解决IDEA修改已有项目为maven项目时目录结构被改变的问题
- [GPL]GREP - basic - practice -advanced
- 给键盘上的enter设置事件_Selenium3 + Python3自动化测试系列——鼠标事件和键盘事件...
- docker kali安装mysql_Linux环境使用Docker安装MySql
- 20165230 2017-2018-2 《Java程序设计》第8周学习总结
- 【招聘】搜狗输入法-自然语言处理研究员
- 完成端口————留着看
- Vue.js 5 @慕课网
- 【算法笔记】扩展kmp算法(exkmp)
- Java 技术书籍大全
- java安卓屏幕护眼效果好_当前安卓机自带的护眼模式,比护眼大师的好嘛?
- 华为云账号登录流程和方法
- Git版本控制管理——远程版本库
- POJ1287 (最小生成树) 中文版
- python爬虫登录微博_【新手学Python爬虫】微博网页PC端抓包分析和模拟登录
热门文章
- asp.net中上传图片并生成小图片,自动添加水印的代码 .
- js实现的简单模态对话框
- fcntl函数完成 set_fl()函数还有clr_fl()函数的封装
- STM32时钟树学习笔记
- “7th-place-solution-microsoft-malware-prediction”——kaggle微软恶意代码检测比赛第七名代码
- BUUCTF-Reverse:reverse2
- 忽略某些文件 —— Git 学习笔记 05
- 【密码学】一万字带您走进密码学的世界(下)
- Truffle合约交互 - WEB端对以太坊数据的读写
- IELE:区块链的一个新虚拟机