Question

Je dois publier un message sur une URL https tierce pour que les données soient traitées et renvoyées. Et tout ce que j'ai comme exemple, c'est ceci:

$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);

Comme nous travaillons avec ASP .NET C # 2.0, je dois porter ceci, mais je reçois toujours une erreur non identifiée.

Voici ce que je fais:

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;

J'ai lu toutes les questions SO que je peux trouver à ce sujet, mais je n'obtiens aucune amélioration. Merci d'avance!

Était-ce utile?

La solution

Eh bien, vous vous trompez en supposant que la longueur en octets est identique à la longueur en caractères . Vous devez utiliser buffer.Length pour la longueur du contenu. Vous appelez également StreamWriter.Write avec un tableau d'octets . Vous ne devriez pas faire cela - vous devriez simplement utiliser le flux, comme vous l'avez déjà fait avec l'encodage:

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

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

Cela ne résoudra pas le problème de l'authentification. Vous constaterez peut-être que le simple fait de définir PreAuthenticate résout ce problème:

q.PreAuthenticate = true;

Si cela ne fonctionne pas, je vous suggère d'exécuter WireShark et d'examiner les différences entre la demande via Curl et la demande de .NET.

Autres conseils

Je pense que vous ne devriez pas fournir l'hôte dans l'authentification ...

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

Ce qui ressemblerait à quelque chose comme:

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
}

Évitez également d'attribuer le délégué délégué à la validation du point de service à chaque requête. Cela pourrait ralentir les requêtes de plus en plus, car la validation est effectuée à plusieurs reprises et constitue en quelque sorte une fuite de mémoire.

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

Voici comment vous ajoutez ce CURLOPT_USERPWD dans 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;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top