بررسی تفاوت رفتار HttpClient در داتنت 4.8 و NET Core.
نویسنده: وحید نصیری
تاریخ: ۱۴۰۵/۰۶/۱۸ ۰۸:۵۵
آدرس: www.dntips.ir
HttpClient در داتنت 4.8 و .NET Core (یا .NET 5+) ناشی از پیادهسازی کاملاً متفاوت لایه شبکه در زیرساخت آنهاست: در .NET Framework 4.8 کلاس HttpClient روی HttpWebRequest و نهایتاً WinHTTP / Schannel ویندوز سوار است، در حالی که در .NET Core روی هندلر اختصاصی و کراسپلتفرم SocketsHttpHandler اجرا میشود. این تفاوت در معماری باعث ایجاد اختلاف در بایتهای ارسالی روی شبکه میشود که اغلب منجر به خطای سمت سرور (مانند 500) میگردد:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
Expect: 100-continueExpect100Continue در لایه ServicePointManager به صورت پیشفرض true است (در درخواستهای POST و PUT).Expect: 100-continue فرستاده شود و کلاینت منتظر تأیید سرور بماند. بسیاری از سرورهای مدرن، API Gatewayها یا روترها این هدر را به درستی هندل نکرده و خطای 500 یا 417 صادر میکنند.// یا از طریق ServicePoint: ServicePointManager.FindServicePoint(uri).Expect100Continue = false; // یا مستقیماً روی HttpClient: httpClient.DefaultRequestHeaders.ExpectContinue = false;
User-Agent)User-Agent را تنظیم نکنید، ممکن است درخواستی تمیز ارسال شود، اما در داتنت 4.8 گاهی هدرهای پیشفرضی از استک ویندوز یا مقادیر خالی تزریق میشوند. برخی سرورها (مانند Cloudflare، WAFها یا کنترلرهای خاص ASP.NET) در صورت نبود User-Agent یا دریافت فرمت غیراستاندارد، کرش میکنند.httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");Content-Type (Charset)charset در داتنت 4.8 و .NET Core تفاوت دارد:StringContent با Encoding.UTF8 استفاده میکنید: application/json; charset=utf-8 ارسال میشود.PostAsJsonAsync صرفاً application/json را بدون پسوند charset ارسال میکنند. برخی از Serializerهای سختگیر سمت سرور با وجود charset=utf-8 در Content-Type در Deserialize کردن دچار Exception شده و خطای 500 برمیگردانند.var content = new StringContent(jsonString, Encoding.UTF8);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); // حذف پارامتر charsetKeep-Alive و Connection)ServicePoint مدیریت میشوند که ممکن است هدر Connection: Keep-Alive را با تنظیمات خاص ارسال کند.DefaultConnectionLimit = 2 اعمال شود که باعث صفبندی یا قطع نابهنگام کانکشن توسط سرور گردد:ServicePointManager.DefaultConnectionLimit = 50;
Expect، Content-Type یا Transfer-Encoding: chunked خواهد بود.