简体   繁体   English

使用asp.net和C#从JavaScript在外部服务器上调用Web服务

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

I'm trying to test web service calls using an ASP.NET page that creates a form with username and password fields and a "Submit" button. 我正在尝试使用ASP.NET页面测试Web服务调用,该页面创建具有用户名和密码字段以及“提交”按钮的表单。 (Both jQuery and the .js file I'm using are included in script tags in the head element.) (我正在使用的jQuery和.js文件都包含在head元素的脚本标签中。)

The "Submit" button calls a function created in the C# code behind file that makes a call to a separate JavaScript file. “提交”按钮调用在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);
}

The JavaScript function, Authenticate , makes web service call, using jQuery and Ajax, to a different server, sending JSON parameters and expecting back JSON in response. 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;
}

However, because the web service I'm calling is on a different server than the ASP.NET, C# and JavaScript files, I'm not getting a statusText or responseText alert. 但是,由于我正在调用的Web服务与ASP.NET,C#和JavaScript文件位于不同的服务器上,因此没有收到statusTextresponseText警报。

Somehow, nothing is being sent to the web service and I'm not getting anything back, not even an error. 不知何故,什么也没有发送到Web服务,我什么也没回来,甚至没有错误。 I tried putting a function in the beforeSend attribute, but that didn't fire. 我尝试将一个函数放在beforeSend属性中,但是没有触发。 Is there a special way I need to handle calling an off-server web service? 我需要处理调用服务器外Web服务的特殊方法吗?

UPDATE! 更新!

At the advice of jjnguy, Janie and Nathan, I'm now trying a server side call to the web service using HttpWebRequest. 在jjnguy,Janie和Nathan的建议下,我现在正在尝试使用HttpWebRequest对Web服务进行服务器端调用。 Using some of jjnguy's code as well as code from this question , I've come up with this. 使用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);
}

However, I'm getting a (400) Bad Request error from the remote server when I try to get the response from my HttpWebRequest. 但是,当我尝试从HttpWebRequest获取响应时,我从远程服务器收到(400) Bad Request错误。 The value of the Response property of the exception says {System.Net.HttpWebResponse} and the value of the Status property is ProtocolError . 异常的Response属性的值表示{System.Net.HttpWebResponse} ,而Status属性的值是ProtocolError I'm pretty sure this is because the URL is using HTTP SSL protocol. 我很确定这是因为URL使用的是HTTP SSL协议。 What can I do to get around that, other than having the ASP.NET page URL start with HTTPS (not an option)? 除了使ASP.NET页面URL以HTTPS开头(不是一种选择)之外,我该怎么办?

事实证明,我在更新中发布的代码是正确的,我只是有错字和一个错误的数据字符串设置。

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

For simplicity's sake, why don't you write the call to the webservice in C# on the Server Side? 为简单起见,为什么不在服务器端用C#编写对Web服务的调用?

You have the same abilities to send requests and get responses in C# as you do with Javascript. 与使用Javascript一样,您具有使用C#发送请求和获取响应的能力。

Here is a crack at your function in 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;
}

Disclaimer This has not been tested. 免责声明这未经测试。

Instead of using the client script to make the request from the server; 而不是使用客户端脚本从服务器发出请求; use server side code to make the request 使用服务器端代码发出请求

EDIT to expand answer: 编辑以扩展答案:

From your web project in visual studio, click add web reference, and point to the service you were originally accessing via your client script: (I believe it was ' https://myHost.com/V1/Identity/Authenticate ) 在Visual Studio中的Web项目中,单击“添加Web参考”,然后指向您最初通过客户端脚本访问的服务:(我相信它是' https://myHost.com/V1/Identity/Authenticate

You can now talk to the service using c# code instead of js (and pass in the users provided credentials.) 现在,您可以使用c#代码而非js与服务进行对话(并传递用户提供的凭据)。

Also, since the request against the service is coming from a server, rather than a browser; 同样,由于针对服务的请求来自服务器,而不是浏览器; you bypass the cross-domain restrictions that apply. 您将绕过适用的跨域限制。

FURTHER EDIT to show additional technique: 进一步编辑以显示其他技术:

If you don't like the idea of using Visual Studio to generate a service proxy for you, then you can handcraft the request yourself using WebClient or HttpRequest 如果您不喜欢使用Visual Studio为您生成服务代理的想法,则可以使用WebClient或HttpRequest手工制作请求

WebClient: http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.80).aspx 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 HttpWebRequest: http : //msdn.microsoft.com/en-us/library/system.net.httpwebrequest( VS.80) .aspx

Seems like you're running into the same origin policy 好像您遇到了相同的原始政策

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

I believe there are ways to circumvent it, but I think the other posters are right. 我相信有很多方法可以绕开它,但是我认为其他海报是正确的。 On the server, write methods that use a HttpWebRequest to call the web service, and then use JavaScriptSerializer to parse out the JSON. 在服务器上,编写使用HttpWebRequest调用Web服务的方法,然后使用JavaScriptSerializer解析出JSON。 I spent most of the afternoon researching this cause I'll have to write something similar myself. 我花了整个下午的时间研究这个原因,我必须自己写一些类似的东西。

>>>>  Nathan

PS I like @Janie's plan better... Can you do that with a web service that returns JSON as well as one that would pass back XML? PS:我更喜欢@Janie的计划...您可以使用返回JSON以及将回传XML的Web服务来做到这一点吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM