ส่งข้อความ HTTP POST ใน ASP.NET Core โดยใช้ HttpClient PostAsJsonAsync


151

ฉันต้องการส่งวัตถุแบบไดนามิกเช่น

new { x = 1, y = 2 };

เป็นเนื้อหาของข้อความ HTTP POST ก็เลยลองเขียนดู

var client = new HttpClient();

แต่ฉันไม่พบวิธีการ

client.PostAsJsonAsync()

ดังนั้นฉันจึงพยายามเพิ่มแพ็คเกจ Microsoft.AspNetCore.Http.Extensions ใน project.json และเพิ่มไฟล์

using Microsoft.AspNetCore.Http.Extensions; 

เพื่อใช้อนุประโยค อย่างไรก็ตามมันไม่ได้ช่วยฉัน

ดังนั้นวิธีที่ง่ายที่สุดในการส่งคำขอ POST ด้วยเนื้อความ JSON ใน ASP.NET Core คืออะไร?


สงสัยว่าทำไมบทความนี้ไม่มีตัวอย่างสำหรับ POST docs.microsoft.com/en-us/dotnet/csharp/tutorials/…
joym8

คำตอบ:


222

คุณควรเพิ่มการอ้างอิงไปยังแพ็คเกจ "Microsoft.AspNet.WebApi.Client" (อ่านบทความนี้เพื่อดูตัวอย่าง)

คุณสามารถใช้PostAsyncวิธีมาตรฐาน:

client.PostAsync(uri, new StringContent(jsonInString, Encoding.UTF8, "application/json"));

ซึ่งjsonInStringค่าที่คุณจะได้รับโดยการเรียกJsonConvert.SerializeObject(<your object>);


