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

发布于 2024-07-29 08:41:05 字数 3086 浏览 6 评论 0原文

我正在尝试使用 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 警报。

不知何故,没有任何内容发送到网络服务,我没有得到任何返回,甚至没有错误。 我尝试将一个函数放入 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 开头(不是一个选项)之外,我还能做些什么来解决这个问题?

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. (Both jQuery and the .js file I'm using are included in script tags in the head element.)

The "Submit" button calls a function created in the C# code behind file that makes a call to a separate JavaScript 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);
}

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.

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.

Somehow, nothing is being sent to the web service and I'm not getting anything back, not even an error. I tried putting a function in the beforeSend attribute, but that didn't fire. Is there a special way I need to handle calling an off-server web service?

UPDATE!

At the advice of jjnguy, Janie and Nathan, I'm now trying a server side call to the web service using HttpWebRequest. Using some of jjnguy's code as well as code from this question, I've come up with this.

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. The value of the Response property of the exception says {System.Net.HttpWebResponse} and the value of the Status property is ProtocolError. I'm pretty sure this is because the URL is using HTTP SSL protocol. What can I do to get around that, other than having the ASP.NET page URL start with HTTPS (not an option)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橘寄 2024-08-05 08:41:05

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

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

Turns out the code that I posted in my update was correct, I just had a typo and one setting incorrect in the data string.

    string data = "{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":true}";
迷途知返 2024-08-05 08:41:05

为了简单起见,为什么不在服务器端用 C# 编写对 Web 服务的调用呢?

在 C# 中,您具有与使用 Javascript 相同的发送请求和获取响应的能力。

以下是对 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;
}

免责声明 这尚未经过测试。

For simplicity's sake, why don't you write the call to the webservice in C# on the Server Side?

You have the same abilities to send requests and get responses in C# as you do with Javascript.

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

Disclaimer This has not been tested.

陌路终见情 2024-08-05 08:41:05

而不是使用客户端脚本向服务器发出请求; 使用服务器端代码发出请求

编辑以扩展答案:

从 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

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)

You can now talk to the service using c# code instead of js (and pass in the users provided credentials.)

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

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

梦晓ヶ微光ヅ倾城 2024-08-05 08:41:05

似乎您遇到了相同的起源政策,

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

我相信有办法规避它,但我认为其他海报是正确的。 在服务器上,编写使用 HttpWebRequest 调用 Web 服务的方法,然后使用 JavaScriptSerializer 解析 JSON。 我花了整个下午的大部分时间来研究这个问题,因为我自己也必须写一些类似的东西。

>>>>  Nathan

PS 我更喜欢 @Janie 的计划...您可以使用返回 JSON 以及传回 XML 的 Web 服务来实现这一点吗?

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. I spent most of the afternoon researching this cause I'll have to write something similar myself.

>>>>  Nathan

P.S. 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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文