tnblog
首页
视频
资源
登录

.net core 塑形资源

5930人阅读 2019/10/30 10:53 总访问:3467596 评论:1 收藏:1 手机
分类: .net后台框架


1.什么是塑形资源

结合http://www.tnblog.net/hb/article/details/2787

对于排序可能要晚点讲解

塑形资源:相当于你去请求一个Api接口时你要请求多少个字段返回给,服务器端就输出多少字段给你

利用的是反射的原理

2.集合塑形资源与单个塑形资源

集合塑形资源EnumerableExtensions.cs

  1. public static class EnumerableExtensions
  2. {
  3.     /// <summary>
  4.     /// 动态反射集合资源
  5.     /// </summary>
  6.     /// <typeparam name="TSource"></typeparam>
  7.     /// <param name="source"></param>
  8.     /// <param name="fields"> 指定哪些属性或字段需要进行实例 </param>
  9.     /// <returns></returns>
  10.     public static IEnumerable<ExpandoObject> ToDynamicIEnumerable<TSource>(this IEnumerable<TSource> source, string fields = null)
  11.     {
  12.         if (source == null)
  13.         {
  14.             throw new ArgumentNullException(nameof(source));
  15.         }
  16.         var expandoObjectList = new List<ExpandoObject>();
  17.         var propertyInfoList = new List<PropertyInfo>();
  18.         if (string.IsNullOrWhiteSpace(fields))
  19.         {
  20.             //获取类中所有的公共的字段与实例
  21.             var propertyInfos = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance);
  22.             //添加到propertyInfoList集合中去
  23.             propertyInfoList.AddRange(propertyInfos);
  24.         }
  25.         else
  26.         {
  27.             var fieldsAfterSplit = fields.Split(',').ToList();
  28.             foreach (var field in fieldsAfterSplit)
  29.             {
  30.                 var propertyName = field.Trim();
  31.                 if (string.IsNullOrEmpty(propertyName))
  32.                 {
  33.                     continue;
  34.                 }
  35.                 //获取属性
  36.                 var propertyInfo = typeof(TSource).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
  37.                 if (propertyInfo == null)
  38.                 {
  39.                     throw new Exception($"Property {propertyName} wasn't found on {typeof(TSource)}");
  40.                 }
  41.                 //添加到集合中
  42.                 propertyInfoList.Add(propertyInfo);
  43.             }
  44.         }
  45.         //通过每一个类获取其中的属性,字段的值到List<ExpandoObject> expandoObjectList中
  46.         foreach (TSource sourceObject in source)
  47.         {
  48.             var dataShapedObject = new ExpandoObject();
  49.             foreach (var propertyInfo in propertyInfoList)
  50.             {
  51.                 var propertyValue = propertyInfo.GetValue(sourceObject);
  52.                 ((IDictionary<stringobject>)dataShapedObject).Add(propertyInfo.Name, propertyValue);
  53.             }
  54.             expandoObjectList.Add(dataShapedObject);
  55.         }
  56.         return expandoObjectList;
  57.     }
  58. }

