【问题标题】:ASP.Net Web API: Formatter Parameter Binding exceptionASP.Net Web API:格式化程序参数绑定异常
【发布时间】:2013-06-18 15:51:36
【问题描述】:

我有一个 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 中的异常并从这里调整响应(虽然这有等级代码气味......)

欢迎提出建议!!!

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    如果模型状态无效,您可能会获得更好的行为。

    【讨论】:

    • 不会清除 ModelValidatorProvider 禁用所有模型验证?如果是这样,这不是一个可接受的解决方法,因为应用程序依赖于许多其他地方的模型验证。
    • “您可能会在无效模型状态下获得更好的行为”是什么意思???
    • 您也可以在模型中只使用字符串而不是 URI。这应该是一个有效的解决方法。
    【解决方案2】:

    鉴于问题似乎没有答案,我将采用的解决方法是我的第二个选择:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-21
      • 1970-01-01
      • 1970-01-01
      • 2017-02-01
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 2014-11-10
      相关资源
      最近更新 更多