C# autofac和webapi 2 ModelBinder使用空的bindingContext.ModelName调用了两次-秒
我有以下配置:C# autofac和webapi 2 ModelBinder使用空的bindingContext.ModelName调用了两次-秒,c#,asp.net-web-api2,autofac,imodelbinder,C#,Asp.net Web Api2,Autofac,Imodelbinder,我有以下配置: builder.RegisterWebApiModelBinderProvider(); RegisterModelBinder<TypeModelBinder, object>(config, builder).InstancePerLifetimeScope(); private static IRegistrationBuilder<TBinder, ConcreteReflectionActivatorData, SingleRegistrationS
builder.RegisterWebApiModelBinderProvider();
RegisterModelBinder<TypeModelBinder, object>(config, builder).InstancePerLifetimeScope();
private static IRegistrationBuilder<TBinder, ConcreteReflectionActivatorData, SingleRegistrationStyle> RegisterModelBinder<TBinder, TTarget>(HttpConfiguration config, ContainerBuilder builder)
{
var targetType = typeof(TTarget);
var regBuilder = builder.RegisterType<TBinder>()
.WithParameter("validateAllProperties", true)
.AsModelBinderForTypes(targetType);
config.ParameterBindingRules.Add(targetType, p => p.BindWithModelBinding());
return regBuilder;
}
[Route("data/{type}")]
public IHttpActionResult Post(string type, object data)
public class TypeModelBinder : IModelBinder
{
public TypeModelBinder(ITypeResolver resolver, ITypeSerializer serializer, IContextETagExtractor eTagExtractor, bool validateAllProperties)
: base(resolver, serializer, eTagExtractor, validateAllProperties)
{
}
public override bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var typeInfo = default(RuntimeTypeInfo);
var data = default(T);
try
{
typeInfo = Resolver.Resolve(typeof(T).Name);
data = this.BindData(actionContext);
Validate(typeInfo.Type, data, bindingContext);
if (this.IsConcurrentMethod(actionContext.Request.Method) && typeInfo.IsVersioned)
{
ValidateAndSetConcurrencyToken(typeInfo.Type, data, actionContext, bindingContext);
}
}
catch (ArgumentException ae)
{
bindingContext.ModelState.AddModelError("Body", ae.Message);
}
catch (JsonSerializationException jse)
{
bindingContext.ModelState.AddModelError("Body", jse.Message);
}
catch (FormatException fe)
{
var errMsg = string.Format("{0} {1}", Constants.MODEL_ERROR_PREFIX_IF_MATCH_INVALID, fe.Message);
bindingContext.ModelState.AddModelError(Constants.MODEL_ERROR_KEY_IF_MATCH, errMsg);
}
catch (Exception e)
{
bindingContext.ModelState.AddModelError("Body", e.Message);
}
bindingContext.Model = data;
return bindingContext.ModelState.IsValid;
}
}
活页夹:
builder.RegisterWebApiModelBinderProvider();
RegisterModelBinder<TypeModelBinder, object>(config, builder).InstancePerLifetimeScope();
private static IRegistrationBuilder<TBinder, ConcreteReflectionActivatorData, SingleRegistrationStyle> RegisterModelBinder<TBinder, TTarget>(HttpConfiguration config, ContainerBuilder builder)
{
var targetType = typeof(TTarget);
var regBuilder = builder.RegisterType<TBinder>()
.WithParameter("validateAllProperties", true)
.AsModelBinderForTypes(targetType);
config.ParameterBindingRules.Add(targetType, p => p.BindWithModelBinding());
return regBuilder;
}
[Route("data/{type}")]
public IHttpActionResult Post(string type, object data)
public class TypeModelBinder : IModelBinder
{
public TypeModelBinder(ITypeResolver resolver, ITypeSerializer serializer, IContextETagExtractor eTagExtractor, bool validateAllProperties)
: base(resolver, serializer, eTagExtractor, validateAllProperties)
{
}
public override bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var typeInfo = default(RuntimeTypeInfo);
var data = default(T);
try
{
typeInfo = Resolver.Resolve(typeof(T).Name);
data = this.BindData(actionContext);
Validate(typeInfo.Type, data, bindingContext);
if (this.IsConcurrentMethod(actionContext.Request.Method) && typeInfo.IsVersioned)
{
ValidateAndSetConcurrencyToken(typeInfo.Type, data, actionContext, bindingContext);
}
}
catch (ArgumentException ae)
{
bindingContext.ModelState.AddModelError("Body", ae.Message);
}
catch (JsonSerializationException jse)
{
bindingContext.ModelState.AddModelError("Body", jse.Message);
}
catch (FormatException fe)
{
var errMsg = string.Format("{0} {1}", Constants.MODEL_ERROR_PREFIX_IF_MATCH_INVALID, fe.Message);
bindingContext.ModelState.AddModelError(Constants.MODEL_ERROR_KEY_IF_MATCH, errMsg);
}
catch (Exception e)
{
bindingContext.ModelState.AddModelError("Body", e.Message);
}
bindingContext.Model = data;
return bindingContext.ModelState.IsValid;
}
}
我编写了一个测试来检查当我放弃一个无效对象时,TypeModelBinder
中的模型绑定是否失败
然而,我注意到以下行为。第一次通过它时,它的行为与我预期的一样,bindingContext.ModelName
被设置为“data”
然而,我注意到,当绑定失败时,它会立即重新进入绑定器的BindModel方法,这次将bindingContext.ModelName
设置为”
,然后它会添加任何已添加模型错误的另一个副本,owin堆栈中的某些内容会抛出500
在连接我的模型绑定器时,是否有任何明显的错误