2009-07-23 10 views
5

Sto provando a verificare le chiamate al servizio Web utilizzando una pagina ASP.NET che crea un modulo con i campi nome utente e password e un pulsante "Invia". (Sia jQuery che il file .js che sto utilizzando sono inclusi nei tag script nell'elemento head.)Chiamare il servizio web sul server esterno da javascript utilizzando asp.net e C#

Il pulsante "Invia" chiama una funzione creata nel codice C# dietro il file che effettua una chiamata a un JavaScript separato file.

protected void mSubmit_Click(object sender, EventArgs eventArgs) 
{ 
    String authenticate = String.Format("Authentication(\"{0}\",\"{1}\");", this.mUsername.Text,this.mPassword.Text); 
    Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScript", authenticate, true); 
} 

La funzione JavaScript, Authenticate, fa chiamata di servizio web, utilizzando jQuery e Ajax, a un altro server, l'invio di parametri JSON e in attesa di tornare in risposta JSON.

function Authentication(uname, pwd) { 

    //gets search parameters and puts them in json format 
    var params = '{"Header":{"AuthToken":null,"ProductID":"NOR","SessToken":null,"Version":1},"ReturnAuthentication":true,"Password":"' + pwd + '","Username":"' + uname + '",”ReturnCredentials”:false }'; 

    var xmlhttp = $.ajax({ 
     async: false, 
     type: "POST", 
     url: 'https://myHost.com/V1/Identity/Authenticate', 
     data: params, 
     contentType: 'application/json' 
    }); 

    alert(xmlhttp.statusText); 
    alert(xmlhttp.responseText); 

    return; 
} 

Tuttavia, poiché il servizio web che sto chiamando si trova su un server diverso da quello dei, C# e ASP.NET file JavaScript, non sto ricevendo un avviso di statusText o responseText.

In qualche modo, non viene inviato nulla al servizio Web e non ricevo nulla indietro, nemmeno un errore. Ho provato a inserire una funzione nell'attributo beforeSend, ma non è stato attivato. C'è un modo speciale che devo gestire chiamando un servizio web fuori server?

AGGIORNAMENTO!

Su consiglio di jjnguy, Janie e Nathan, ora sto provando una chiamata lato server al servizio Web utilizzando HttpWebRequest. Usando un po 'del codice di jjnguy e del codice da this question, sono arrivato a questo.

public static void Authenticate(string pwd, string uname) 
{ 
    string ret = null; 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://myhost.com/V1/Identity/Authenticate"); 
    request.ContentType = "application/json"; 
    request.Method = "POST"; 

    string data = "{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":false }'"; 

    byte[] byteData = UTF8Encoding.UTF8.GetBytes(data); 
    request.ContentLength = byteData.Length; 

    using (Stream postStream = request.GetRequestStream()) 
    { 
     postStream.Write(byteData, 0, byteData.Length); 
    } 

    HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

    using (response) 
    { 
     // Get the response stream 
     StreamReader reader = new StreamReader(response.GetResponseStream()); 

     // Console application output 
     ret = reader.ReadToEnd(); 
    } 

    Console.WriteLine(ret); 
} 

Tuttavia, sto ottenendo un errore di (400) Bad Request dal server remoto quando si tenta di ottenere la risposta dal mio HttpWebRequest. Il valore della proprietà Response dell'eccezione indica {System.Net.HttpWebResponse} e il valore della proprietà Status è ProtocolError. Sono abbastanza sicuro perché l'URL sta usando il protocollo SSL HTTP. Cosa posso fare per ovviare a questo, oltre ad avere l'URL della pagina ASP.NET iniziare con HTTPS (non un'opzione)?

+0

Questa è una soluzione in stile Rube Goldberg, è necessario semplificare notevolmente. – Janie

+0

concordato. Sono felice che siamo sulla stessa pagina. – jjnguy

+0

Riesci a vedere il servizio dal browser? – Janie

risposta

3

