ASP.Net Web API: Formatter Parameter Binding exception

守給你的承諾、 提交于 2019-12-08 01:38:42

问题


I have a DataContract which my Web API action method accepts as an action parameter.

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

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

One of the properties of the contract is a list of URI objects ('References').

If the client ever submits a request which contains a string that does not resolve to a correct URI, an exception is thrown deep within the framework code (because it can't instantiate the URI class from the given string):

Example Json Input:

{ "References": [ "This is not a valid uri." ] }

Exception Details / Stack Trace

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)

The requirement is that the user be returned a Response with code 400 (BadRequest) and a message along the lines of "The referenced URI 'xxx' is not valid".

At the moment, the exception is caught by the GlobalExceptionFilter and a unhelpful 500 is returned.

Ideally, I'd like this scenario to be captured as a Model State error or some other mechanism which will allow me to control the response.

Options I've considered: 1. Create a custom HttpParameterBinding class and handle the exception in there? 2. Change the References property to be a list of String objects and then handle the instantiation of the URI class within the action method of the Controller 3. Catch the exception in the GlobalExceptionFilter explictly and tailor the response from here (this has a rank code smell though...)

Suggestions most welcomed!!!


回答1:


This is a bug in Web API. It currently will always fail when any public property on the type throws.

It's already been fixed in our current bits: https://aspnetwebstack.codeplex.com/workitem/611 and the fix should be available in our next release.

If you disable validation like this as a workaround:

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

you might get a better behavior with an invalid model state.




回答2:


Given that there appears to be no answer to the problem, the work around I am going to employ is my second option:

Change the References property to be a list of String objects and then handle the instantiation of the URI class within the action method of the Controller

And then handle any exceptions that occur during the instantiation of the URI myself...



来源:https://stackoverflow.com/questions/17236527/asp-net-web-api-formatter-parameter-binding-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!