Saturday, February 28, 2009

Unable to connect to the remote server

I was programming a payment gateway for NAB. I construct the xml in vb.net and then send the web request of xml contenttype to the NAB payment gateway URL using the WebRequest class:

Imports System.Reflection

Imports System.Web

Imports System.Net

Imports System.IO

Imports System.Text


Public Class clsNABTransact


Private mstrErrorMessage As String = ""


Public Property strErrorMessage() As String


Get


strErrorMessage = mstrErrorMessage


End Get


Set(ByVal Value As String)


mstrErrorMessage = Value


End Set


End Property


Public Function ReadHtmlPagePost(ByVal sURL As String, ByVal sPostData As String) As String


Dim objResponse As WebResponse


Dim objRequest As WebRequest


Dim result As String


Dim myWriter As StreamWriter


Try


objRequest = WebRequest.Create(sURL)


objRequest.Method = "POST"


objRequest.ContentLength = sPostData.Length()


objRequest.ContentType = "text/xml"


Try


myWriter = New StreamWriter(objRequest.GetRequestStream())


myWriter.Write(sPostData)


myWriter.Close()


objResponse = objRequest.GetResponse()


Dim sr As New StreamReader(objResponse.GetResponseStream())


result += sr.ReadToEnd()


'clean up StreamReader


sr.Close()


Return result


Catch Ex As Exception


strErrorMessage = Ex.ToString


Return ""


End Try


Catch E As Exception


strErrorMessage = E.ToString


Return ""


End Try


End Function


End Class


When I tested on my local, I can get the response XML from NAB with no problems. But when the client test it on their end, they get the following error:

Credit card payment unsuccessful Problem in Payment Gateway Error:System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it XXX.XX.XXX.XXX:XXX at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP) at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception) — End of inner exception stack trace — at System.Net.HttpWebRequest.GetRequestStream() at clsNABTransact.ReadHtmlPagePost(String sURL, String sPostData)()

Reason:

  • Cannot connet to the Remote Server (NAB), because the proxy server is blocking the your access to the NAB server.
  • The ISA server (proxy server) on the client side is set such that you need to be a member of a windows security group to browse the internet.

What I tried:

1. Firstly, I add the following in the web.config:

<system.net>


<defaultProxy useDefaultCredentials="true" >


<proxy usesystemdefault="True" proxyaddress="http://proxy.test.com.au:8080" bypassonlocal="True"/>


</defaultProxy>


</system.net>


2. Then I got a different error says:

Credit card payment unsuccessful Problem in Payment Gateway Error:System.Net.WebException: The remote server returned an error: (407) Proxy Authentication Required. at System.Net.HttpWebRequest.GetRequestStream() at CMDotNet.Common.clsNABTransact.ReadHtmlPagePost(String sURL, String sPostData)()

3. Then what I did was: on the proxy server, there’s some site that all users are able to access regardless of whether you are a member of a windows security group or not, I added the Nab URl to this allow access list.

4. Then everything is working.

5. But I think what the real reason is that:

  • Firstly, it says it cannot connect to the NAB server is because
    • The Network Service account is a special built in account that is local and unique to each machine. That means the Network Service account on Server A is different from the Network Service on Server B. If it is the Network Service account that running your application pool identity in IIS, it is a low access account which does not have access to the machine proxy configuration settings which are stored in the registry under HKLM keys. So you can’t get the proxy settings.
  • When I added the proxy info in the web.config, the web.config tells the application where to find the proxy, then it will try to connect to the NAB URL throught the proxy server, but since Network Service is a local account, it may not have the access to the NAB URL, so you got the Proxy Authentication Required.
  • Then I added the URL to the access list which means everyone can access the URL. Here are the better solutions which does not require you to change the web.config:
    • You can try to change the application pool identity to a domain account whose password never expires.
    • Alternatively, when you are using WebRequest, you can set WebRequest.UseDefaultCredentials or WebRequest.Credentials in the code or web.config.

Terms:

  • bypassonlocal : if you do not want the proxy server computer to be used when you connect to a computer on the local network (this may speed up performance).
  • usesystemdefault : if true, then it will pick up the default proxy you set in the IE. If false, then it will pick up the proxy in the control panel. My company is using a transparent proxy setting which means that you do not get to see what proxy you are using in the IE, the proxy is set in a way that it is both the default proxy and a transparent proxy.