1
แต่ Microsoft.AspNet.WebApi.Client ไม่เหมือนไลบรารี ASP.NET Core RC2 และวิธี secon ก็คือการซ้ำรหัสมากเกินไป ((
Rem

1
@ โปรดจำไว้ว่าทำไมคุณไม่สร้างHttpClient วิธีการขยาย ( PostAsJsonAsync) เพื่อใช้วิธีที่สอง ช่วยให้คุณหลีกเลี่ยงการซ้ำรหัส
adem caglin

1
แน่นอน แต่ฉันถามคำถามเพื่อดูว่าฉันพลาดอะไรไปหรือเปล่า ไม่อยากจะเชื่อเลยว่ามันยังไม่ถูกนำไปใช้ใน Core!
Rem

1
ไลบรารีนี้ไม่ใช่ core / .net-standard ฉันไม่คิดว่า System.Net.Http.Formatting ได้รับการย้ายแล้ว
Chris S

1
สิ่งนี้จะใช้ได้กับ HttpClient ที่สร้างโดย IHttpClientFactory ใน. NET Core 2.2 จากแพคเกจ nuget Microsoft.Extensions.Http อย่างไรก็ตามคุณทำได้อย่างไร แต่เพิ่มส่วนหัวเช่นคีย์การอนุญาต
Nick Gallimore

104

ฉันใช้คลาสนี้:

public class JsonContent : StringContent
{
    public JsonContent(object obj) :
        base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json")
    { }
}

ตัวอย่างการใช้งาน:

new HttpClient().PostAsync("http://...", new JsonContent(new { x = 1, y = 2 }));

5
ทำไมไม่ขยายวิธี? JsonContent คลาสคงที่สาธารณะ {public Task <?> PostAsJSonAsync (ไคลเอนต์ HttpClient นี้ object toSerializeAsJson) {... }}
TamusJRoyce

2
ฉันชอบวิธีคลาส JsonContent
Marco Alves

สิ่งนี้ตั้งค่าContent-Length:ส่วนหัว HTTP หรือไม่
Vyacheslav Napadovsky

1
@VyacheslavNapadovsky ขึ้นอยู่กับHttpClientการตั้งค่าเช่นหากclient.DefaultRequestHeaders.TransferEncodingChunked = true Content-Lengthไม่ได้ตั้งค่าส่วนหัวชุดเดียวและTransfer-Encoding: chunkedจะตั้งค่าแทน อย่างไรก็ตามหากมีการสร้างไคลเอนต์เช่นvar client = new HttpClient();นี้ส่วนหัวContent-Lengthจะถูกตั้งค่าสำหรับคลาสเนื้อหานี้ตามค่าเริ่มต้น
stop-cran

12

ฉันจะเพิ่มคำตอบที่ยอมรับว่าคุณต้องการเพิ่มAcceptส่วนหัวในhttpClient:

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

2

ตอนนี้ Microsoft แนะนำให้ใช้IHttpClientFactoryพร้อมสิทธิประโยชน์ดังต่อไปนี้:

  • จัดเตรียมตำแหน่งกลางสำหรับการตั้งชื่อและกำหนดค่าHttpClientอินสแตนซ์โลจิคัล ตัวอย่างเช่นไคลเอ็นต์ชื่อ github สามารถลงทะเบียนและกำหนดค่าเพื่อเข้าถึง GitHub ลูกค้าเริ่มต้นสามารถลงทะเบียนสำหรับการเข้าถึงทั่วไป
  • codifies HttpClientแนวคิดของมิดเดิลแวร์ขาออกผ่านการมอบหมายไสใน จัดเตรียมส่วนขยายสำหรับมิดเดิลแวร์ที่ใช้ Polly เพื่อใช้ประโยชน์จากการมอบหมายตัวจัดการในHttpClient.
  • จัดการการรวมและอายุการใช้งานของ HttpClientMessageHandlerอินสแตนซ์ที่สำคัญ การจัดการอัตโนมัติหลีกเลี่ยงปัญหา DNS ทั่วไป (ระบบชื่อโดเมน) ที่เกิดขึ้นเมื่อจัดการHttpClientอายุการใช้งานด้วยตนเอง
  • เพิ่มประสบการณ์การบันทึกที่กำหนดค่าได้ (ผ่านILogger) สำหรับคำขอทั้งหมดที่ส่งผ่านไคลเอนต์ที่สร้างโดยโรงงาน

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1

ติดตั้ง:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient();
        // Remaining code deleted for brevity.

ตัวอย่าง POST:

public class BasicUsageModel : PageModel
{
    private readonly IHttpClientFactory _clientFactory;

    public BasicUsageModel(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }
    
    public async Task CreateItemAsync(TodoItem todoItem)
    {
        var todoItemJson = new StringContent(
            JsonSerializer.Serialize(todoItem, _jsonSerializerOptions),
            Encoding.UTF8,
            "application/json");
            
        var httpClient = _clientFactory.CreateClient();
        
        using var httpResponse =
            await httpClient.PostAsync("/api/TodoItems", todoItemJson);
    
        httpResponse.EnsureSuccessStatusCode();
    }

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1#make-post-put-and-delete-requests


1

คุณคิดถูกแล้วที่มีการใช้งาน. NET Core มานาน

ในขณะที่เขียน (กันยายน 2019) project.jsonไฟล์ของ NuGet 3.x + ถูกแทนที่ด้วยPackageReference(ตามที่อธิบายไว้ที่https://docs.microsoft.com/en-us/nuget/archive/project-json )

ในการเข้าถึง*AsyncเมธอดของHttpClientคลาส.csprojไฟล์ของคุณต้องได้รับการกำหนดค่าอย่างถูกต้อง

เปิด.csprojไฟล์ของคุณในโปรแกรมแก้ไขข้อความธรรมดาและตรวจสอบให้แน่ใจว่าบรรทัดแรกคือ
<Project Sdk="Microsoft.NET.Sdk.Web">
(ตามที่ระบุไว้ที่https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj#the -csproj- รูปแบบ ).

ในการเข้าถึง*AsyncเมธอดของHttpClientคลาสคุณต้องมีการอ้างอิงแพ็คเกจที่ถูกต้องใน.csprojไฟล์ของคุณดังนี้:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <!-- ... -->
</ItemGroup>

(โปรดดูhttps://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereferenceนอกจากนี้เราขอแนะนำแอปพลิเคชันที่กำหนดเป้าหมาย ASP.NET Core 2.1 และ ต่อมาใช้ metapackage Microsoft.AspNetCore.App , https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage )

วิธีการเช่นPostAsJsonAsync, ReadAsAsync, PutAsJsonAsyncและDeleteAsyncตอนนี้ควรจะทำงานออกมาจากกล่อง (ไม่จำเป็นต้องใช้คำสั่ง)

อัปเดต:ไม่จำเป็นต้องใช้แท็ก PackageReference ใน. NET Core 3.0 อีกต่อไป


ฉันไม่สามารถจัดการเพื่อให้ PostAsJsonAsync ทำงานกับ. NET Core 3.1 ได้ ขอบคุณ
Chris Kolenko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.