using System.Net.Mime; using System.Text; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.Primitives; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Masuit.Tools.AspNetCore.ModelBinder; internal static class ModelBindingContextExtension { /// /// 获取绑定参数对应的 Attribute /// /// Attribute对象 /// 绑定参数上下文 /// 参数名称 /// public static T GetAttribute(this ModelBindingContext bindingContext, string parameterName = null) where T : Attribute { var fieldName = parameterName ?? bindingContext.FieldName; var ctrlActionDesc = bindingContext.ActionContext.ActionDescriptor as ControllerActionDescriptor; var fieldParameter = ctrlActionDesc!.MethodInfo.GetParameters().Single(p => p.Name == fieldName); return fieldParameter.GetCustomAttributes(typeof(T), false).Single() as T; } /// /// 判断该次请求体Body是否是Json内容类型 /// /// /// /// public static bool IsJsonContent(this HttpContext httpContext, out string charSet) { string strContentType = httpContext.Request.ContentType; if (string.IsNullOrEmpty(strContentType)) { charSet = null; return false; } var contentType = new ContentType(strContentType); charSet = contentType.CharSet; return contentType.MediaType.ToLower() == "application/json"; } /// /// 获取请求体Body字符串内容 /// /// /// /// public static string GetBodyString(this HttpContext context, Encoding encoding) { context.Request.EnableBuffering(); //Ensure the HttpRequest.Body can be read multipletimes int contentLen = 255; if (context.Request.ContentLength != null) { contentLen = (int)context.Request.ContentLength; } var body = context.Request.Body; string bodyText; if (contentLen <= 0) { bodyText = ""; } else { using var reader = new StreamReader(body, encoding, true, contentLen, true); bodyText = reader.ReadToEndAsync().Result; } body.Position = 0; return bodyText; } /// /// 尝试设置默认值 /// /// public static bool TrySetDefaultValue(this ModelBindingContext bindingContext) { var attr = bindingContext.GetAttribute(); if (attr.DefaultValue != null) { var targetValue = attr.DefaultValue.ChangeType(bindingContext.ModelType); bindingContext.Result = ModelBindingResult.Success(targetValue); return true; } return false; } /// /// 转换为对应类型 /// /// public static T ConvertObjectTo(this object @this) { return (T)ConvertObject(@this, typeof(T)); } /// /// 转换为对应类型 /// /// /// public static object ConvertObject(this object @this, Type type) { object value; if (@this is string str) { str = str.Trim(); if ((str.StartsWith("[") && str.EndsWith("]")) || str.StartsWith("{") && str.EndsWith("}")) { value = JsonConvert.DeserializeObject(str, type); } else if ((str.StartsWith("\"[") && str.EndsWith("]\"")) || str.StartsWith("\"{") && str.EndsWith("}\"")) { // json字符串 又被 json序列化 的情况 var objects = JsonConvert.DeserializeObject(str); value = JsonConvert.SerializeObject(objects).ConvertObject(type); } else { var text = JsonConvert.SerializeObject(@this); value = JsonConvert.DeserializeObject(text, type); } } else if (@this is StringValues values) { var text = values.ToString(); if (type.IsSimpleArrayType() || type.IsSimpleListType()) { text = JsonConvert.SerializeObject(values); value = JsonConvert.DeserializeObject(text, type); } else { text = JsonConvert.SerializeObject(text); value = JsonConvert.DeserializeObject(text, type); } } else if (@this is JToken) { var text = JsonConvert.SerializeObject(@this); value = JsonConvert.DeserializeObject(text, type); } else { var text = JsonConvert.SerializeObject(@this); value = JsonConvert.DeserializeObject(text, type); } return value; } }