2009-04-21 17 views
11

Dopo aver sprecato due giorni con this question (e cercando di farlo funzionare), ho deciso di fare un passo indietro e fare una domanda di base, perché a quanto pare c'è qualcosa che non conosco o sto sbagliando.Pubblicazione tramite POST da C# su https

I requisiti sono semplici, Ho bisogno di fare un post HTTP (passando alcuni valori) su https da C#.

Il sito Web (se fornito i valori appropriati) restituirà alcuni semplici codici html e di risposta. (lo mostrerò più tardi).

È davvero quello semplice. Il "webservice" funziona. Ho un campione php che funziona e si connette con successo ad esso. Ho anche un'applicazione Dephi "demo" (con codice sorgente) che funziona anche. E infine ho l'applicazione demo (binaria) della compagnia che ha il "servizio", che ovviamente funziona anche.

Ma ho bisogno di farlo attraverso C#. Sembra così semplice, non funziona.

A scopo di test, ho creato una semplice app per console e un semplice metodo di connessione. Ho provato 7 modi diversi per creare una richiesta HTTP, più o meno la stessa cosa, un'implementazione diversa (utilizzando WebClient, usando HttpWebRequest, ecc.).

Ogni metodo funziona, eccetto quando l'URI inizia con "https".

Ricevo un'eccezione web che dice che il server remoto ha restituito 404. Ho installato Fiddler (come suggerito da un utente SO) e ho analizzato un po 'il traffico. Il 404 è perché sto passando qualcosa di sbagliato, perché come ho detto più tardi, il "servizio" funziona. Parlerò dei risultati del violinista più tardi.

L'URL dove devo pubblicare il dato è: https://servicios.mensario.com/enviomasivo/apip/

E questo è il dato POST: (i valori sono falsi)

usuario = QualcheUtente & clave = UnaPassword & nserie = versione = 01010000 & operacion = 220

Il server può restituire una risposta di due/tre righe (mi dispiace per lo spagnolo, ma la società è spagnola). Ecco un esempio di una possibile risposta:

HTTP/1.1 200 OK 
Content-Type: text/plain 

01010000 100 BIEN 
998 

Ed ecco un altro

HTTP/1.1 200 OK 
Content-Type: text/plain 

01010000 20 AUTENTIFICACION NEGATIVA 
Ha habido un problema en la identificación ante el servidor. Corrija sus datos de autentificacion. 

Il 1 ° uno significa OK, e il 2 ° è Auth Failure.

Come si può vedere l'attività è piuttosto facile, solo che non funziona. Se uso il violinista, vedo che c'è una sorta di roba SSL in corso nella connessione e quindi tutto funziona correttamente. Tuttavia, per quanto ho letto, .NET gestisce tutte queste cose per noi (sì, ho aggiunto il callback per convalidare sempre i certificati non validi). Non capisco cosa sto sbagliando.Posso inviare/inviare via email il codice, ma quello che mi piacerebbe sapere è molto semplice:

Come si può fare un POST su SSL usando C# e un "semplice" HttpWebRequest e più tardi avere la risposta in una stringa/array/Qualunque cosa sia l'elaborazione?

Fidati di me quando dico che sono stato googling e Stackoverflowing per due giorni. Non ho alcun tipo di proxy. La connessione passa attraverso il mio router. Porte standard Nulla di bello. La mia macchina si trova all'interno di una macchina virtuale VMWare ed è Windows Vista, ma dato che le applicazioni di esempio (php, delphi, binary) funzionano tutte senza problemi, non la vedo come un problema).

I diversi campioni (senza il binario) sono disponibili here se qualcuno vuole dare un'occhiata a loro.

Apprezzerei qualsiasi aiuto. Se qualcuno vuole provare con un nome utente "reale", ho un utente demo e potrei passarti l'utente/pass a scopo di test. Ho solo un utente demo (quello che mi hanno dato) ed è per questo che non lo sto incollando qui. Non voglio inondare l'utente con i test;)

