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