使用asp.net和C#从javascript调用外部服务器上的webservice

我正在尝试使用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服务吗?

UPDATE!

在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错误。 exception的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#中的function:

 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/en-us/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的Web服务以及一个可以传回XML的Web服务吗?