If you are expericing slow connection, but finally you can connect to the internet, then you can disables automatic Proxy detection. According to Rick, the reasons it happened is because
  • In .NET 1.1 no proxy is set, it would try to connect directly.
  • .NET 2.0 uses the machine’s default proxy configuration by default. The default proxy configuration is the configuration you see in the IE proxy configuration settings.
  • NETWORK SERVICE is a low access account which does not have access to the machine proxy configuration settings which are stored in the registry under HKLM keys. So you can’t get the proxy settings.

There are two ways you can solve this:

  • Set usesystemdefault="false" in the web.config
  • In the code to explicitly set the Proxy property of the Http object (WebRequest, XmlDom, Web Service Client etc.) to null

proxy server

  • A server that sits between a client application, such as a Web browser, and a real server. It intercepts all requests to the real server to see if it can fulfill the requests itself. If not, it forwards the request to the real server.
  • Proxy servers have two main purposes:
    • Improve Performance
    • Filter Requests

References:

Sending HttpWebRequest via firewall & over SSL

Unable to connect to the remote server

Slow Http client calls from ASP.NET 2.0? Make sure you check your Proxy Settings!

proxy server

Is it possible to specify proxy credentials in your web.config?
(407) proxy authentication required : Use HttpWebRequest with Proxy

Saturday, February 21, 2009

Load unreferenced dll at runtime

If you want to call methods in another dll which was not referenced in the current project, here is how:

Public Sub ExportXML(ByVal userID As Integer, _


ByVal oldPassword As String, _


ByVal newPassword As String)

Try


Dim isExportXML As String = WebConfigurationManager.AppSettings("IsExportXMLWhenPasswordChanged")


If isExportXML IsNot Nothing AndAlso isExportXML.ToLower() = "yes" Then


Dim ht As New Hashtable


Dim binPath As String = Path.Combine(HttpContext.Current.Server.MapPath("~"), "bin\Test.Common.dll")


Dim myDllAssembly As Assembly = Assembly.LoadFile(binPath)


Dim o As Object = myDllAssembly.CreateInstance("Test.Common.ExportXML")


Dim objUser As New clsUser(mstrConn)


objUser.getData(userID)


Dim logon As String = objUser.strLogon


Dim argstopass As Object() = New Object() {ht, "AgentID", logon}


o.GetType.GetMethod("InsertHash").Invoke(o, argstopass)


argstopass = New Object() {ht, "OldWebPassWord", oldPassword}


o.GetType.GetMethod("InsertHash").Invoke(o, argstopass)


argstopass = New Object() {ht, "NewWebPassWord", newPassword}


o.GetType.GetMethod("InsertHash").Invoke(o, argstopass)


Dim argstopass1 As Object() = New Object() {ht, 7}


o.GetType.GetMethod("ExportUsingHash").Invoke(o, argstopass1)


End If


Catch e As Exception


clsLog.log(e.ToString)


Throw e


End Try


Imports System.IO

Imports System.Reflection


Public Class ExportXML


Public Sub New()


End Sub


Public Sub ExportUsingHash(ByVal ht As Hashtable, ByVal exportType As ExportType)


Try


If ht.Count <= 0 Then


Return


End If


'header open


Dim sb As New StringBuilder()


sb.Append("<DataRoot>")


sb.Append("<TestNode>")


'loop content


For Each item As DictionaryEntry In ht


sb.AppendFormat("<{0}>{1}</{2}>", item.Key, item.Value, item.Key)


Next


sb.Append("</TestNode>")


sb.Append("</DataRoot>")


'output xml


Dim logFilePath As String = _


String.Format("{0}\Integration\{1}{2}({3}).xml", _


HttpContext.Current.Server.MapPath("~"), _


exportType.ToString(), _


String.Format("{0:ddMMyyyyHHmmss}", DateTime.Now), _


System.Guid.NewGuid().ToString())


Using sw As New StreamWriter(logFilePath, True)


sw.WriteLine("<?xml version=""1.0"" ?>")


sw.Write(sb.ToString())


sw.Close()


End Using


Catch ex As Exception


Throw ex


End Try


End Sub


'Compare object changes


Public Sub Export(ByVal obj_Before As Object, _


ByVal obj_After As Object, _


ByVal exportType As ExportType, _


ByVal actionMode As ActionMode)


Try


'header open


Dim sb As New StringBuilder()


sb.Append("<DataRoot>")


sb.Append("<TestNode>")


'if add mode, add all to the xml


If actionMode = Common.ActionMode.Add Then


If obj_After IsNot Nothing Then


Dim t2 As Type = obj_After.GetType()


For Each p2 As PropertyInfo In t2.GetProperties()


WriteContent(p2.Name, p2.GetValue(obj_After, Nothing), exportType, sb, actionMode, False)


Next


