当前位置: 代码迷 >> 综合 >> asp.net core IModelBinder
  详细解决方案

asp.net core IModelBinder

热度:15   发布时间:2024-01-31 21:57:38.0

环境:Windows 10,Visual Studio 2017,ASP.NET Core,.NET Core 2.2
————————————————————————————————————————————————————
最近在做一个项目升级,要把之前.net framework升级到.net core,有用到Action参数绑定(DefaultModelBinder)这个类去做一些东西,因为.net core里面已经没有 DefaultModelBinder 了,所以要改用 IModelBinder。

继承IModelBinder接口,在进行Action参数绑定的时候,每多一个参数,就会执行一次BindModelAsync,但是除了第一次之外就无法通过bindingContext.ActionContext.HttpContext.Request.Body获取传进来的数据,所以要把数据保存起来。(我开发的时候观察到的情况是这样的,不保证正确)

在BindModelAsync里面可以通过ModelBindingContext 获得很多东西,比如:HttpContext、Files、ContentType等。

在做完我们自己的事情后,通过bindingContext.Result = ModelBindingResult.Success(obj);返回数据。

详细的看代码。

IModelBinder接口,自定义参数绑定实现代码

using DevMate.Common;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Threading.Tasks;namespace WSM.Manage.Common
{public class CustomModelBinder : IModelBinder{private readonly object _locker = new object();private const string cachekey = "JsonModel";private int paramIndex = 0;private const string paramIndexKey = "ParamIndex";public Task BindModelAsync(ModelBindingContext bindingContext){var request = bindingContext.ActionContext.HttpContext.Request;if (request.HttpContext.Request.ContentType.ToLower() != "application/json" && request.Form.Files.Count > 0)return Task.CompletedTask;JObject data = request.HttpContext.Items[cachekey] as JObject;if (_data == null){using (var sr = new StreamReader(request.Body)){var json = sr.ReadToEnd();data = JsonConvert.DeserializeObject<JObject>(json);request.HttpContext.Items[cachekey] = data;}}string Sign = data["Sign"] == null ? null : _data["Sign"].ToString();if (string.IsNullOrEmpty(Sign))return Task.CompletedTask;paramIndex = request.HttpContext.Items[paramIndexKey] == null ? 0 : int.Parse("0" + request.HttpContext.Items[paramIndexKey]);string key = "param";lock (_locker){key = "param" + paramIndex;paramIndex++;request.HttpContext.Items[paramIndexKey] = paramIndex;}object obj = null;string jsonField = DataConvert.ToString(data[key]);if (bindingContext.ModelType == typeof(JArray)){obj = DataConvert.ToJArray(jsonField);}else if (bindingContext.ModelType.IsClass || bindingContext.ModelType.IsArray || bindingContext.ModelType.IsGenericType){obj = JsonConvert.DeserializeObject(jsonField, bindingContext.ModelType);}else{obj = data[key].ToObject(bindingContext.ModelType);}bindingContext.Result = ModelBindingResult.Success(obj);return Task.CompletedTask; }}
}

IModelBinderProvider

using Microsoft.AspNetCore.Mvc.ModelBinding;namespace WSM.Manage.Common
{public class CustomModelBinderProvider: IModelBinderProvider{public IModelBinder GetBinder(ModelBinderProviderContext context){return new CustomModelBinder();}}
}

绑定到ModelBinderProviders,放在第一个

services.AddMvc(options =>{options.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());});
  相关解决方案