ฟอร์ม ASP.NET Core POST ส่งผลให้เกิดการตอบสนอง HTTP 415 Media Type ที่ไม่รองรับ


173

การส่งคำขอ POST HTTP แบบฟอร์ม ( Content-Type: application/x-www-form-urlencoded) ไปยังตัวควบคุมด้านล่างจะส่งผลให้เป็นHTTP 415การตอบสนองของMedia Type ที่ไม่รองรับ

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

แบบฟอร์มโพสต์ส่วนหัว 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

สิ่งนี้เคยทำงานกับ ASP.NET MVC 5 บน. NET 4.6


คุณไม่จำเป็นต้องใช้ [FromForm] "ส่ง (รุ่น MyModel)" นอกจากนี้ยังรับรุ่นได้อย่างถูกต้อง
hasan

คำตอบ:


298

สำหรับฟอร์มให้ใช้แอ[FromForm]ททริบิวแทนแอ[FromBody]ททริบิวต์

ตัวควบคุมด้านล่างทำงานร่วมกับ ASP.NET Core 1.1:

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

หมายเหตุ: หากต้องการควบคุมของคุณจะถูกกำกับด้วย[FromXxx] [ApiController]สำหรับตัวควบคุมมุมมองปกติสามารถละเว้นได้


104

คุณสามารถใช้[FromBody]แต่คุณจำเป็นต้องตั้งค่าContent-Typeส่วนหัวของคำขอของคุณไปapplication/jsonคือ

Content-Type: application/json

1
นั่นเป็นเหตุผลที่คำถามเฉพาะกล่าวถึงรูปแบบapplication/x-www-form-urlencodedการโพสต์ที่มีเนื้อหาประเภท กด<form>ไลค์จากบนหน้า HTML
Bart Verkoeijen

สิ่งนี้มีประโยชน์สำหรับฉันเพราะฉันกำลังส่งวัตถุไม่ใช่แบบฟอร์ม คำตอบที่ได้รับการยอมรับนั้นถูกต้องที่สุดสำหรับ OP ซึ่งเป็นผู้ใช้ประเภทเนื้อหาที่ถูกต้องสำหรับ [FromForm] แล้ว ถึงกระนั้นฉันก็ดีใจที่อันนี้ก็อยู่ที่นี่เช่นกัน :)
Ken Lyon

1
นี่ไม่ได้ตอบคำถามเลย คำถามคือทำอย่างไรให้ร่างแบบสนับสนุนเซิร์ฟเวอร์ไม่ใช่แค่บอกลูกค้าของคุณให้หยุดส่ง!
csauve

รอหมายความว่ามันเป็นไปไม่ได้ที่จะนำเข้าไปในร่างกายเนื้อหาจากที่แตกต่างกันของร่างกายคำขอของกว่าapplication/jsonเช่นapplication/text? @BartVerkoeijen ความคิดใด ๆ
SpiritBob

10

ครั้งแรกที่คุณจะต้องระบุในส่วนหัวเช่นมันอาจเป็นContent-Typeapplication/json

หากคุณตั้งค่าapplication/jsonประเภทเนื้อหาคุณจะต้องส่ง json

ดังนั้นในbodyคำขอของคุณคุณจะไม่ส่งform-dataไม่x-www-for-urlencodedแต่rawJSON ตัวอย่างเช่น{"Username": "user", "Password": "pass"}

คุณสามารถปรับตัวอย่างให้เข้ากับประเภทเนื้อหาต่าง ๆ รวมถึงสิ่งที่คุณต้องการส่ง

คุณสามารถใช้เครื่องมือเช่นบุรุษไปรษณีย์หรือขดเพื่อเล่นกับสิ่งนี้


6

นอกเหนือจากคำตอบที่ดีคุณไม่จำเป็นต้องใช้[FromForm]เพื่อรับข้อมูลฟอร์มในตัวควบคุม Framework จะแปลงข้อมูลฟอร์มให้เป็นโมเดลโดยอัตโนมัติตามที่คุณต้องการ คุณสามารถใช้งานได้ดังต่อไปนี้

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

3
ไม่ใช่สิ่งที่ฉันเห็น
François

ฉันได้ทำการทดสอบแล้วและมันใช้งานได้อาจมีปัญหากับรหัสของคุณอีก
hasan

นี่เป็นการแก้ไขปัญหาของฉัน ฉันกำลังรวมวัตถุ FormData กับเขตข้อมูลและไฟล์ในนั้น [FromForm] หรือ [FromBody] ไม่ทำงาน ลบออกและใช้งานได้ (Asp.Net MVC Core 2.1 ด้านหลัง, ด้านหน้าของ vanilla js) สรุปสาระสำคัญที่นี่
Daniel Szabo

ตลกสองสามเดือนหลังจากความคิดเห็นก่อนหน้าของฉัน - วันนี้ฉันมีปัญหาเดียวกันในโครงการ AspNetCore 2.2 Web Api และฉันต้องใช้ [FromFrom] เพื่อให้มันทำงานในตัวควบคุม WebAPI (ดู @ คำตอบของ Bart)
Daniel Szabo

1
สำหรับฉันฉันมี[FromQuery]พารามิเตอร์ แต่ฉันไม่ได้ระบุประเภทเนื้อหาเป็นapplication/json- เพิ่มในคำขอของฉันทำให้งานนี้มีพารามิเตอร์ [FromQuery]
Mike Upjohn

5

นี่คือกรณีของฉัน: เรียกใช้สภาพแวดล้อม: ตัวควบคุม AspNet Core 2.1:

public class MyController
{
    // ...

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

ดู:

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

2

ปัญหาอาจเกิดจาก MVC MW.you คุณต้องตั้งค่า formatterType ในตัวเลือก 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;
            });

โดยที่ options.UseCustomStringModelBinder () มีให้ที่ใดบ้าง ฉันไม่พบเอกสารของมันในสถานที่ใด ๆ
Fabricio Araujo

0

"HTTP 415 การตอบสนองประเภทสื่อที่ไม่รองรับ" เกิดขึ้นจากประเภทเนื้อหาในส่วนหัวของคำขอของคุณ ตัวอย่างเช่นใน javascript โดย axios:

Axios({
            method: 'post',
            headers: { 'Content-Type': 'application/json'},
            url: '/',
            data: data,  // an object u want to send
          }).then(function (response) {
            console.log(response);
          });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.