ASP.Net Web API: исключение привязки параметров форматирования

У меня есть 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:

{"Ссылки": [ "Это не действительный 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, а затем обработайте создание экземпляра класса URI в методе действия Controller. 3. Явным образом перехватите исключение в GlobalExceptionFilter и адаптируйте ответ отсюда (это имеет код ранга). хотя пахнут...)

Предложения приветствуются!!!

2 ответа

Решение

Учитывая, что, похоже, нет ответа на проблему, обходной путь, который я собираюсь нанять, - это мой второй вариант:

Измените свойство References на список объектов String, а затем обработайте создание экземпляра класса URI в методе действия Controller.

А затем обрабатывать любые исключения, которые возникают во время создания URI самостоятельно...

Это ошибка в веб-API. В настоящее время он всегда будет терпеть неудачу, когда какое-либо открытое свойство типа throws

Это уже исправлено в наших текущих версиях: https://aspnetwebstack.codeplex.com/workitem/611 и исправление должно быть доступно в следующем выпуске.

Если вы отключите валидацию следующим образом:

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

Вы можете получить лучшее поведение с недопустимым состоянием модели.

Другие вопросы по тегам