J'essaie de porter du code C# sur F #.System.Net.WebException lors du portage de C# à F #
Le code C# a été prise d'ici (et légèrement dénudés): https://github.com/joelpob/betfairng/blob/master/BetfairClient.cs
public bool Login(string p12CertificateLocation, string p12CertificatePassword, string username, string password)
{
var appKey = "APPKEY";
string postData = string.Format("username={0}&password={1}", username, password);
X509Certificate2 x509certificate = new X509Certificate2(p12CertificateLocation, p12CertificatePassword);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://identitysso.betfair.com/api/certlogin");
request.UseDefaultCredentials = true;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("X-Application", appKey);
request.ClientCertificates.Add(x509certificate);
request.Accept = "*/*";
using (Stream stream = request.GetRequestStream())
using (StreamWriter writer = new StreamWriter(stream, Encoding.Default))
writer.Write(postData);
using (Stream stream = ((HttpWebResponse)request.GetResponse()).GetResponseStream())
using (StreamReader reader = new StreamReader(stream, Encoding.Default))
Le code C# ci-dessus fonctionne très bien. Cependant, lorsque j'essaie d'exécuter (ce que je pense être) un code équivalent à F #, sans réel changement, je reçois un message d'erreur.
Le code est exécuté à partir du même ordinateur, de la même installation VS et avec exactement les mêmes 4 arguments.
Le message d'erreur que je reçois est le deuxième avant-dernière ligne:
member x.Login(username, password,p12CertificateLocation:string, p12CertificatePassword:string) =
let AppKey = "APPKEY"
let url = "https://identitysso.betfair.com/api/certlogin"
let postData = "username=" + username + "&password=" + password
let x509certificate = new X509Certificate2(p12CertificateLocation, p12CertificatePassword)
let req = HttpWebRequest.Create(url) :?> HttpWebRequest
req.ClientCertificates.Add(x509certificate)|>ignore
req.UseDefaultCredentials <- true
req.Method <- "POST"
req.ContentType <- "application/x-www-form-urlencoded"
req.Headers.Add("X-Application",AppKey)
req.Accept <-"*/*"
use stream = req.GetRequestStream()
use writer =new StreamWriter(stream,Encoding.Default)
writer.Write(postData)
// fails on this line:
use stream = (req.GetResponse() :?> HttpWebResponse).GetResponseStream()
// with System.Net.WebException: 'The remote server returned an error: (400) Bad Request.'
use reader = new StreamReader(stream,Encoding.Default)
Je suis un peu perdu, à mon esprit les deux implémentations de code doivent être identiques?
Vous pourriez avoir des raisons très spécifiques au port le code C# directement, mais il y a aussi des clients plus idimatic qui enveloppent HttpWebRequest, par exemple [Http.fs] (https://github.com/haf/Http. fs) ou [Http Utilities] (http://fsharp.github.io/FSharp.Data/library/Http.html) dans FSharp.Data. – s952163
La méthode C# consiste à utiliser HttpClient, pas HttpWebRequest directement.Les gens n'enchaînent pas les appels à GetResponse, GetRresponseStream non plus - quel est le * point * de lecture d'une réponse s'il n'y en a pas, par exemple si le code d'état est une erreur? –
Enfin, n'utilisez pas un encodage * random * comme vous le faites ici - Encoding.Default est la page de code ANSI du système. Presque tous les services Web utilisent UTF8, à l'exception de certains qui peuvent utiliser UTF16. Aucun n'utilise les pages de code ANSI. Dans tous les cas, le codage doit être spécifié dans les en-têtes appropriés –