End If


ElseIf actionMode = Common.ActionMode.Edit Then


'if edit mode, only add changed ones to xml


If obj_Before IsNot Nothing AndAlso obj_After IsNot Nothing Then


Dim t1 As Type = obj_Before.GetType()


Dim t2 As Type = obj_After.GetType()


For Each p1 As PropertyInfo In t1.GetProperties()


For Each p2 As PropertyInfo In t2.GetProperties()


If p1.Name = p2.Name Then


Dim IsEqual As Boolean = False


IsEqual = p1.GetValue(obj_Before, Nothing).Equals(p2.GetValue(obj_After, Nothing))


WriteContent(p2.Name, p2.GetValue(obj_After, Nothing), exportType, sb, actionMode, IsEqual)


Exit For


End If


Next


Next


End If


ElseIf actionMode = Common.ActionMode.Delete Then


If obj_Before IsNot Nothing Then


Dim t1 As Type = obj_Before.GetType()


For Each p1 As PropertyInfo In t1.GetProperties()


WriteContent(p1.Name, p1.GetValue(obj_Before, Nothing), exportType, sb, actionMode, False)


Next


End If


End If


sb.Append("</TestNode>")


sb.Append("</DataRoot>")


'output xml


Dim logFilePath As String = _


String.Format("{0}\Integration\{1}{2}({3}).xml", _


HttpContext.Current.Server.MapPath("~"), _


exportType.ToString(), _


String.Format("{0:ddMMyyyyHHmmss}", DateTime.Now), _


System.Guid.NewGuid().ToString())


Using sw As New StreamWriter(logFilePath, True)


sw.WriteLine("<?xml version=""1.0"" ?>")


sw.Write(sb.ToString())


sw.Close()


End Using


Catch ex As Exception


Throw ex


End Try


End Sub


Public Sub InsertHash(ByVal ht As Hashtable, _


ByVal key As String, _


ByVal val As Object)


If Not IsDBNull(key) AndAlso key IsNot Nothing Then


ht(key) = val.ToString()


End If


End Sub


End Class


Reference:

Using Reflection to load unreferenced assemblies at runtime in C#

Sunday, February 15, 2009

Javascript page redirection

The following javascript will:
  • Create a form on the fly and send post request without using the underlying form action tag
  • Post only the fields you want
  • You can put the following code in the RadEditor




<input type=hidden name="retURL" value="http://www.whatever.com.au/">

<label for="salutation">Salutation</label>

<select id="salutation" name="salutation">

<option value="">--None--</option>

<option value="Mr">Mr</option>

<option value="Ms">Ms</option>

<option value="Miss">Miss</option>

<option value="Mrs">Mrs</option>

<option value="Dr">Dr</option>

<option value="Prof">Prof</option>

<option value="Hon">Hon</option>

<option value="Sir">Sir</option>

<option value="Lady">Lady</option>

<option value="Capt">Capt</option>

</select><br>

<label for="first_name">First Name</label><input id="first_name" maxlength="40" name="first_name" size="20" type="text" /><br>

<label for="last_name">Last Name</label><input id="last_name" maxlength="80" name="last_name" size="20" type="text" /><br>

<label for="email">Email</label><input id="email" maxlength="80" name="email" size="20" type="text" /><br>

<label for="phone">Phone</label><input id="phone" maxlength="40" name="phone" size="20" type="text" /><br>

<label for="description">Description</label><textarea name="description"></textarea><br>

<label for="street">Address</label><textarea name="street"></textarea><br>

<label for="city">City</label><input id="city" maxlength="40" name="city" size="20" type="text" /><br>

<label for="state">State/Province</label><input id="state" maxlength="20" name="state" size="20" type="text" /><br>

<label for="zip">Zip</label><input id="zip" maxlength="20" name="zip" size="20" type="text" /><br>

<label for="title">Title</label><input id="title" maxlength="40" name="title" size="20" type="text" /><br>

<label for="fax">Fax</label><input id="fax" maxlength="40" name="fax" size="20" type="text" /><br>

<label for="mobile">Mobile</label><input id="mobile" maxlength="40" name="mobile" size="20" type="text" /><br>

<label for="lead_source">Lead Source</label><select id="lead_source" name="lead_source"><option value="">--None--</option><option value="Details Referred">Details Referred</option>

<option value="Direct Mail">Direct Mail</option>

<option value="Display">Display</option>

<option value="Email">Email</option>

<option value="Event">Event</option>

<option value="Mobile">Mobile</option>

<option value="Open House">Open House</option>

<option value="Phone">Phone</option>

