ASP.Net Web API:Formatter参数绑定异常

时间:2013-06-21 13:30:04

标签: asp.net-web-api model-binding parameterbinding

我有一个DataContract,我的Web API操作方法接受它作为操作参数。

public HttpResponseMessage PostMyObject(MyObjectRequestDc objRequest){ ... }

[DataContract]
public class MyObjectRequestDc
{
    public MyObjectRequestDc()
    {
        References = new List<Uri>();
    }
    [DataMember]
    public List<Uri> References { get; set; }
}

合同的一个属性是URI对象列表('References')。

如果客户端提交的请求包含一个不能解析为正确URI的字符串,则会在框架代码中深深抛出异常(因为它无法从给定字符串中实例化URI类):

示例Json输入:

{“References”:[“这不是有效的uri。” ]}

异常详细信息/堆栈跟踪

Error details: System.InvalidOperationException: This operation is not supported for a relative URI.
at System.Uri.get_AbsolutePath()
at GetAbsolutePathFromUri(Object )
at System.Web.Http.Metadata.Providers.AssociatedMetadataProvider`1.<>c__DisplayClass3.<GetMetadataForPropertiesImpl>b__0()
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container)
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container)
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateElements(IEnumerable model, ValidationContext validationContext)
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container)
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container)
at System.Web.Http.ModelBinding.FormatterParameterBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(Object model)
at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass49.<ToAsyncVoidTask>b__48()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)

要求是用户返回带有代码400(BadRequest)的响应,并且“引用的URI'xxx'行的消息无效”。

目前,GlobalExceptionFilter捕获了异常,并返回了无用的500.

理想情况下,我希望将此场景捕获为模型状态错误或其他一些允许我控制响应的机制。

我考虑的选项: 1.创建一个自定义的HttpParameterBinding类并在那里处理异常? 2.将References属性更改为String对象列表,然后在Controller的action方法中处理URI类的实例化 3.明确地捕获GlobalExceptionFilter中的异常并从这里定制响应(虽然这有一个排名代码的味道......)

建议最受欢迎!!!

2 个答案:

答案 0 :(得分:3)

这是Web API中的一个错误。当类型上的任何公共属性抛出时,它总是会失败。

已经修复了我们当前的位:https://aspnetwebstack.codeplex.com/workitem/611,修复程序应该可以在我们的下一个版本中找到。

如果您禁用此类验证作为解决方法:

config.Services.Clear(typeof(ModelValidatorProvider));

使用无效的模型状态可能会获得更好的行为。

答案 1 :(得分:1)

鉴于问题似乎没有答案,我将采用的工作是我的第二个选择:

  

将References属性更改为String对象列表,然后在Controller的action方法中处理URI类的实例化

然后处理在我自己实例化URI期间发生的任何异常......