1

我有以下配置:

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 ...

连接我的模型绑定器时有什么明显的我做错了吗?

4

0 回答 0