Ho provato (all'interno degli esempi) utilizzando UTF8 e ASCII, ma ciò non ha cambiato nulla.

Sono sicuro al 100% che c'è qualcosa che devo fare con SSL e non lo sto facendo perché non lo so.

Grazie in anticipo.

Martín.

risposta

5

vedere la mia risposta alla tua altra domanda. Credo che il tuo problema potrebbe non essere il tuo codice C#. L'URL del servizio web restituisce accidentalmente un 404 con diversi altri strumenti che ho usato, ma restituisce la risposta che hai indicato se lasci la barra finale dall'URL del servizio web, quindi ti suggerisco di provarlo.

Stranamente, non sembra importare se l'URL finale è lì quando non si esegue SSL. Qualcosa di strano con quel server web, immagino.

+0

Erv, è stato così! Molte grazie. (E grazie agli altri poster per gli esempi, userò sicuramente un mix di tutti questi elementi. Sei il mio eroe, come ho affermato nell'altra domanda :) :) –

+1

Morale della storia: controlla sempre cosa " altri sviluppatori "te lo dico. (Il programmatore del server Web ha insistito sul fatto che l'URL avesse la barra e io gli credevo). : S –

8

Stavo combattendo con lo stesso identico problema un po 'prima (anche se in un framework compatto). Ecco la mia domanda e la mia risposta: Asynchronous WebRequest with POST-parameters in .NET Compact Framework

La mia versione è asincrona, quindi è un po 'più complessa di quello che stai cercando, ma l'idea rimane.

private string sendRequest(string url, string method, string postdata) { 
    WebRequest rqst = HttpWebRequest.Create(url); 

    // only needed, if you use HTTP AUTH 
    //CredentialCache creds = new CredentialCache(); 
    //creds.Add(new Uri(url), "Basic", new NetworkCredential(this.Uname, this.Pwd)); 
    //rqst.Credentials = creds; 
    rqst.Method = method; 
    if (!String.IsNullOrEmpty(postdata)) { 
     //rqst.ContentType = "application/xml"; 
     rqst.ContentType = "application/x-www-form-urlencoded"; 

     byte[] byteData = UTF8Encoding.UTF8.GetBytes(postdata); 
     rqst.ContentLength = byteData.Length; 
     using (Stream postStream = rqst.GetRequestStream()) { 
      postStream.Write(byteData, 0, byteData.Length); 
      postStream.Close(); 
     } 
    } 
    ((HttpWebRequest)rqst).KeepAlive = false; 
    StreamReader rsps = new StreamReader(rqst.GetResponse().GetResponseStream()); 
    string strRsps = rsps.ReadToEnd(); 
    return strRsps; 

} 
+0

Ciao Tommi, grazie per il campione. Sfortunatamente neanche sembra che funzioni per me. Ci sono due errori di battitura nel codice (si usa 'req' quando si crea lo StreamReader e penso che sia il migliore? E poi lo streamIn penso sia rsps (vicino alla fine). Nonostante ciò, ottengo ancora un 404 in quella linea: StreamReader rsps = new StreamReader (req.GetResponse(). GetResponseStream()); Domanda: Se non desidero utilizzare le credenziali, posso saltarlo? L'ho fatto ma non ha funzionato. Questo servizio non richiede. utente/passaggio –

+1

Accidenti, mi dispiace per gli errori di battitura. Li sistemerò nella risposta subito. Se è 404, il problema non è nel codice, stai solo inviando l'URL sbagliato. Metti alcuni punti di interruzione nel codice che invia la richiesta e verifica due volte che l'url che stai fornendo Uri-constructor sia valido. E sì, certo che puoi saltare la parte Credenziali, lo commenterò! –

+0

Oh, e inoltre, ho bisogno di cambiare il tipo di contenuto in "application/x-www-form-urlencoded" mentre invii regolari parametri POST. Nel mio caso stavo inviando XML nel campo post params e imponeva quel tipo di contenuto. –

0

non so se hai già risolto questo problema, è un post di un anno fa. Sono spagnolo e sto usando anche il mensario.

di inviare e richiedere http: (questo è in ASP, ma il processo è lo stesso)

Function enviarMsg2 
    Dim oHTTP,inicio 
    Dim strParametros 
    Dim devolver 

    Set oHTTP= server.CreateObject("Msxml2.ServerXMLHTTP") 
    strParametros = "usuario="&usuario&"&clave="&clave&"&nserie="&nserie&"&  version=01010000&operacion=300&sms=1%0934635035526%0920041231233000%09Clinica+Paz%09Clinica+Paz+le+desea+Feliz+Navidad%2E&sms=2%0934612345678%0920041231233001%09Clinica+Paz%09Clinica+Paz+le+desea+Feliz+Navidad%2E" 
'response.Write strParametros 
'response.End 
'Abrimos la conexión con el método POST, ya que estamos enviando una petición. 
oHTTP.open "POST", "https://servicios.mensario.com/enviomasivo/apip", False 

'Agregamos encabezados HTTP requeridos... 
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" 

'Enviamos la petición 
oHTTP.send strParametros 
devolver = oHTTP.responsetext 

'Comprobamos si fue correcto   
inicio = Instr(devolver, "100 BIEN") 
'response.Write "--->"&inicio 
'response.End  
if inicio <=0 then 
    enviarSMS2 = "Ha ocurrido un error en el envío del SMS." 
else 
    enviarSMS2 = Mid(devolver,inicio+9,len(devolver)) 
end if 

Set oHTTP = Nothing 

L'unica cosa che io non ho è un utente/password per una prova :)

Fondamentalmente, quando la risposta è "100 bien" la funzione ritorna, altrimenti restituisce un errore. Spero che lo aiuti :)

+0

Grazie per la risposta Jorge, abbiamo già risolto il problema. Il problema era che l'url mensario aveva un "/" alla fine, che era scorretto. –