locked
proxy error when consuming internal web service

    Question

  • I've pulled out much hair over this, so I hope a guru out there can quickly see the err of my ways.   I have created (with the help of some code from articles) a web service that accesses an external web site (outside of our company firewall).   I have coded the web proxy and credentials into the web service.  In testing via a browser, the web service performs correctly, in that it authenticates thru the firewall and returns data to the browser in XML format.  Now I need to consume that web service in an ASP.NET application.  However, it fails with the error : The request failed with HTTP status 502: Bad Gateway.  The client code is pretty darn simple, so I'm embarrassed that it's not easily working.  The sanitized code is below (client and web service).  Thanks to anyone that can assist. 
    CLIENT CODE:
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using com.mycompany.intranet1;
    using System.Web.Services;
    using System.Net;
    
    public partial class _Default : System.Web.UI.Page 
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            StockServices ss = new StockServices();
            WebProxy myProxy;
            myProxy = new WebProxy("000.000.000.000", 80);
            myProxy.Credentials = new NetworkCredential("systemid", "systempassword");
            ss.Proxy = myProxy;
            ss.GetQuotes("MSFT");  //<---here is the line that fails    
            GridView1.DataSource = ss;
            GridView1.DataBind();
        }    
    }
    
    WEB SERVICE CODE:
    using System;
    using System.IO;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web.Services;
    using System.Net;
    using System.Web;
    
    
    	/// <summary>
    	/// Summary description for StockServices.
    	/// </summary>
    	[WebService (Namespace="http://enterprise.intranet.com")]
    	public class StockServices : System.Web.Services.WebService
             {
            WebProxy myProxy;
    
            public StockServices()
    		{
    			InitializeComponent();
    		}
    
    		#region Component Designer generated code
    		
    		//Required by the Web Services Designer 
    		private IContainer components = null;
    				
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		private void InitializeComponent()
    		{
    		}
    
    		/// <summary>
    		/// Clean up any resources being used.
    		/// </summary>
    		protected override void Dispose( bool disposing )
    		{
    			if(disposing && components != null)
    			{
    				components.Dispose();
    			}
    			base.Dispose(disposing);		
    		}
    		
    		#endregion
    
    		[WebMethod]
    		public string GetQuote(string ticker)
    		{
    			string stockURL, page, retval;
    			try
    			{
    				stockURL = GetURL(ticker);
                                    page = GetPageContent(stockURL);
    				retval = ParsePage(page);
    			}
    			catch (ArgumentOutOfRangeException) 
    			{
    				retval = "Invalid Ticker!";
    			}
    			catch (Exception)
    			{
    				retval = "Unknown Error";
    			}
    			
    			return retval;
    		}
    
    		[WebMethod]
    		public DataSet GetQuotes(string tickers)
    		{
    			char[] splitter = {' '};
    			string[] _tickers = tickers.Trim().Split(splitter);
    			Int32 i, ticks;
    
    			ticks = _tickers.Length;
    
    			DataSet ds = new DataSet();
    			DataTable dt = new DataTable("StockData");
    			DataColumn dc;
    
    			dc = dt.Columns.Add("Ticker",System.Type.GetType("System.String"));
    			dc = dt.Columns.Add("Price",System.Type.GetType("System.String"));
    
    			for (i = 0; i < ticks; i++)
    			{
    				DataRow dr = dt.NewRow();
    				dr["Ticker"] = _tickersIdea.ToUpper();
    				dr["Price"] = GetQuote(_tickersIdea);
    				dt.Rows.Add(dr);
    			}
    
    			ds.Tables.Add(dt);
    			return ds;
    		}
    
            public void SetProxy()
            {
                myProxy = new WebProxy("000.000.000.000", 80);
                myProxy.Credentials = new NetworkCredential("sysid", "syspw");
            }
    
    		private string GetURL(string ticker)
    		{
    			StringBuilder url = new StringBuilder();
    
    			url.Append("http://finance.yahoo.com/q/ecn?s=");
    			url.Append(ticker);
    
    			return url.ToString();
    		}
    
    		private string ParsePage(string page)
    		{
    			Int32 i;
    
    			i = page.IndexOf("Last Trade:");
    			page = page.Substring(i);
    
    			i = page.IndexOf("&lt;b>");
    			page = page.Substring(i);
    
    			i = page.IndexOf("&lt;/b>");
    			page = page.Substring(0,i);
    
    			page = Regex.Replace(page,"&lt;b>","");
    			return page;
    		}
            public string GetPageContent(string url)
            {
                WebRequest wreq;
                WebResponse wres;
                StreamReader sr;
                String content;
                
                wreq = (HttpWebRequest)WebRequest.Create(url);
                SetProxy();
                wreq.Proxy = myProxy;
                wreq.Credentials = myProxy.Credentials;
    
                // make the HTTP call
                wres = (HttpWebResponse)wreq.GetResponse();
                sr = new StreamReader(wres.GetResponseStream());
                content = sr.ReadToEnd();
                sr.Close();
    
                return content;
            }
    }
    
     
    Tuesday, July 18, 2006 7:57 PM

