لا يمكن تعيين بعض رؤوس HTTP عند استخدام النظام.صافي.WebRequest

StackOverflow https://stackoverflow.com/questions/239725

  •  04-07-2019
  •  | 
  •  

سؤال

عند محاولة إضافة HTTP رأس مفتاح/قيمة الزوج على WebRequest كائن أحصل على الاستثناء التالي:

هذا يجب أن يكون رأس تعديلها باستخدام العقار المناسب

لقد حاولت إضافة قيم جديدة إلى Headers مجموعة باستخدام إضافة (طريقة) ولكن أنا لا يزال الحصول على نفس الاستثناء.

webRequest.Headers.Add(HttpRequestHeader.Referer, "http://stackoverflow.com");

يمكنني الحصول على حول هذا عن طريق صب WebRequest كائن إلى HttpWebRequest تعيين خصائص مثل httpWebReq.Referer ="http://stackoverflow.com", ولكن هذا يعمل فقط من أجل حفنة من الرؤوس التي يتعرض لها عن طريق خصائص.

أود أن أعرف إذا كان هناك طريقة للحصول على أدق الحبيبات السيطرة على تعديل رؤوس مع طلب مورد بعيد.

هل كانت مفيدة؟

المحلول

إذا كنت في حاجة قصيرة و التقنية الجواب الحق في الذهاب إلى القسم الأخير من الإجابة.

إذا كنت تريد أن تعرف أفضل قراءة كل شيء ، وآمل أن تستمتع...


لقد ورد هذا المشكلة أيضا اليوم ما اكتشفت اليوم أن:

  1. الإجابات أعلاه صحيحا،:

    1.1 أقول لك أن رأس كنت تحاول إضافة موجودة بالفعل ثم يجب تعديل القيمة باستخدام العقار المناسب (مفهرس على سبيل المثال) بدلا من محاولة إضافته مرة أخرى.

    1.2 في أي وقت كنت في تغيير رؤوس من HttpWebRequest, تحتاج إلى استخدام الخصائص المناسبة على الكائن نفسه ، إذا كانت موجودة.

شكرا و Jvenema أبرز المبادئ التوجيهية...

  1. ولكن ما تبين لي ، الذي كان في عداد المفقودين قطعة في اللغز هو أن:

    2-1 WebHeaderCollection الفئة عموما الوصول إليها من خلال WebRequest.رؤوس أو WebResponse.رؤوس. بعض رؤوس تعتبر مقيدة إما يتعرض مباشرة من خلال واجهة برمجة التطبيقات (مثل نوع المحتوى) أو محمية من قبل النظام و لا يمكن تغييرها.

المقيدة رؤوس هي:

  • Accept
  • Connection
  • Content-Length
  • Content-Type
  • Date
  • Expect
  • Host
  • If-Modified-Since
  • Range
  • Referer
  • Transfer-Encoding
  • User-Agent
  • Proxy-Connection

لذا في المرة القادمة كنت تواجه هذا الاستثناء ولا تعرف كيفية حل هذا تذكر أن هناك بعض المقيدة رؤوس, و الحل هو تعديل قيمها باستخدام العقار المناسب صراحة من WebRequest/HttpWebRequest فئة.


تحرير:(مفيدة من التعليقات تعليق من قبل المستخدم Kaido)

الحل هو الاختيار إذا كان الرأس موجودا بالفعل أو مقيد (WebHeaderCollection.IsRestricted(key)) قبل استدعاء إضافة

نصائح أخرى

وأنا واجهت هذه المشكلة مع عميل الويب المخصصة. أعتقد أن الناس يمكن الحصول على الخلط بسبب عدة طرق للقيام بذلك. عند استخدام WebRequest.Create() يمكنك يلقي إلى HttpWebRequest واستخدام الخاصية لإضافة أو تعديل الرأس. عند استخدام WebHeaderCollection يمكنك استخدام .Add("referer","my_url").

والسابق 1

WebClient client = new WebClient();
client.Headers.Add("referer", "http://stackoverflow.com");
client.Headers.Add("user-agent", "Mozilla/5.0");

مثال 2

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Referer = "http://stackoverflow.com";
request.UserAgent = "Mozilla/5.0";
response = (HttpWebResponse)request.GetResponse();

جميع الإجابات السابقة تصف المشكلة دون تقديم حلول.هنا هو امتداد الأسلوب الذي يحل المشكلة عن طريق السماح لك لتحديد أي رأس طريق string name.

الاستخدام

HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.SetRawHeader("content-type", "application/json");

امتداد الدرجة

public static class HttpWebRequestExtensions
{
    static string[] RestrictedHeaders = new string[] {
            "Accept",
            "Connection",
            "Content-Length",
            "Content-Type",
            "Date",
            "Expect",
            "Host",
            "If-Modified-Since",
            "Keep-Alive",
            "Proxy-Connection",
            "Range",
            "Referer",
            "Transfer-Encoding",
            "User-Agent"
    };

    static Dictionary<string, PropertyInfo> HeaderProperties = new Dictionary<string, PropertyInfo>(StringComparer.OrdinalIgnoreCase);

    static HttpWebRequestExtensions()
    {
        Type type = typeof(HttpWebRequest);
        foreach (string header in RestrictedHeaders)
        {
            string propertyName = header.Replace("-", "");
            PropertyInfo headerProperty = type.GetProperty(propertyName);
            HeaderProperties[header] = headerProperty;
        }
    }

