2009-07-23 39 views
5

Tôi đang cố gắng kiểm tra các cuộc gọi dịch vụ web bằng trang ASP.NET tạo biểu mẫu có tên người dùng và mật khẩu và nút "Gửi". (Cả jQuery và tệp .js tôi đang sử dụng được bao gồm trong các thẻ tập lệnh trong phần tử đầu.)Gọi dịch vụ web trên máy chủ bên ngoài từ javascript bằng asp.net và C#

Nút "Gửi" gọi hàm được tạo trong mã C# phía sau tệp thực hiện cuộc gọi đến một JavaScript riêng biệt tập tin.

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

Các hàm JavaScript, Authenticate, làm cho cuộc gọi dịch vụ web, sử dụng jQuery và Ajax, đến một máy chủ khác nhau, gửi thông số JSON và mong trở lại JSON trong phản ứng.

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

Tuy nhiên, do các dịch vụ web tôi gọi là trên một máy chủ khác với ASP.NET, C# và các tập tin JavaScript, tôi không nhận được một statusText hoặc responseText cảnh báo.

Bằng cách nào đó, không có gì được gửi tới dịch vụ web và tôi không nhận được bất kỳ điều gì trở lại, thậm chí không phải là lỗi. Tôi đã thử đặt một hàm trong thuộc tính beforeSend, nhưng điều đó không kích hoạt. Có cách nào đặc biệt mà tôi cần để xử lý việc gọi một dịch vụ web ngoài máy chủ không?

CẬP NHẬT!

Theo lời khuyên của jjnguy, Janie và Nathan, tôi hiện đang thử một cuộc gọi phía máy chủ với dịch vụ web bằng HttpWebRequest. Sử dụng một số mã của jjnguy cũng như mã số từ this question, tôi đã nghĩ ra điều này.

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

Tuy nhiên, tôi nhận được lỗi (400) Bad Request từ máy chủ từ xa khi tôi cố nhận phản hồi từ HttpWebRequest của mình. Giá trị của thuộc tính Response của ngoại lệ cho biết {System.Net.HttpWebResponse} và giá trị của thuộc tính Trạng thái là ProtocolError. Tôi khá chắc chắn điều này là do URL đang sử dụng giao thức HTTP SSL. Những gì tôi có thể làm để có được xung quanh đó, khác hơn là có URL trang ASP.NET bắt đầu với HTTPS (không phải là một lựa chọn)?

+0

Đây là giải pháp phong cách Rube Goldberg, bạn sẽ cần phải đơn giản hóa rất nhiều. – Janie

+0

Đồng ý. Tôi rất vui vì chúng tôi đang ở trên cùng một trang. – jjnguy

+0

Bạn có thể xem dịch vụ từ trình duyệt không? – Janie

Trả lời

3

Tắt mã mà tôi đăng trong bản cập nhật của mình là chính xác, tôi vừa có lỗi chính tả và một cài đặt không chính xác trong chuỗi dữ liệu.

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

Vì mục đích đơn giản, tại sao bạn không viết cuộc gọi tới dịch vụ web trong C# ở phía máy chủ?

Bạn có cùng khả năng gửi yêu cầu và nhận phản hồi trong C# khi bạn làm với Javascript.

Dưới đây là một vết nứt ở chức năng của bạn trong 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 này chưa được thử nghiệm.

+0

Tôi hy vọng bạn sẽ đặt một số khối bằng cách sử dụng trong đó. Tôi đang xuống đến hai phiếu bầu - đừng làm cho tôi _use_ một người về bạn ... –

+0

ok, chăm sóc bệnh của các dòng của tôi – jjnguy

+0

p.s. Tôi không giỏi C#. – jjnguy

1

Thay vì sử dụng tập lệnh ứng dụng khách để thực hiện yêu cầu từ máy chủ; sử dụng mã phía máy chủ để thực hiện yêu cầu

EDIT để mở rộng câu trả lời:

Từ dự án web của bạn trong visual studio, nhấp thêm tài liệu tham khảo web, và trỏ đến dịch vụ mà bạn ban đầu được truy cập thông qua kịch bản khách hàng của bạn: (I tin rằng đó là 'https://myHost.com/V1/Identity/Authenticate)

Bây giờ bạn có thể nói chuyện với dịch vụ bằng cách sử dụng mã C# thay vì js (và chuyển vào thông tin xác thực do người dùng cung cấp.)

Ngoài ra, do yêu cầu đối với dịch vụ đến từ máy chủ chứ không phải trình duyệt; bạn bỏ qua các hạn chế tên miền chéo áp dụng.

EDIT THÊM để hiển thị thêm kỹ thuật:

Nếu bạn không thích ý tưởng sử dụng Visual Studio để tạo ra một dịch vụ proxy cho bạn, sau đó bạn có thể thủ công theo yêu cầu bản thân sử dụng WebClient hoặc 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

Tôi không có quyền truy cập vào dịch vụ đó trong dự án web của mình. Đó là một phần khác của cơ sở mã so với vị trí tệp của tôi. –

+0

Tôi hiểu điều đó; VS sẽ tạo một đối tượng proxy sẽ tương tác với dịch vụ đó nhân danh bạn. Bạn sẽ có quyền truy cập vào tất cả các phương pháp trên đó ... – Janie

+0

Hãy xem giải pháp của jjnguy để biết chi tiết ... – Janie

0

Có vẻ như bạn đang chạy vào cùng một hoặc Chính sách igin

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

Tôi tin rằng có nhiều cách để vượt qua nó, nhưng tôi nghĩ các áp phích khác là đúng. Trên máy chủ, viết các phương thức sử dụng HttpWebRequest để gọi dịch vụ web, và sau đó sử dụng JavaScriptSerializer để phân tích cú pháp JSON. Tôi dành phần lớn buổi chiều để nghiên cứu nguyên nhân này tôi sẽ phải viết một cái gì đó tương tự như bản thân mình.

>>>> Nathan 

P.S. Tôi thích kế hoạch của @ Janie tốt hơn ... Bạn có thể làm điều đó với một dịch vụ web trả về JSON cũng như một dịch vụ trả về XML không?

+0

Còn kế hoạch của @ jjnguy thì sao? – jjnguy

+0

Bạn không thêm JavaScriptSerializer./jk Tôi vẫn còn tò mò nếu bạn có thể xây dựng các lớp proxy cho các dịch vụ JSON ... Có vẻ như không làm cho nó hoạt động trên máy của tôi ở đây ... – Nathan

Các vấn đề liên quan