Mẫu ASP.NET Core POST kết quả trong phản hồi Loại phương tiện không được hỗ trợ HTTP 415


173

Gửi một biểu mẫu POST HTTP yêu cầu ( Content-Type: application/x-www-form-urlencoded) đến bộ điều khiển bên dưới dẫn đến phản hồi Loại phương tiện không được hỗ trợ HTTP 415 .

public class MyController : Controller
{
    [HttpPost]
    public async Task<IActionResult> Submit([FromBody] MyModel model)
    {
        //...
    }
}

Mẫu tiêu đề HTTP:

POST /submit HTTP/1.1
Host: example.com:1337
Connection: keep-alive
Content-Length: 219
Pragma: no-cache
Cache-Control: no-cache
Origin: https://example.com:1337
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: https://example.com:1337/submit
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8,nl;q=0.6

Điều này được sử dụng để làm việc với ASP.NET MVC 5 trên .NET 4.6.


bạn không phải sử dụng [FromForm] "Gửi (mô hình MyModel)" cũng có được mô hình chính xác.
hasan

Câu trả lời:


298

Đối với các hình thức, sử dụng [FromForm]thuộc tính thay vì [FromBody]thuộc tính.

Bộ điều khiển dưới đây hoạt động với ASP.NET Core 1.1:

public class MyController : Controller
{
    [HttpPost]
    public async Task<IActionResult> Submit([FromForm] MyModel model)
    {
        //...
    }
}

Lưu ý: [FromXxx]là bắt buộc nếu bộ điều khiển của bạn được chú thích [ApiController]. Đối với bộ điều khiển xem bình thường, nó có thể được bỏ qua.


104

Bạn có thể sử dụng [FromBody]nhưng bạn cần đặt Content-Typetiêu đề cho yêu cầu của mình application/json, nghĩa là

Content-Type: application/json

1
Đó là lý do tại sao câu hỏi đề cập cụ thể đến một dạng POST, với kiểu nội dung application/x-www-form-urlencoded. Giống như từ một <form>trang HTML.
Bart Verkoeijen

Điều này hữu ích cho tôi, vì tôi đã gửi một đối tượng, không phải là một hình thức. Câu trả lời được chấp nhận là chính xác nhất cho OP, người đã sử dụng loại nội dung chính xác cho [FromForm]. Tuy nhiên, tôi rất vui vì điều này cũng ở đây. :)
Ken Lyon

1
Điều này không trả lời câu hỏi nào cả. Câu hỏi là làm thế nào để tạo các thân biểu mẫu hỗ trợ máy chủ, không phải làm thế nào để chỉ nói với tất cả khách hàng của bạn ngừng gửi chúng!
csauve

Đợi đã, điều đó có nghĩa là không thể nhập nội dung từ cơ thể của yêu cầu khác với application/json, như thế application/textnào? @BartVerkoeijen có ý kiến ​​gì không?
SpiritBob

10

Trước tiên, bạn cần chỉ định trong Tiêu đề Content-Type, ví dụ, nó có thể làapplication/json .

Nếu bạn đặt application/json loại nội dung, thì bạn cần gửi json.

Vì vậy, trong bodyyêu cầu của bạn, bạn sẽ gửi không form-data, x-www-for-urlencodednhưng không phải là mộtraw json, ví dụ{"Username": "user", "Password": "pass"}

Bạn có thể điều chỉnh ví dụ cho các loại nội dung khác nhau, bao gồm cả những gì bạn muốn gửi.

Bạn có thể sử dụng một công cụ như Postman hoặc curl để chơi với cái này.


6

Ngoài các câu trả lời hay, Bạn không phải sử dụng [FromForm]để lấy dữ liệu biểu mẫu trong bộ điều khiển. Framework tự động chuyển đổi dữ liệu biểu mẫu thành mô hình như bạn muốn. Bạn có thể thực hiện như sau.

[HttpPost]
public async Task<IActionResult> Submit(MyModel model)
{
    //...
}

3
Không phải những gì tôi thấy.
François

Tôi đã thử nghiệm nó và nó đã hoạt động, Có thể có một vấn đề khác với mã của bạn
hasan

Điều này đã giải quyết vấn đề của tôi. Tôi đã khởi động một đối tượng FormData với các trường và tệp trong đó, [FromForm] hoặc [FromBody] không hoạt động. Loại bỏ chúng và nó đã làm việc. (Mặt sau Asp.Net MVC Core 2.1, mặt trước vanilla js). Gist đây .
Daniel Szabo

Thật buồn cười, vài tháng sau bình luận trước đây của tôi - hôm nay tôi gặp vấn đề tương tự trong dự án ApNet của AspNetCore 2.2 và tôi đã phải sử dụng [FromFrom] để làm cho nó hoạt động trong bộ điều khiển WebAPI (xem câu trả lời của @ Bart).
Daniel Szabo

1
Đối với tôi, tôi đã có một [FromQuery]tham số, nhưng tôi không chỉ định Kiểu nội dung là application/json- thêm vào đó trong yêu cầu của tôi, cũng khiến nó hoạt động với tham số [FromQuery].
Mike Upjohn

5

Đây là trường hợp của tôi: nó chạy Môi trường: Bộ điều khiển AspNet Core 2.1:

public class MyController
{
    // ...

    [HttpPost]
    public ViewResult Search([FromForm]MySearchModel searchModel)
    {
        // ...
        return View("Index", viewmodel);
    }
}

Lượt xem:

<form method="post" asp-controller="MyController" asp-action="Search">
    <input name="MySearchModelProperty" id="MySearchModelProperty" />
    <input type="submit" value="Search" />
</form>

2

vấn đề có thể do MVC MW. Bạn phải đặt formatterType trong tùy chọn MVC:

services.AddMvc(options =>
            {
                options.UseCustomStringModelBinder();
                options.AllowEmptyInputInBodyModelBinding = true;
                foreach (var formatter in options.InputFormatters)
                {
                    if (formatter.GetType() == typeof(SystemTextJsonInputFormatter))
                        ((SystemTextJsonInputFormatter)formatter).SupportedMediaTypes.Add(
                            Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("text/plain"));
                }
            }).AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
            });

Trường hợp tùy chọn.UseCustomStringModelBinder () có sẵn ?? Tôi không tìm thấy tài liệu về nó ở bất cứ nơi nào.
Fabricio Araujo

0

"Phản hồi loại phương tiện không được hỗ trợ HTTP 415" xuất phát từ Loại nội dung trong tiêu đề yêu cầu của bạn. ví dụ trong javascript bởi axios:

Axios({
            method: 'post',
            headers: { 'Content-Type': 'application/json'},
            url: '/',
            data: data,  // an object u want to send
          }).then(function (response) {
            console.log(response);
          });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.