【发布时间】:2017-09-26 13:08:05
【问题描述】:
我有一个场景,我有一个特定的基类,我们称之为“PagingCriteriaBase”
public class PagingCriteriaBase : CriteriaBase
{
public Int32 CountOfItemsPerPage { get; set; }
public SortOrder SortingOrder { get; set; }
public String SortBy { get; set; }
public Int32 PageNo { get; set; }
public PagingCriteriaBase(Int32 pageNo,Int32 countOfItemsPerPage, SortOrder sortingOrder, String sortBy,Int32 draw)
{
this.PageNo = pageNo>0?pageNo:1;
this.CountOfItemsPerPage = countOfItemsPerPage>0?countOfItemsPerPage:10;
this.SortBy = sortBy;
this.SortingOrder = sortingOrder;
this.Draw = draw;
}
}
然后我有其他类将从“PagingCriteriaBase”继承,例如
public class UserCriteria:PagingCriteriaBase
{
public String Email { get; set; }
public String DisplayName { get; set; }
public UserCriteria():base(1,0,SortOrder.Asc,"",1)
{
}
public UserCriteria(Int32 pageNo,Int32 countOfItemsPerPage, SortOrder sortingOrder, String sortBy, Int32 draw)
:base(pageNo, countOfItemsPerPage,sortingOrder,sortBy,draw)
{
}
}
现在我想做的是我想创建一个模型绑定器,它将与 Web API 方法一起使用,模型绑定器将与“PagingCriteriaBase”的所有子类一起使用,这个模型的目的binder 是根据来自 ajax 请求的数据设置一些属性,我尝试执行以下操作:
-
我创建了一个实现“IModelBinder”的类,如下所示:
public class PagingModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (!bindingContext.ModelType.IsSubclassOf(typeof(PagingCriteriaBase))) { return Task.FromResult(false); } String startModelName = "start"; String lengthModelName = "length"; var startResult = bindingContext.ValueProvider.GetValue(startModelName); var lengthResult = bindingContext.ValueProvider.GetValue(lengthModelName); Int32 start, length; if (!Int32.TryParse(startResult.FirstValue, out start)) { start = 0; } if (!Int32.TryParse(lengthResult.FirstValue, out length)) { length = SystemProp.PAGE_SIZE; } else { length = 20; } var model = Activator.CreateInstance(bindingContext.ModelType); Int32 pageNo = (int)Math.Ceiling((decimal)start / length); bindingContext.ModelState.SetModelValue("PageNo", new ValueProviderResult(pageNo.ToString())); bindingContext.ModelState.SetModelValue("CountOfItemsPerPage", new ValueProviderResult(length.ToString())); bindingContext.Model = model; var mProv = (IModelMetadataProvider)bindingContext.HttpContext.RequestServices.GetService(typeof(IModelMetadataProvider)); bindingContext.Result = ModelBindingResult.Success(model); return Task.CompletedTask; } } -
我创建了一个 ModelBinderProvider 如下:
public class PagingEntityBinderProvider:IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Metadata.ModelType == typeof(PagingCriteriaBase)) { return new BinderTypeModelBinder(typeof(PagingModelBinder)); } return null; } } -
我使用以下方法注册了模型绑定器:
services.AddMvc(op => op.ModelBinderProviders.Insert(0, new PagingEntityBinderProvider())) ; -
在我的 Web API 方法中,我执行了以下操作:
public IActionResult GetAll([ModelBinder(typeof(PagingModelBinder))]UserCriteria crit) { //Code goes here }
当我使用上面的模型绑定器时,我发现一旦代码到达 Web API 方法,类中的值没有任何改变,例如“PageNo”属性保持为 1,所以我需要做的是让模型绑定器为子类对象设置所有相关属性,无论类本身的类型如何,最后一旦代码到达Web API方法,模型将正确设置所有属性,你能指点我吗我需要在我的代码中更改什么来处理这个问题?
请注意,我使用的是 Asp.Net Core 2.0
【问题讨论】:
标签: c# asp.net-core model-binding asp.net-core-2.0 custom-model-binder