<option value="Walk-In">Walk-In</option>

<option value="Website">Website</option>

</select><br>

Project Office:<select id="00N20000000lQgj" name="00N20000000lQgj" title="Project Office"><option value="">--None--</option><option value="Abervale">Abervale</option>

<option value="Bingara Gorge">Bingara Gorge</option>

<option value="Blakeview">Blakeview</option>

<option value="Burwood Terrace">Burwood Terrace</option>

<option value="Caesia Gardens">Caesia Gardens</option>

<option value="Caroline Springs">Caroline Springs</option>

<option value="Craigieburn">Craigieburn</option>

<option value="Daikyo">Daikyo</option>

<option value="Edgewater">Edgewater</option>

<option value="Fiddlers Green">Fiddlers Green</option>

<option value="Forest Gardens">Forest Gardens</option>

<option value="Forest Hills">Forest Hills</option>

<option value="Glenaeon">Glenaeon</option>

<option value="Gawler East">Gawler East</option>

<option value="Highvale">Highvale</option>

<option value="Jacksons Landing">Jacksons Landing</option>

<option value="Keperra">Keperra</option>

<option value="Lakeside Pakenham">Lakeside Pakenham</option>

<option value="Laurimar">Laurimar</option>

<option value="Lutanda">Lutanda</option>

<option value="Mawson Lakes">Mawson Lakes</option>

<option value="Nelsons Grove">Nelsons Grove</option>

<option value="Nelsons Ridge">Nelsons Ridge</option>

<option value="Peppertree Hills">Peppertree Hills</option>

<option value="Pittwater">Pittwater</option>

<option value="Rochford Place">Rochford Place</option>

<option value="Rocky Springs">Rocky Springs</option>

<option value="Rouse Hill">Rouse Hill</option>

<option value="Springfield Lakes">Springfield Lakes</option>

<option value="St Marys">St Marys</option>

<option value="St Patricks Estate">St Patricks Estate</option>

<option value="Sunshine Coast">Sunshine Coast</option>

<option value="The Terraces">The Terraces</option>

<option value="Trinity Green">Trinity Green</option>

<option value="Varsity Lakes">Varsity Lakes</option>

<option value="Victoria Harbour">Victoria Harbour</option>

<option value="Woodlands">Woodlands</option>

<option value="Yarrabilba">Yarrabilba</option>

</select><br>

<label for="emailOptOut">Email Opt Out</label>

<input id="emailOptOut" name="emailOptOut" type="checkbox" value="1" /><br>

<input type="button" onclick="post_to_url('http://www.test.com', 'post');" value="Submit">

<script type="text/javascript">

function post_to_url(path, method)

{

method = method "post"; // Set method to post by default, if not specified.

// The rest of this code assumes you are not using a library.

// It can be made less wordy if you use one.

var form = document.createElement("form");

form.setAttribute("method", method);

form.setAttribute("action", path);

var sal = document.getElementById("salutation");

createHidden("salutation", sal.options[sal.selectedIndex].value, form);

createHidden("first_name", document.getElementById('first_name').value, form);

createHidden("last_name", document.getElementById('last_name').value, form);

createHidden("email", document.getElementById('email').value, form);

createHidden("phone", document.getElementById('phone').value, form);

createHidden("description", document.getElementById('description').value, form);

createHidden("street", document.getElementById('street').value, form);

createHidden("city", document.getElementById('city').value, form);

createHidden("state", document.getElementById('state').value, form);

createHidden("zip", document.getElementById('zip').value, form);

createHidden("title", document.getElementById('title').value, form);

createHidden("fax", document.getElementById('fax').value, form);

createHidden("mobile", document.getElementById('mobile').value, form);

var lead = document.getElementById("lead_source");

createHidden("lead_source", lead.options[lead.selectedIndex].value, form);

var projOffice = document.getElementById("00N20000000lQgj");

createHidden("00N20000000lQgj", projOffice.options[projOffice.selectedIndex].value, form);

var opt = document.getElementById("emailOptOut");

var ischecked;

if(opt.checked){

ischecked = 1

}

else{

ischecked = 0

}

createHidden("emailOptOut", ischecked, form);

document.body.appendChild(form); //This is necessary

form.submit();

}

function createHidden(hiddenName, hiddenValue, myForm)

{

var hiddenField = document.createElement("input");

hiddenField.setAttribute("type", "hidden");

hiddenField.setAttribute("name", hiddenName);

hiddenField.setAttribute("value", hiddenValue);

myForm.appendChild(hiddenField);

}

</script>


Reference:
Javascript Post Request like a Form Submit