All replies

  • I am not sure if I am missing anything but I cannot see a Proxy property on your web service. So what is your client trying to set on the line:

    ss.Proxy = myProxy;
    Is your proxy server to be hard-coded on the web service or is the ASP.NET client supposed to set it?

    Tuesday, July 18, 2006 9:09 PM
  • In the web service itself, in the GetPageContent method, I'm manually setting the proxy so that the external URL call will work.  I guess that's where I'm confused.  I'm not sure why, if the service is handling the proxy settings itself, I am required to even worry with it in the consuming application.

    I didn't even think the .Proxy property would be there, but sure enough it was there in IntelliSense.  Maybe it's just there by default with a web reference?  I'm not sure. 

    The thing to remember is that the web service, when tested in a browser using http all by itself, works fine.  It goes out thru the proxy server and returns data correctly.  The thing I'm struggling with is consuming it.  Trying to consume it generates the 502 Bad Gateway error from both an ASP.NET app as well as a local VB.NET app.

    Tuesday, July 18, 2006 11:17 PM
  • The Proxy that you see on the web refernce is inheited from SoapHttpClientProtocol. Set this only if the client is accessing the web service over a firewall.(this is NOT the proxy that the web serveice uses to connect to the external web service)
    Wednesday, July 19, 2006 12:08 AM
  • Thanks.  I'll adjust that.  I had tried that originally, but was getting a 404 Not Found error instead.  I'll try it again in the office in the morning.
    Wednesday, July 19, 2006 12:21 AM
  • Well, interesting thing.  I do get the 404 error when I take out that line.  However, when I run it in debug mode, which launches localhost instead of the actual server, it runs fine!  Any thoughts on that?
    Wednesday, July 19, 2006 11:35 AM
  • Where exactly is your first web service running?

    Your scenario is something like this

                                

    Client---->WS------------------>External WS

    The red line is thro the firewall.

    How about the client calling the WS. Is the WS on the same machine? Is the url specified correctly? (In .NET 2.0 this is in the app.config)

    Wednesday, July 19, 2006 5:26 PM
  • Actually, there is only one web service, and it's on the same server as the ASP.NET application that's consuming it.  The web service goes out to an external site and does some scraping and returns data.  There isn't any external web service being used.
    Wednesday, July 19, 2006 6:40 PM
  • In looking at the stack trace, I'm now wondering if this is a permissions issue on the server.  That would seem to explain why it works when I run it in debug mode (which launches localhost) and not on the production box.  Here's the stack trace:

    [WebException: The request failed with HTTP status 404: Not Found.]
       System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) +533199
       System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +204
       StockServices.GetQuotes(String tickers) in c:\WIN2KE\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\stockquote\f5c10ec1\fde27c5b\App_WebReferences.mcw2vbcq.0.cs:93
       _Default.Page_Load(Object sender, EventArgs e) in e:\Inetpub\wwwroot\cc\DevStockQuote\StockQuote.aspx.cs:18
       System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
       System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
       System.Web.UI.Control.OnLoad(EventArgs e) +99
       System.Web.UI.Control.LoadRecursive() +47
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061

    Wednesday, July 19, 2006 6:58 PM
  • How is your development different from production?

    ASPX Client-->Local WS(same machine as Client)-->External Site

    Are the client and WS on the same machine in both cases?

     

    Wednesday, July 19, 2006 10:00 PM
  • Client ASP.NET app is on the same server as the web service.  When I run in debug mode, it launches a local web server of course so it's on my machine. 

    I've done a general search on 404 errors with ASP.NET web services and it seems quite common.  Not a lot of solutions, but a common error.  I'm hoping to find a solution soon!

    Thursday, July 20, 2006 1:17 AM
  • I would say check out the exact URL the client accesses.(Check your web.config for the url.)
    Thursday, July 20, 2006 6:13 AM
  • I did, and it is exactly the correct URL.
    Thursday, July 20, 2006 11:13 AM
  • Could this have anything to do with a proxy setting?  I find it VERY odd that it fails with a server URL, but when I debug (which launches the server application with a localhost instance) it works fine.  Could there be some web.config setting?  Or maybe something to set on the server box itself?  I just have this feeling that it's trying to find the URL somewhere where it's not resolving.
    Thursday, July 20, 2006 1:20 PM