单个塑形资源ObjectExtensions.cs

  1. public static class ObjectExtensions
  2. {
  3.     /// <summary>
  4.     /// 动态返回单个资源
  5.     /// </summary>
  6.     /// <typeparam name="TSource"></typeparam>
  7.     /// <param name="source"></param>
  8.     /// <param name="fields"> 反射所需要的字段(用逗号分隔) </param>
  9.     /// <returns></returns>
  10.     public static ExpandoObject ToDynamic<TSource>(this TSource source, string fields = null)
  11.     {
  12.         if (source == null)
  13.         {
  14.             throw new ArgumentNullException(nameof(source));
  15.         }
  16.         var dataShapedObject = new ExpandoObject();
  17.         //当为空时表示返回所有字段
  18.         if (string.IsNullOrWhiteSpace(fields))
  19.         {
  20.             var propertyInfos = typeof(TSource).GetProperties(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
  21.             foreach (var propertyInfo in propertyInfos)
  22.             {
  23.                 var propertyValue = propertyInfo.GetValue(source);
  24.                 ((IDictionary<stringobject>)dataShapedObject).Add(propertyInfo.Name, propertyValue);
  25.             }
  26.             return dataShapedObject;
  27.         }
  28.         //返回指定字段或属性
  29.         var fieldsAfterSplit = fields.Split(',').ToList();
  30.         foreach (var field in fieldsAfterSplit)
  31.         {
  32.             var propertyName = field.Trim();
  33.             var propertyInfo = typeof(TSource).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
  34.             if (propertyInfo == null)
  35.             {
  36.                 throw new Exception($"Can't found property ??{typeof(TSource)}?ˉ on ??{propertyName}?ˉ");
  37.             }
  38.             var propertyValue = propertyInfo.GetValue(source);
  39.             ((IDictionary<stringobject>)dataShapedObject).Add(propertyInfo.Name, propertyValue);
  40.         }
  41.         return dataShapedObject;
  42.     }
  43. }

3.结合我们对前文的PostController.csGet方法的修改

  1.  [HttpGet(Name = "GetPosts")]
  2.  public async Task<IActionResult> Get(PostParameters postParameters)
  3.  {
  4.      var posts = await _PostRepository.GetAllPosts(postParameters);
  5.      var postResources = _mapper.Map<IEnumerable<Post>, IEnumerable<PostResource>>(posts);
  6.      #region 塑形资源()
  7.      //这里我们是通过Field字段进行查找
  8.      var result = postResources.ToDynamicIEnumerable(postParameters.Fields);
  9.      #endregion
  10.      //判断上一页
  11.      var previousPageLink = posts.HasPrevious ? CreatePostUri(postParameters, PaginationResourceUriType.PreviousPage) : null;
  12.      //判断下一页
  13.      var nextPageLink = posts.HasNext ? CreatePostUri(postParameters, PaginationResourceUriType.NextPage) : null;
  14.      var metta = new {
  15.          Pagesize = posts.PageSize,
  16.          posts.PageIndex,
  17.          posts.TotalItemsCount,
  18.          posts.PageCount,
  19.          PreviousPageLink=previousPageLink,
  20.          NextPageLink = nextPageLink
  21.      };
  22.      //标准化
  23.      Response.Headers.Add("x-Pagination", JsonConvert.SerializeObject(metta,new JsonSerializerSettings()
  24.      {
  25.          //Json输出格式小写
  26.          ContractResolver = new CamelCasePropertyNamesContractResolver()
  27.      }));
  28.      return Ok(result);
  29.  }

Result:

没塑形之前的

塑形之后(只要id与anthor):


4.问题

问题一:

从上面看出来一个问题,我们发现输出接口的字段首字母变大写了

解决:

Startup.cs-->ConfigureServices方法

  1. services.AddMvc(option =>
  2. {
  3.     option.ReturnHttpNotAcceptable = true;
  4.     option.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
  5. }).AddJsonOptions(options=> {
  6.     //输出小写
  7.     options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
  8. });

Result:

问题二:

如果字段不存在那么内部就会异常,所以我们需要进行验证一下

解决:

创建一个ITypeHelperService接口

  1. public interface ITypeHelperService
  2. {
  3.     bool TypeHasProperties<T>(string fields);
  4. }

创建一个TypeHelperService.cs验证Failed字段并实现ITypeHelperService接口

  1. public class TypeHelperService : ITypeHelperService
  2. {
  3.     public bool TypeHasProperties<T>(string fields)
  4.     {
  5.         if (string.IsNullOrWhiteSpace(fields))
  6.         {
  7.             return true;
  8.         }
  9.         var fieldsAfterSplit = fields.Split(',');
  10.         foreach (var field in fieldsAfterSplit)
  11.         {
  12.             var propertyName = field.Trim();
  13.             if (string.IsNullOrEmpty(propertyName))
  14.             {
  15.                 continue;
  16.             }
  17.             var propertyInfo = typeof(T)
  18.                 .GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
  19.             if (propertyInfo == null)
  20.             {
  21.                 return false;
  22.             }
  23.         }
  24.         return true;
  25.     }
  26. }

服务注入

  1. #region 验证塑形字段注册
  2. services.AddTransient<ITypeHelperService, TypeHelperService>();
  3. #endregion

然后再控制器中

  1. [HttpGet(Name = "GetPosts")]
  2. public async Task<IActionResult> Get(PostParameters postParameters)
  3. {
  4.         #region 排序验证
  5.         if (!_propertyMappingContainer.ValidateMappingExistsFor<PostResource,Post>(postParameters.OrderBy))
  6.         {
  7.             return BadRequest(" Can't finds fields not sorting ");
  8.         }
  9.         #endregion
  10.     #region 判断塑形字段是否存在
  11.     if (!_typeHelperService.TypeHasProperties<PostResource>(postParameters.Fields))
  12.     {
  13.         return BadRequest("Fields not exist");
  14.     }
  15.     #endregion
  16.     ...

Result:




欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

net core 使用 EF Code First

下面这些内容很老了看这篇:https://www.tnblog.net/aojiancc2/article/details/5365 项目使用多层,把数据库访问...

.net mvc分部页,.net core分部页

.net分部页的三种方式第一种:@Html.Partial(&quot;_分部页&quot;)第二种:@{ Html.RenderPartial(&quot;分部页&quot;);}...

StackExchange.Redis操作redis(net core支持)

官方git开源地址https://github.com/StackExchange/StackExchange.Redis官方文档在docs里边都是官方的文档通过nuget命令下...

.net core 使用session

tip:net core 2.2后可以直接启用session了,不用在自己添加一次session依赖,本身就添加了使用nuget添加引用Microsoft.AspN...

通俗易懂,什么是.net?什么是.net Framework?什么是.net core?

朋友圈@蓝羽 看到一篇文章写的太详细太通俗了,搬过来细细看完,保证你对.NET有个新的认识理解原文地址:https://www.cnblo...

asp.net core2.0 依赖注入 AddTransient与AddScoped的区别

asp.net core主要提供了三种依赖注入的方式其中AddTransient与AddSingleton比较好区别AddTransient瞬时模式:每次都获取一...

.net core 使用 Kestrel

Kestrel介绍 Kestrel是一个基于libuv的跨平台web服务器 在.net core项目中就可以不一定要发布在iis下面了Kestrel体验可以使...

net core中使用cookie

net core中可以使用传统的cookie也可以使用加密的cookieNET CORE中使用传统cookie设置:HttpContext.Response.Cookies.Appe...

net core项目结构简单分析

一:wwwrootwwwroot用于存放网站的静态资源,例如css,js,图片与相关的前端插件等lib主要是第三方的插件,例如微软默认引用...

net core使用EF之DB First

一.新建一个.net core的MVC项目新建好项目后,不能像以前一样直接在新建项中添加ef了,需要用命令在添加ef的依赖二.使用Nug...

.net core使用requestresponse下载文件下载excel等

使用request获取内容net core中request没有直接的索引方法,需要点里边的Query,或者formstringbase64=Request.Form[&quot;f...

iframe自适应高度与配合net core使用

去掉iframe边框frameborder=&quot;0&quot;去掉滚动条scrolling=&quot;no&quot;iframe 自适应高度如果内容是固定的,那么就...

net core启动报错Unable to configure HTTPS endpoint. No server certificate was specified

这是因为net core2.1默认使用的https,如果使用Kestrel web服务器的话没有安装证书就会报这个错其实仔细看他的错误提示,其...

net core中使用url编码与解码操作

net core中暂时还没有以前asp.net与mvc中的server对象。获取url的编码与解码操作不能使用以前的server对象来获取。使用的是...

下载net core

官方下载地址:https://dotnet.microsoft.com/download 进来之后就可以看到最新的下载版本可以直接点击下载,也可以下载其...

net core使用依赖注入来装载EF的上下文对象

妹子情人节快乐~.net core中用了不少的依赖注入,官方文档中也推荐使用。这样使用依赖注入来管理ef对象,还是比较科学,比如...
这一世以无限游戏为使命!
排名
2
文章
634
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术