Risulta che il codice che ho postato nel mio aggiornamento era corretto, ho appena avuto un refuso e un'impostazione errata nella stringa di dati.

string data = "{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":true}"; 
2

Per semplicità, perché non si scrive la chiamata al servizio web in C# sul lato server?

Hai le stesse capacità di inviare richieste e ottenere risposte in C# come fai con Javascript.

Ecco una crepa a vostra funzione in C#:

public static string Authenticate(string pwd, string uname) 
{ 
    HttpWebRequest requestFile = (HttpWebRequest)WebRequest.Create("https://myHost.com/V1/Identity/Authenticate"); 
    requestFile.ContentType = "application/json"; 
    requestFile.Method = "POST"; 
    StreamWriter postBody = new StreamWriter(requestFile.GetRequestStream()) 
    using (postBody) { 
     postBody.Write("{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":false }'"); 
    } 
    HttpWebResponse serverResponse = (HttpWebResponse)requestFile.GetResponse(); 
    if (HttpStatusCode.OK != serverResponse.StatusCode) 
     throw new Exception("Url request failed. Connection to the server inturrupted"); 
    StreamReader responseStream = new StreamReader(serverResponse.GetResponseStream()); 
    string ret = null; 
    using (responseStream) { 
     ret = responseStream.ReadLine(); 
    } 
    return ret; 
} 

responsabilità Questo non è stato testato.

+0

Spero che stiate mettendo alcuni blocchi usando là. Sono giù a due voti - non rendermi _use_ uno su di te ... –

+0

ok, malato prendersi cura dei miei flussi – jjnguy

+0

p.s. Non sono molto bravo in C#. – jjnguy

1

Invece di utilizzare lo script client per effettuare la richiesta dal server; utilizzare codice lato server per effettuare la richiesta

EDIT per espandere risposta:

Dal tuo progetto web in Visual Studio, scegliere Aggiungi riferimento Web, e punto al servizio si erano originariamente accedendo tramite il proprio script client: (I credo fosse 'https://myHost.com/V1/Identity/Authenticate)

Ora puoi parlare al servizio usando il codice C# invece di js (e inoltrare le credenziali fornite dagli utenti.)

Inoltre, poiché la richiesta contro il servizio proviene da un server, piuttosto che da un browser; ignori le restrizioni interdominio che si applicano.

ULTERIORI EDIT per mostrare tecnica aggiuntiva:

Se non ti piace l'idea di utilizzare Visual Studio per generare un proxy di servizio per voi, allora si può artigianato la richiesta da soli, usando WebClient o HttpRequest

WebClient: http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.80).aspx

HttpWebRequest: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest(VS.80).aspx

+0

Non ho accesso a quel servizio nel mio progetto web. Si trova in una parte diversa del codice base rispetto a dove si trovano i miei file. –

+0

Lo capisco; VS genererà un oggetto proxy che interagirà con quel servizio per conto dell'utente. Avrai accesso a tutti i metodi su di esso ... – Janie

+0

Dai un'occhiata alla soluzione di jjnguy per le specifiche ... – Janie

0

Sembra che si sta eseguendo nella stessa o igin policy

http://en.wikipedia.org/wiki/Same_origin_policy 

Credo che ci siano modi per aggirarlo, ma penso che gli altri poster abbiano ragione. Sul server, scrivere metodi che utilizzano HttpWebRequest per chiamare il servizio Web, quindi utilizzare JavaScriptSerializer per analizzare il JSON. Ho trascorso la maggior parte del pomeriggio alla ricerca di questa causa, dovrò scrivere qualcosa di simile anch'io.

>>>> Nathan 

P.S. Mi piace il piano di @ Janie meglio ... Puoi farlo con un servizio web che restituisce JSON e uno che restituisce XML?

+0

E il piano di @jjnguy? – jjnguy

+0

Non hai aggiunto JavaScriptSerializer./jk Sono ancora curioso di poter creare classi proxy per i servizi JSON ... Non riesco a farlo funzionare sulla mia macchina qui ... – Nathan

Problemi correlati