
1.什么是塑形资源
结合http://www.tnblog.net/hb/article/details/2787
对于排序可能要晚点讲解
塑形资源:相当于你去请求一个Api接口时你要请求多少个字段返回给,服务器端就输出多少字段给你
利用的是反射的原理
2.集合塑形资源与单个塑形资源
集合塑形资源EnumerableExtensions.cs
- public static class EnumerableExtensions
- {
- /// <summary>
- /// 动态反射集合资源
- /// </summary>
- /// <typeparam name="TSource"></typeparam>
- /// <param name="source"></param>
- /// <param name="fields"> 指定哪些属性或字段需要进行实例 </param>
- /// <returns></returns>
- public static IEnumerable<ExpandoObject> ToDynamicIEnumerable<TSource>(this IEnumerable<TSource> source, string fields = null)
- {
- if (source == null)
- {
- throw new ArgumentNullException(nameof(source));
- }
-
- var expandoObjectList = new List<ExpandoObject>();
- var propertyInfoList = new List<PropertyInfo>();
- if (string.IsNullOrWhiteSpace(fields))
- {
- //获取类中所有的公共的字段与实例
- var propertyInfos = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance);
- //添加到propertyInfoList集合中去
- propertyInfoList.AddRange(propertyInfos);
- }
- else
- {
- var fieldsAfterSplit = fields.Split(',').ToList();
- foreach (var field in fieldsAfterSplit)
- {
- var propertyName = field.Trim();
- if (string.IsNullOrEmpty(propertyName))
- {
- continue;
- }
- //获取属性
- var propertyInfo = typeof(TSource).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
- if (propertyInfo == null)
- {
- throw new Exception($"Property {propertyName} wasn't found on {typeof(TSource)}");
- }
- //添加到集合中
- propertyInfoList.Add(propertyInfo);
- }
- }
- //通过每一个类获取其中的属性,字段的值到List<ExpandoObject> expandoObjectList中
- foreach (TSource sourceObject in source)
- {
- var dataShapedObject = new ExpandoObject();
- foreach (var propertyInfo in propertyInfoList)
- {
- var propertyValue = propertyInfo.GetValue(sourceObject);
- ((IDictionary<string, object>)dataShapedObject).Add(propertyInfo.Name, propertyValue);
- }
- expandoObjectList.Add(dataShapedObject);
- }
-
- return expandoObjectList;
-
- }
- }
单个塑形资源ObjectExtensions.cs
- public static class ObjectExtensions
- {
- /// <summary>
- /// 动态返回单个资源
- /// </summary>
- /// <typeparam name="TSource"></typeparam>
- /// <param name="source"></param>
- /// <param name="fields"> 反射所需要的字段(用逗号分隔) </param>
- /// <returns></returns>
- public static ExpandoObject ToDynamic<TSource>(this TSource source, string fields = null)
- {
- if (source == null)
- {
- throw new ArgumentNullException(nameof(source));
- }
-
- var dataShapedObject = new ExpandoObject();
- //当为空时表示返回所有字段
- if (string.IsNullOrWhiteSpace(fields))
- {
- var propertyInfos = typeof(TSource).GetProperties(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
- foreach (var propertyInfo in propertyInfos)
- {
- var propertyValue = propertyInfo.GetValue(source);
- ((IDictionary<string, object>)dataShapedObject).Add(propertyInfo.Name, propertyValue);
- }
- return dataShapedObject;
- }
- //返回指定字段或属性
- var fieldsAfterSplit = fields.Split(',').ToList();
- foreach (var field in fieldsAfterSplit)
- {
- var propertyName = field.Trim();
- var propertyInfo = typeof(TSource).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
- if (propertyInfo == null)
- {
- throw new Exception($"Can't found property ??{typeof(TSource)}?ˉ on ??{propertyName}?ˉ");
- }
- var propertyValue = propertyInfo.GetValue(source);
- ((IDictionary<string, object>)dataShapedObject).Add(propertyInfo.Name, propertyValue);
- }
-
- return dataShapedObject;
- }
- }
3.结合我们对前文的PostController.cs的Get方法的修改
- [HttpGet(Name = "GetPosts")]
- public async Task<IActionResult> Get(PostParameters postParameters)
- {
- var posts = await _PostRepository.GetAllPosts(postParameters);
- var postResources = _mapper.Map<IEnumerable<Post>, IEnumerable<PostResource>>(posts);
-
- #region 塑形资源()
- //这里我们是通过Field字段进行查找
- var result = postResources.ToDynamicIEnumerable(postParameters.Fields);
-
- #endregion
-
- //判断上一页
- var previousPageLink = posts.HasPrevious ? CreatePostUri(postParameters, PaginationResourceUriType.PreviousPage) : null;
- //判断下一页
- var nextPageLink = posts.HasNext ? CreatePostUri(postParameters, PaginationResourceUriType.NextPage) : null;
-
-
- var metta = new {
- Pagesize = posts.PageSize,
- posts.PageIndex,
- posts.TotalItemsCount,
- posts.PageCount,
- PreviousPageLink=previousPageLink,
- NextPageLink = nextPageLink
- };
- //标准化
- Response.Headers.Add("x-Pagination", JsonConvert.SerializeObject(metta,new JsonSerializerSettings()
- {
- //Json输出格式小写
- ContractResolver = new CamelCasePropertyNamesContractResolver()
- }));
- return Ok(result);
- }
Result:
没塑形之前的
塑形之后(只要id与anthor):
4.问题
问题一:
从上面看出来一个问题,我们发现输出接口的字段首字母变大写了
解决:
Startup.cs-->ConfigureServices方法
- services.AddMvc(option =>
- {
- option.ReturnHttpNotAcceptable = true;
- option.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
- }).AddJsonOptions(options=> {
- //输出小写
- options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
- });
Result:
问题二:
如果字段不存在那么内部就会异常,所以我们需要进行验证一下
解决:
创建一个ITypeHelperService接口
- public interface ITypeHelperService
- {
- bool TypeHasProperties<T>(string fields);
- }
创建一个TypeHelperService.cs验证Failed字段并实现ITypeHelperService接口
- public class TypeHelperService : ITypeHelperService
- {
- public bool TypeHasProperties<T>(string fields)
- {
- if (string.IsNullOrWhiteSpace(fields))
- {
- return true;
- }
-
- var fieldsAfterSplit = fields.Split(',');
-
- foreach (var field in fieldsAfterSplit)
- {
- var propertyName = field.Trim();
- if (string.IsNullOrEmpty(propertyName))
- {
- continue;
- }
- var propertyInfo = typeof(T)
- .GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
- if (propertyInfo == null)
- {
- return false;
- }
- }
- return true;
- }
- }
服务注入
- #region 验证塑形字段注册
- services.AddTransient<ITypeHelperService, TypeHelperService>();
- #endregion
然后再控制器中
- [HttpGet(Name = "GetPosts")]
- public async Task<IActionResult> Get(PostParameters postParameters)
- {
- #region 排序验证
- if (!_propertyMappingContainer.ValidateMappingExistsFor<PostResource,Post>(postParameters.OrderBy))
- {
- return BadRequest(" Can't finds fields not sorting ");
- }
- #endregion
- #region 判断塑形字段是否存在
- if (!_typeHelperService.TypeHasProperties<PostResource>(postParameters.Fields))
- {
- return BadRequest("Fields not exist");
- }
- #endregion
- ...
Result:
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
评价
排名
2
文章
634
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 :
好是好,这个对效率影响大不大哇,效率高不高
一个bug让程序员走上法庭 索赔金额达400亿日元
剑轩 : 有点可怕
ASP.NET Core 服务注册生命周期
剑轩 :
http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:
50010702506256


欢迎加群交流技术