سؤال

ولقد جعل وظيفة لطرف ثالث الشبكي رابط للحصول على البيانات procesed وإعادته. وكل ما لدي كمثال هو هذا:

$signature= foo_string;
$data_to_post = json_dictionary;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $base_url);
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_HTTPHEADER,array("JSON-Signature: $signature"));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_to_post);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);

ونحن نعمل مع ASP .NET C # 2.0، لا بد لي من ميناء ذلك، ولكن أنا دائما الحصول على خطأ لا autenticated.

وهنا هو ما أفعله:

HttpWebRequest q = (HttpWebRequest)WebRequest.Create(Host + ":" + Port);
                ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(new interhanse().AcceptAllCertifications);                

                q.Method = "POST";
                q.Headers.Add("JSON-Signature:" + GetSignature(data));
                q.ContentType = "application/json";

                q.UseDefaultCredentials = false;
                q.Credentials = new NetworkCredential(user,pwd, Host);

                byte[] buffer = UTF8Encoding.UTF8.GetBytes(data);

                q.ContentLength = data.Length;                

                Stream oStream = q.GetRequestStream();
                StreamWriter oWriter = new StreamWriter(oStream);
                oWriter.Write(buffer);
                oWriter.Close();


                HttpWebResponse reps = q.GetResponse() as HttpWebResponse;

ولقد قرأت جميع الأسئلة SO I يمكن العثور على هذا، ولكن أنا لا أحصل على أي تحسينات. ويرجع الفضل في ذلك مسبقا!

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

المحلول

حسنا، شيء واحد تفعلونه خطأ وعلى افتراض أن طول في بايت هو نفس طول في الأحرف . يجب عليك استخدام buffer.Length لطول المحتوى. كنت تتصل أيضا StreamWriter.Write مع صفيف بايت . يجب أن لا تفعل ذلك - يجب عليك فقط استخدام تيار، كما كنت قد فعلت الترميز:

byte[] buffer = Encoding.UTF8.GetBytes(data);

q.ContentLength = buffer.Length;
using (Stream stream = q.GetRequestStream())
{
    stream.Write(buffer, 0, buffer.Length);
}

والآن، وهذا لن يحل قضية المصادقة. قد تجد أن PreAuthenticate مجرد وضع يحل هذه على الرغم من:

q.PreAuthenticate = true;

إذا لم يفلح ذلك، أقترح عليك تشغيل يريشارك وإلقاء نظرة على الاختلافات بين الطلب عن طريق الضفيرة و طلب من .NET.

نصائح أخرى

وأعتقد أنك يجب أن يتم توفير المضيف في المصادقة ...

q.Credentials = new NetworkCredential(user,pwd);

والتي من شأنها أن يكون شيئا مثل:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Host + ":" + Port);
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(new interhanse().AcceptAllCertifications);

request.Method = "POST";
request.Headers.Add("JSON-Signature:" + GetSignature(data));
request.ContentType = "application/json";

request.UseDefaultCredentials = false;
request.Credentials = new NetworkCredential(user, pwd);

byte[] buffer = UTF8Encoding.UTF8.GetBytes(data);

request.ContentLength = buffer.Length;
using (Stream oStream = request.GetRequestStream()) {
    oStream.Write(buffer, 0, buffer.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
    // load data from response here
}

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

curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");

وهنا هو كيف أضيف أن CURLOPT_USERPWD في Asp.Net:

    private async Task<string> Execute(string url, string query, string user, string pasword)
    {
        HttpClient httpClient = new HttpClient();
        var baseUri = new Uri(url, UriKind.Absolute);  // e.g. http://somedomain.com/endpoint
        Uri request = new Uri(baseUri, query);    // with query e.g. http://somedomain.com/endpoint?arg1=xyz&arg2=abc

        // Add a new Request Message
        HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, request);

        // add headers -> CURLOPT_USERPWD equivalent
        var encodedStr = Convert.ToBase64String(Encoding.Default.GetBytes(string.Format("{0}:{1}", user, password)));
        var authorizationKey = "Basic" + " " + encodedStr;    // Note: Basic case sensitive
        requestMessage.Headers.Add("Authorization", authorizationKey);

        // if POST - do this instead
        // content
        //HttpContent content = new StringContent(jsonContent);     // string jsonContent i.e. JsonConvert.SerializeObject(YourObject);
        //requestMessage.Content = content;
        //requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

        // execute
        HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
        var responseString = await responseMessage.Content.ReadAsStringAsync();    // reads it as string; 

        // if json and you need to convert to an object do this
        // var myresponse = JsonConvert.DeserializeObject<YourMappedObject>(responseString);

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