C# 从自定义模型绑定器调用默认模型绑定器? 我已经编写了一个定制的模型绑定器,它应该根据当前的文化来映射URL字符串(get)的日期(这里的旁注:如果使用GET作为HTTP调用……默认的模型绑定器不考虑当前的文化)。
我在global.asax中注册了模型绑定器:C# 从自定义模型绑定器调用默认模型绑定器? 我已经编写了一个定制的模型绑定器,它应该根据当前的文化来映射URL字符串(get)的日期(这里的旁注:如果使用GET作为HTTP调用……默认的模型绑定器不考虑当前的文化)。,c#,asp.net-mvc-2,asp.net-mvc-3,C#,Asp.net Mvc 2,Asp.net Mvc 3,我在global.asax中注册了模型绑定器: ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeModelBinder()); 现在问题出现在最后一个返回null。如果我在POST中使用其他表单,它将用null覆盖已经映射的值。我怎样才能避免这种情况 任何输入的Thx。 sl3dg3派生并调用基本方法: public class DateTimeModelBinder : DefaultModelBinder { publ
ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeModelBinder());
现在问题出现在最后一个返回null代码>。如果我在POST中使用其他表单,它将用null覆盖已经映射的值。我怎样才能避免这种情况
任何输入的Thx。
sl3dg3派生并调用基本方法:
public class DateTimeModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// ... Your code here
return base.BindModel(controllerContext, bindingContext);
}
}
实际上,这是一个简单的解决方案:我创建一个默认活页夹的新实例,并将任务传递给他:
public class DateTimeModelBinder : IModelBinder
{
#region IModelBinder Members
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext.HttpContext.Request.HttpMethod == "GET")
{
string theDate = controllerContext.HttpContext.Request.Form[bindingContext.ModelName];
DateTime dt = new DateTime();
bool success = DateTime.TryParse(theDate, System.Globalization.CultureInfo.CurrentUICulture, System.Globalization.DateTimeStyles.None, out dt);
if (success)
{
return dt;
}
else
{
return null;
}
}
DefaultModelBinder binder = new DefaultModelBinder();
return binder.BindModel(controllerContext, bindingContext);
}
#endregion
}
另一个可能的解决方案是将一些最好的默认模型投标者传递给custom并在那里调用它
public class BaseApiRequestModelBinder : IModelBinder
{
private readonly IModelBinder _modelBinder;
public BaseApiRequestModelBinder(IModelBinder modelBinder)
{
_modelBinder = modelBinder;
}
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
//calling best default model binder
await _modelBinder.BindModelAsync(bindingContext);
var model = bindingContext.Result.Model as BaseApiRequestModel;
//do anything you want with a model that was bind with default binder
}
}
public class BaseApiRequestModelBinderProvider : IModelBinderProvider
{
private IList<IModelBinderProvider> _modelBinderProviders { get; }
public BaseApiRequestModelBinderProvider(IList<IModelBinderProvider> modelBinderProviders)
{
_modelBinderProviders = modelBinderProviders;
}
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(BaseApiRequestModel) || context.Metadata.ModelType.IsSubclassOf(typeof(BaseApiRequestModel)))
{
//Selecting best default model binder. Don't forget to exlude the current one as it is also in list
var defaultBinder = _modelBinderProviders
.Where(x => x.GetType() != this.GetType())
.Select(x => x.GetBinder(context)).FirstOrDefault(x => x != null);
if (defaultBinder != null)
{
return new BaseApiRequestModelBinder(defaultBinder);
}
}
return null;
}
//Register model binder provider in ConfigureServices in startup
services
.AddMvc(options => {
options.ModelBinderProviders.Insert(0, new BaseApiRequestModelBinderProvider(options.ModelBinderProviders));
})
公共类BaseApiRequestModelBinder:IModelBinder
{
专用只读IModelBinder\u modelBinder;
公共BaseApiRequestModelBinder(IModelBinder modelBinder)
{
_modelBinder=modelBinder;
}
公共异步任务BindModelAsync(ModelBindingContext bindingContext)
{
//调用最佳默认模型绑定器
wait_modelBinder.bindmodelsync(bindingContext);
var model=bindingContext.Result.model作为BaseApiRequestModel;
//对使用默认绑定器绑定的模型执行任何操作
}
}
公共类BaseApiRequestModelBinderProvider:IModelBinderProvider
{
私有IList_modelBinderProviders{get;}
公共BaseApiRequestModelBinderProvider(IList modelBinderProviders)
{
_modelBinderProviders=modelBinderProviders;
}
公共IModelBinder GetBinder(ModelBinderProviderContext)
{
if(上下文==null)
{
抛出新ArgumentNullException(nameof(context));
}
if(context.Metadata.ModelType==typeof(BaseApiRequestModel)| | context.Metadata.ModelType.IsSubclassOf(typeof(BaseApiRequestModel)))
{
//选择最佳默认模型活页夹。不要忘记排除当前活页夹,因为它也在列表中
var defaultBinder=\u modelBinderProviders
.Where(x=>x.GetType()!=this.GetType())
.Select(x=>x.GetBinder(context)).FirstOrDefault(x=>x!=null);
if(defaultBinder!=null)
{
返回新的BaseApiRequestModelBinder(defaultBinder);
}
}
返回null;
}
//在启动中的ConfigureServices中注册模型绑定器提供程序
服务
.AddMvc(选项=>{
Insert(0,新BaseApiRequestModelBinderProvider(options.ModelBinderProviders));
})
没有其他选项吗?出于更一般的目的,我已经从DefaultModelBinder
派生了另一个活页夹。我希望避免在其中执行所有特殊问题…@sl3dg3,从DefaultModelBinder派生有什么问题吗?此活页夹将仅用于日期时间字段,因为这是如何注册的d、 确切地说,这只是关于类型DateTime
。我想让URL字符串中的DateTime值了解当前的文化……好吧,也许我最好将它包含在我现有的binder类中,它派生自DefaultModelBinder……我想,Darin说可以有几个ModelBinder
实现erive fromDefaultModelBinder
。不必只有一个。
public class BaseApiRequestModelBinder : IModelBinder
{
private readonly IModelBinder _modelBinder;
public BaseApiRequestModelBinder(IModelBinder modelBinder)
{
_modelBinder = modelBinder;
}
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
//calling best default model binder
await _modelBinder.BindModelAsync(bindingContext);
var model = bindingContext.Result.Model as BaseApiRequestModel;
//do anything you want with a model that was bind with default binder
}
}
public class BaseApiRequestModelBinderProvider : IModelBinderProvider
{
private IList<IModelBinderProvider> _modelBinderProviders { get; }
public BaseApiRequestModelBinderProvider(IList<IModelBinderProvider> modelBinderProviders)
{
_modelBinderProviders = modelBinderProviders;
}
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(BaseApiRequestModel) || context.Metadata.ModelType.IsSubclassOf(typeof(BaseApiRequestModel)))
{
//Selecting best default model binder. Don't forget to exlude the current one as it is also in list
var defaultBinder = _modelBinderProviders
.Where(x => x.GetType() != this.GetType())
.Select(x => x.GetBinder(context)).FirstOrDefault(x => x != null);
if (defaultBinder != null)
{
return new BaseApiRequestModelBinder(defaultBinder);
}
}
return null;
}
//Register model binder provider in ConfigureServices in startup
services
.AddMvc(options => {
options.ModelBinderProviders.Insert(0, new BaseApiRequestModelBinderProvider(options.ModelBinderProviders));
})