    public static void SetRawHeader(this HttpWebRequest request, string name, string value)
    {
        if (HeaderProperties.ContainsKey(name))
        {
            PropertyInfo property = HeaderProperties[name];
            if (property.PropertyType == typeof(DateTime))
                property.SetValue(request, DateTime.Parse(value), null);
            else if (property.PropertyType == typeof(bool))
                property.SetValue(request, Boolean.Parse(value), null);
            else if (property.PropertyType == typeof(long))
                property.SetValue(request, Int64.Parse(value), null);
            else
                property.SetValue(request, value, null);
        }
        else
        {
            request.Headers[name] = value;
        }
    }
}

سيناريوهات

كتبت المجمع HttpWebRequest و لا تريد فضح كل 13 المقيدة رؤوس خصائص كما في المجمع.بدلا أردت استخدام بسيط Dictionary<string, string>.

مثال آخر هو وكيل HTTP حيث تحتاج إلى أن تأخذ رؤوس في طلب وتقديمها إلى المتلقي.

هناك الكثير من السيناريوهات الأخرى حيث بدأت العملية أو من الممكن استخدام خصائص.مما اضطر المستخدم إلى مجموعة رأس عن طريق خاصية غير مرنة جدا التصميم الذي هو السبب في أن التفكير هو مطلوب.إلى الجانب المشرق هو أن التفكير المستخرجة بعيدا, انها لا تزال سريع (.001 الثاني في بلدي التجارب) ، كامتداد الأسلوب يشعر الطبيعية.

ملاحظات

رأس الأسماء حساسة لحالة الأحرف في RFC, http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2

وفي أي وقت كنت تغيير رؤوس من HttpWebRequest، تحتاج إلى استخدام الخصائص المناسبة على الكائن نفسه، إذا كانت موجودة. إذا كان لديك WebRequest سهل، ومن المؤكد أن يلقي ذلك إلى HttpWebRequest أولا. ثم Referrer في حالتك يمكن الوصول إليها عبر ((HttpWebRequest)request).Referrer، لذلك لا تحتاج إلى تعديل رأس مباشرة - مجرد تعيين الخاصية إلى القيمة الصحيحة. ContentLength، ContentType، UserAgent، الخ، وكلها تحتاج إلى تعيين بهذه الطريقة.

وIMHO، وهذا هو أحد أوجه القصور في MS جزء ... وينبغي وضع رؤوس عبر Headers.Add() الاتصال تلقائيا الخاصية المناسبة وراء الكواليس، واذا كان هذا ما يريدون القيام به.

وكان لي نفس استثناء عندما حاول قانون بلدي لتعيين "قبول" قيمة رأس مثل هذا:

WebRequest request = WebRequest.Create("http://someServer:6405/biprws/logon/long");
request.Headers.Add("Accept", "application/json");

والحل هو تغيير لهذا:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://someServer:6405/biprws/logon/long");
request.Accept = "application/json";

WebRequest يجري ملخص (ومنذ أي فئة وراثة يجب تجاوز الملكية الرؤوس) .. التي WebRequest الخرسانة الذي تستخدمه؟ وبعبارة أخرى، كيف يمكن الحصول على هذا كائن WebRequest لbeign مع؟

والسجل الصحي الإلكتروني .. mnour الجواب جعلني أدرك أن رسالة الخطأ التي كانوا يحصلون هو الحال في الواقع على: انها أقول لك أن رأس تحاول إضافة بالفعل موجودة ومن ثم يجب تعديل قيمة لها باستخدام الخاصية المناسبة (مفهرس على سبيل المثال)، بدلا من محاولة إضافته مرة أخرى. ربما كان هذا كل ما تبحث عنه.

والطبقات الأخرى وراثة من WebRequest قد يكون حتى أفضل الخصائص التفاف بعض الرؤوس. انظر> وأ href = "http://weblogs.asp.net/cazzu/archive/2007/07/30/setting-http-headers-in-net-this-header-must-be-modified-using-the- الاقتضاء، property.aspx "يختلط =" نوفولو noreferrer "> هذا المنصب على سبيل المثال.

والأجوبة المذكورة أعلاه كلها جيدة، ولكن جوهر المسألة هو أن بعض رؤوس يتم تعيين اتجاه واحد، ويتم تعيين آخرين بطرق أخرى. انظر أعلاه لقوائم "رأس مقيد. لهؤلاء، كنت مجرد مجموعة منهم كخاصية. وبالنسبة لآخرين، كنت في الواقع إضافة رأس. نرى هنا.

    request.ContentType = "application/x-www-form-urlencoded";

    request.Accept = "application/json";

    request.Headers.Add(HttpRequestHeader.Authorization, "Basic " + info.clientId + ":" + info.clientSecret);

وأساسا، لا. وهذا هو رأس HTTP، ولذلك فمن المعقول أن يلقي إلى HttpWebRequest وتعيين .Referer (كما تبين في هذا السؤال):

HttpWebRequest req = ...
req.Referer = "your url";

وأنا أستخدم فقط:

request.ContentType = "application/json; charset=utf-8"

ويمكنك يلقي مجرد WebRequest إلى HttpWebRequest أظهر أدناه:

var request = (HttpWebRequest)WebRequest.Create(myUri);

وثم بدلا من محاولة التلاعب في رأس قائمة، تطبيقه مباشرة في request.Referer طلب الملكية:

request.Referer = "yourReferer";

وهذه الخصائص المتوفرة في وجوه الطلب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top