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));
Вы можете получить лучшее поведение с недопустимым состоянием модели.