MVC WebApi Routing с типом поля, указанным в маршруте - PullRequest
0 голосов
/ 14 июня 2019

У меня есть следующее определение API

[RoutePrefix("api/lead/1.0")]
public class LeadController:ApiController
{
    [Route("/{id:integer}/request-td")]
    [HttpPost]
    public IHttpActionResult SubmitLead(int id, 
        FromBody]FormData FormData)
    {

    }
}

Когда мой отдел контроля качества тестирует этот код, они звонят

/ API / свинца / 1.0 / 12345 / запрос-тд

с действительным телом и все проходит

Однако, если они меняют идентификатор с int на строку, /api/lead/1.0/invalidid/request-td

Они возвращают сообщение iis 404.

В качестве временного решения я изменил id с int на строку и удалил определение из маршрута.

Внутри контроллера выполняется TyParse, чтобы убедиться, что в URL передано действительное целое число

Однако это решение не очень элегантно для меня

Есть ли способ, чтобы я мог оставить поле id, определенное как int, с правильным типом, определенным в маршруте, перехватить недопустимый запрос API и затем отправить обратно мою собственную ошибку. т.е. другой код статуса http и тело сообщения

Если у меня есть подпись как int, но без определения переменной в маршруте,

[Route("/{id}/request-td")]
[HttpPost]
public IHttpActionResult SubmitLead(int id, 
        FromBody]FormData FormData)

Отправляет слишком много информации о том, почему запрос недействителен

То, что я видел до сих пор, это то, что вам нужно получить определения, созданные в правильном порядке в global.asax, а не как перехватывать недопустимые запросы API и возвращать мой собственный ответ

Ответы [ 2 ]

0 голосов
/ 14 июня 2019

Я бы на самом деле создал пользовательский атрибут.

public class CheckArgumentTypeAttribute : ActionFilterAttribute
{
    private readonly string ActionArgumentName;

    public CheckArgumentIsPositiveAttribute(string actionArgumentName)
    {
        if (string.IsNullOrWhiteSpace(actionArgumentName)) throw new ArgumentException(nameof(actionArgumentName));
        ActionArgumentName = actionArgumentName;
    }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var keyValuePair = actionContext.ActionArguments.FirstOrDefault(x => x.Key.Equals(ActionArgumentName, StringComparison.OrdinalIgnoreCase));
        if (keyValuePair.Equals(default(KeyValuePair<string, object>)) || !int.TryParse(keyValuePair.Value, out in result))
        {
            actionContext.Response = new HttpResponseMessage(HttpStatusCode.BadRequest)
            {
                Content = new StringContent(JsonConvert.SerializeObject(new YourClass())), Encoding.UTF8, MimeTypes.Application.Json)
            };
        }
    }
}

Затем я бы украсил свои методы действия как [CheckArgumentType("id")].Можно создать динамическое сообщение об ошибке на основе ActionArgumentName или расширить этот атрибут.

0 голосов
/ 14 июня 2019

Если вы хотите получить "string" или "int" в качестве параметра запроса, вам нужно несколько раз написать свой атрибут "Route", чтобы добавить его в карту маршрутизации.

Ниже приведено решение для получения значений.

[Route("{id:int}/request-td")]
[Route("{id:alpha}/request-td")]

Он будет принимать запросы как "string", так и "int", а не страницу 404.

Надеюсь, этот код поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...