2

我有一个 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 对象列表(“引用”)。

如果客户端提交的请求包含的字符串无法解析为正确的 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 中显式捕获异常并从这里调整响应(这有一个等级代码虽然闻起来......)

欢迎提出建议!!!

4

2 回答 2

3

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

它已经在我们当前的位中得到修复:https ://aspnetwebstack.codeplex.com/workitem/611并且修复应该在我们的下一个版本中可用。

如果您禁用这样的验证作为解决方法:

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

您可能会在无效的模型状态下获得更好的行为。

于 2013-06-21T16:01:50.707 回答
1

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

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

然后自己处理URI实例化过程中发生的任何异常......

于 2013-07-01T10:31:06.103 回答