簡體   English   中英

使用asp.net和C#從JavaScript在外部服務器上調用Web服務

[英]Call webservice on outside server from javascript using asp.net and C#

我正在嘗試使用ASP.NET頁面測試Web服務調用,該頁面創建具有用戶名和密碼字段以及“提交”按鈕的表單。 (我正在使用的jQuery和.js文件都包含在head元素的腳本標簽中。)

“提交”按鈕調用在C#代碼后面的文件中創建的函數,該函數調用一個單獨的JavaScript文件。

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

JavaScript函數Authenticate ,使用jQuery和Ajax對另一個服務器進行Web服務調用,發送JSON參數並期望返回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;
}

但是,由於我正在調用的Web服務與ASP.NET,C#和JavaScript文件位於不同的服務器上,因此沒有收到statusTextresponseText警報。

不知何故,什么也沒有發送到Web服務,我什么也沒回來,甚至沒有錯誤。 我嘗試將一個函數放在beforeSend屬性中,但是沒有觸發。 我需要處理調用服務器外Web服務的特殊方法嗎?

更新!

在jjnguy,Janie和Nathan的建議下,我現在正在嘗試使用HttpWebRequest對Web服務進行服務器端調用。 使用jjnguy的一些代碼以及該問題的代碼,我想到了這個。

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

但是,當我嘗試從HttpWebRequest獲取響應時,我從遠程服務器收到(400) Bad Request錯誤。 異常的Response屬性的值表示{System.Net.HttpWebResponse} ,而Status屬性的值是ProtocolError 我很確定這是因為URL使用的是HTTP SSL協議。 除了使ASP.NET頁面URL以HTTPS開頭(不是一種選擇)之外,我該怎么辦?

事實證明,我在更新中發布的代碼是正確的,我只是有錯字和一個錯誤的數據字符串設置。

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

為簡單起見,為什么不在服務器端用C#編寫對Web服務的調用?

與使用Javascript一樣,您具有使用C#發送請求和獲取響應的能力。

這是您在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;
}

免責聲明這未經測試。

而不是使用客戶端腳本從服務器發出請求; 使用服務器端代碼發出請求

編輯以擴展答案:

在Visual Studio中的Web項目中,單擊“添加Web參考”,然后指向您最初通過客戶端腳本訪問的服務:(我相信它是' https://myHost.com/V1/Identity/Authenticate

現在,您可以使用c#代碼而非js與服務進行對話(並傳遞用戶提供的憑據)。

同樣,由於針對服務的請求來自服務器,而不是瀏覽器; 您將繞過適用的跨域限制。

進一步編輯以顯示其他技術:

如果您不喜歡使用Visual Studio為您生成服務代理的想法,則可以使用WebClient或HttpRequest手工制作請求

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

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

好像您遇到了相同的原始政策

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

我相信有很多方法可以繞開它,但是我認為其他海報是正確的。 在服務器上,編寫使用HttpWebRequest調用Web服務的方法,然后使用JavaScriptSerializer解析出JSON。 我花了整個下午的時間研究這個原因,我必須自己寫一些類似的東西。

>>>>  Nathan

PS:我更喜歡@Janie的計划...您可以使用返回JSON以及將回傳XML的Web服務來做到這一點嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM