Не могу получить POST-запрос Asp.net core 2.2 - PullRequest
0 голосов
/ 23 июня 2019

Не могу получить 3-х сторонний POST-запрос.415 Неподдерживаемый тип носителя или пустая модель

На сервере: Asp.net core 2.2 и Aspnetbilerplate (если это важно)

запрос от стороннего сервера, поэтому я не могу на него повлиять.Я могу указать только конечную точку, в которую будут отправляться запросы

Похоже: curl http://MyServer/api/MyController/MyAction -d '{"a": "a", "b": 1}'

Мой код Dto:

    public class testDto
    {
        public string A { get; set; }
        public int B { get; set; }
    }

Контроллер:

[Route("api/[controller]/[action]")]
public class MyController : MyControllerBase
{
   ...
   [HttpPost]
   public async Task<testDto> MyAction(testDto dto)
   {
     //some code
     _logger.Info("test");            
   }
   ...
}

Мой тестовый запрос с консоли с результатами:

C:\WINDOWS\system32>curl -d '{"a":"a", "b":1}' http://myServerUrl/api/MyController/MyAction
curl: (3) [globbing] unmatched close brace/bracket in column 4
{"result":{"a":null,"b":0},"targetUrl":null,"success":true,"error":null,"unAuthorizedRequest":false,"__abp":true}

Модель пуста, нетпривязка произошла.

Я добавил [FromBody] к такому действию:

   [HttpPost]
   public async Task<testDto> MyAction([FromBody]testDto dto)
   {
     //some code
     _logger.Info("test");            
   }

Результат: код состояния HTTP 415

Также попробуйте добавить [FromForm] и[FromQyesry].Результат: пустая модель

В чем проблема?Как мне заставить это работать?Заранее спасибо.

1 Ответ

1 голос
/ 24 июня 2019

Во-первых, запрос curl http://MyServer/api/MyController/MyAction -d '{"a":"a", "b":1}' неверен, вы можете увидеть использование протокола:

curl http://MyServer/api/MyController/MyAction -d '{"a":"a", "b":1}' --trace-ascii debugdump.txt

При проверке файла дампа вы обнаружите, что данные отправлены не полностью:

0000: POST /api/values/MyAction HTTP/1.1
0024: Host: localhost:44348
003b: User-Agent: curl/7.55.1
0054: Accept: */*
0061: Content-Length: 6
0074: Content-Type: application/x-www-form-urlencoded
00a5: 
=> Send data, 6 bytes (0x6)
0000: '{a:a,
== Info: upload completely sent off: 6 out of 6 bytes
== Info: schannel: client wants to read 102400 bytes
== Info: schannel: encdata_buffer resized 103424
== Info: schannel: encrypted data buffer: offset 0 length 103424
== Info: schannel: encrypted data got 322
== Info: schannel: encrypted data buffer: offset 322 length 103424

Вы должны связаться с 3ds party для подтверждения запроса.

В любом случае, если привязка модели по умолчанию не соответствует вашим требованиям, вы можете создать Связывание пользовательской модели :

  1. Добавление промежуточного программного обеспечения для запроса EnableRewind:

    app.Use(async (ctx, next) =>
    {
        ctx.Request.EnableRewind();
        await next();
    });
    
  2. Создать пользовательское связующее, которое реализует IModelBinder:

    public class testDtoEntityBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
    
    
            var body = bindingContext.HttpContext.Request.Body;
            body.Position = 0;
    
    
            string raw = new System.IO.StreamReader(body).ReadToEnd();
    
            //now read content from request content and fill your model 
            var result = new testDto
            {
                A = "",
                B = 1,
            };
    
    
            bindingContext.Result = ModelBindingResult.Success(result);
            return Task.CompletedTask;
        }
    }
    
  3. Пользователь подшивки:

    [ModelBinder(BinderType = typeof(testDtoEntityBinder))]
    public class testDto
    {
        public string A { get; set; }
        public int B { get; set; }
    }
    
...