Web API模型绑定错误(“没有为此对象定义的无参数构造函数。”)

时间:2015-10-12 16:20:03

标签: c# asp.net asp.net-web-api

我是ASP NET Web API的新手,但在MVC方面有一些经验。 我正在尝试使用Web API 5.2.3实现IModelBinder绑定PhysicalAddress。这是它的代码:

public class PhysicalAddressModelBinder : FromStringModelBinderBase<PhysicalAddress>
{
    protected override bool BindFromString(string value, ModelBindingContext bindingContext)
    {
        try
        {
            var addressUnformatted = PhysicalAddressFormatter.ToNonFormattedPhysicalAddress(value); // returns string without delimiters
            var physicaladdress = PhysicalAddress.Parse(addressUnformatted); 
            bindingContext.Model = physicaladdress;
            return true;
        }
        catch (FormatException)
        {
            bindingContext.Model = null;
            return false;
        }
    }
}

public abstract class FromStringModelBinderBase<T> : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType != typeof(T))
            return false;

        var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (val == null)
            return false;

        var str = val.RawValue as string;

        if (str == null)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName,
                $"A string is needed to populate {bindingContext.ModelType} but a {val.GetType().Name} was provided.");
            return false;
        }

        if (BindFromString(str, bindingContext))
        {
            return true;
        }
        bindingContext
            .ModelState
            .AddModelError( bindingContext.ModelName, $"The string \"{str}\" cant be presented as {typeof(T).Name}." );

        bindingContext.Model = null;
        return false;
    }

    protected abstract bool BindFromString(string value, ModelBindingContext bindingContext);
}

我使用

在WebApiConfig中注册了活页夹
config.Services.Insert(typeof(ModelBinderProvider), 0, new SimpleModelBinderProvider(typeof(PhysicalAddress), new PhysicalAddressModelBinder()));

然后我尝试绑定模型:

public class DeviceModel 
{
    public PhysicalAddress MacAddress { get; set; }
}

public IHttpActionResult Unregister(DeviceModel model)
{
    //do stuff        
}

如果提供的MacAddress字符串有效,一切都会好起来的 - 我得到一个带有填充值的模型。

但是当地址字符串无效(PhysicalAddress.Parse(addressUnformatted)抛出FormatException)时,代码

bindingContext
.ModelState
.AddModelError( bindingContext.ModelName, $"The string \"{str}\" cant be presented as {typeof(T).Name}." );

运行良好,然后在Web API引擎中发生了一些事情,但是当我到达控制器时,ModelState不包含我的错误,但它确实包含以下错误:

ErrorMessage: ""
Exception:  {"No parameterless constructor defined for this object."}   
Exception stack trace:
System.Exception {System.MissingMethodException}
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) 
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at System.Web.Http.ModelBinding.Binders.MutableObjectModelBinder.EnsureModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
at System.Web.Http.ModelBinding.Binders.MutableObjectModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
at System.Web.Http.Controllers.HttpActionContextExtensions.Bind(HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable``1 binders)
at System.Web.Http.ModelBinding.Binders.ComplexModelDtoModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
at System.Web.Http.Controllers.HttpActionContextExtensions.Bind(HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable``1 binders)
at System.Web.Http.ModelBinding.Binders.MutableObjectModelBinder.CreateAndPopulateDto(HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable``1 propertyMetadatas) 
at System.Web.Http.ModelBinding.Binders.MutableObjectModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
at System.Web.Http.Controllers.HttpActionContextExtensions.Bind(HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable``1 binders)
at System.Web.Http.ModelBinding.Binders.CompositeModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
at System.Web.Http.ModelBinding.FormDataCollectionExtensions.ReadAsInternal(FormDataCollection formData, Type type, String modelName, HttpActionContext actionContext)
at System.Web.Http.ModelBinding.FormDataCollectionExtensions.ReadAs(FormDataCollection formData, Type type, String modelName, IRequiredMemberSelector requiredMemberSelector, IFormatterLogger formatterLogger, HttpConfiguration config)
at System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter.<ReadFromStreamAsyncCore>d__0.MoveNext()

看起来内部绑定器/格式化程序正在尝试再次绑定属性,因为PhysicalAddress中缺少无参数ctor而无法执行此操作。但为什么会这样呢?我的错误来自ModelState?

我做错了什么?我试图寻找类似的问题,但没有任何运气。任何建议都是非常有用的。

0 个答案:

没有答案