In ASP.Net C#, Call webpage asynchronously with get and post method type and additional parameters in callback method

Asynchronous method call is a mechanism in which control execution returns directly to the next statement without waiting for the method operation execution. Every asynchronous call is associated with a dedicated thread. IIS has limited number of application thread pools (default 5000 per CPU). IIS can handle that number of concurrent request at a time. So if you have a situation where you expect large number of concurrent requests in a single application, asynchronous method call will be a good practice. Where synchronous call executes by occupying 5000 threads, asynchronous can perform the same task with only 50 available threads. Here you can read more on thread pools here

In C# data posting with get() method in asynchronous calls can be done by just passing parameters in URL where as in asynchronous post() method for passing the parameters you will need to write them in stream asynchronously. For that .Net is providing reach HttpWebRequest class methods.

Recently I had a situation where my application was expecting very heavy user traffic and I had a requirement to store them into my database as well as also need to pass the data to a third party webpage. So I needed to pass the data asynchronously to that third party webpage without waiting for the response from that webpage. Also if any asynchronous call fails during the execution due to any data mismatch, I need to log the error along with an “id” from my database for that user request. And to achieve that I needed to pass some extra data like “UserId”, which was not a part of asynchronous method parameters. Also I could not add the “id” in webpage parameter collection as it was not a part of the third party webpage definition.
So to accomplish this I have sent the parameter of type Object array into asynchronous method request with method type post. Following are the example of code for asynchronous get method, asynchronous post method and asynchronous post method with extra parameters.

Example for asynchronous GET method:

protected void Page_Load(object sender, EventArgs e)
{
//For testing I have used current application’s about.aspx itself
//Passes id, firstname and lastname as a quesrystring in URL
GetMethodCall(“http://localhost:2839/about.aspx?id=1&firstname=abc&lastname=xyz”);
}
private static void GetMethodCall(string URL)
{
//Create new HttpWebRequest object for the passed URL using create method
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);//BeginGetResponse is used to call asynchronously URL
IAsyncResult result =
(IAsyncResult)request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);}
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
// Request state is asynchronous.
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
request.Method = “GET”;
try
{
//Read the response for any future needs.
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);// Release the HttpWebResponse
response.Close();
}
catch (Exception ex)
{
//Log the error
string errormessage = ex.Message;
}
}

 

Example for POST method:

protected void Page_Load(object sender, EventArgs e)
{
// GetMethodCall(“http://localhost:2839/about.aspx?id=1&firstname=abc&lastname=xyz”);
//For post data testing I have used current application’s aboutpost.aspx
PostMethodCall(“http://localhost:2839/aboutpost.aspx”);
}
private static void PostMethodCall(string URL)
{
//Create new HttpWebRequest object for the passed URL using create method
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);//Set method verb type to POST
request.Method = “POST”;
request.ContentType = “application/x-www-form-urlencoded”;// BeginGetRequestStream is used to set post data content in asynchronously call
IAsyncResult result =
(IAsyncResult)request.BeginGetRequestStream(new AsyncCallback(GetRequestCallback), request);}
private static void GetRequestCallback(IAsyncResult asynchronousResult)
{
// Request state is asynchronous.
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
try
{
Stream postStream = request.EndGetRequestStream(asynchronousResult);//Set data to be post
string postData = “id=1&firstname=abc&lastname=xyz”;// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(postData);// Write to the request stream.
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
catch (Exception ex)
{
//Log the error
string errormessage = ex.Message;
}
}

You need to use same GetResponseCallback method as previous example.

Example for GET & POST methods with additional user defined parameters:

protected void Page_Load(object sender, EventArgs e)
{
// GetMethodCall(“http://localhost:2839/about.aspx?id=1&firstname=abc&lastname=xyz”);
//For post data testing I have used current application’s aboutpost.aspx
PostMethodCall(“http://localhost:2839/aboutpost.aspx”, “L001020″, “U112″);
}
private static void PostMethodCall(string URL, string logID, string userid)
{
//Create new HttpWebRequest object for the passed URL using create method
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);//Set method verb type to POST
request.Method = “POST”;
request.ContentType = “application/x-www-form-urlencoded”;// BeginGetRequestStream is used to set post data content in asynchronously call
//Use 2nd parameter for asyncresult as oject type and pass additional parameters comma separated
IAsyncResult result =
(IAsyncResult)request.BeginGetRequestStream(new AsyncCallback(GetRequestCallback), new object[] { request, userid, logID });}
private static void GetRequestCallback(IAsyncResult asynchronousResult)
{
// Request state is asynchronous.
object[] param = (object[])asynchronousResult.AsyncState;
HttpWebRequest request = (HttpWebRequest)param[0];
//Read additional parametrs using object array
string userid = param[1].ToString();
string MyUniqueLogID = param[2].ToString();
try
{
Stream postStream = request.EndGetRequestStream(asynchronousResult);//Set data to be post
string postData = “id=1&firstname=abc&lastname=xyz”;// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(postData);// Write to the request stream.
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();// Start the asynchronous operation to get the response
//Use 2nd parameter for asyncresult as oject type and pass additional parameters comma separated
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), new object[] { request, userid, MyUniqueLogID });
}
catch (Exception ex)
{
//My custom log with my unique logID and userid
string errormessage = userid + “-” + MyUniqueLogID + “:” + ex.Message;
}
}private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
// Request state is asynchronous.
object[] param = (object[])asynchronousResult.AsyncState;
HttpWebRequest request = (HttpWebRequest)param[0];
//Read additional parametrs using object array
string userid = param[1].ToString();
string MyUniqueLogID = param[2].ToString();
try
{
//Read the response for any future needs.
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);// Release the HttpWebResponse
response.Close();
}
catch (Exception ex)
{
//My custom log with my unique logID and userid
string errormessage = userid + “-” + MyUniqueLogID + “:” + ex.Message;
}
}

Similarly you can pass additional parameters in GET method type by calling same GetResponseCallback callback.

request.BeginGetResponse(new AsyncCallback(GetResponseCallback), new object[] { request, userid, MyUniqueLogID });

Additional information:

  • You can retrieve GET method parameters as follows:

  • You can retrieve POST method parameters as follows:

You can retrieve return value from asynchronous web page call using following code:

private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
// Request state is asynchronous.
object[] param = (object[])asynchronousResult.AsyncState;
HttpWebRequest request = (HttpWebRequest)param[0];
//Read additional parametrs using object array
string userid = param[1].ToString();
string MyUniqueLogID = param[2].ToString();
try
{
//Read the response for any future needs.
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
//Get response stream for check return values by external webpage
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
//Get response in string object
string myResult = responseString;
if (myResult == “success”)
{
string status = “I am done”;
}
else
{
string status = “I am done with some error”;
}

// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
}
catch (Exception ex)
{
//My custom log with my unique logID and userid
string errormessage = userid + “-” + MyUniqueLogID + “:” + ex.Message;
}
}

Required additional namespaces

System.Net.HttpWebRequest
System.Text; // for Encoding.UTF8

Supported .NET Frameworks

Supported in: 4.5.1, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

Posted By: Kruti V Parmar

How to manage "Cross-Domain" Call

What is Cross-Domain Call?

  • When a web-application request data from other domain then its called Cross Domain Call. It is also known as “Cross Site Scripting” or “XSS”.

Why we need Cross-Domain Call?

  • When it is required to get some data from other than current domain and that domain gives data in certain format then we need to make “Cross Domain” request.
  • or e.g: To display twitter feed data in our Web-Application, we need to make request to www.twitter.comfor feeding required feeds to our sites which is called Cross-Domain Call.

Behavior of cross-Domain Call :

  • ross-Domain calls are always asynchronous.

Ways to make Cross-Domain Call :

  • There are two ways to make Cross-Domain Call :
    1. Client-Side Call
    2. Server-Side Call

    1. Client-Side Cross-Domain Call :
      • Client-Side Cross-Domain Calls are Ajax calls and can be made through JavaScript or jQuery.
      • Client-Side call are always acynchronous in manner.
      • We can make Cross-Domain calls from Client-Side when it is independent call means no taks is depend on it.
      • For e.g. If we are making Cross-Domain Call from Client-Side in Fancybox Pop-Up and we have written code of Cross-Domain call and after that we are closing Fancybox then it ispossile that ajax call is under progrss asynchronously and Fancybox gets Closed.
      • So in above situation we can’t make Cross-Domain call from Client Side as Ajax calls are asynchron in nature specially when it is Cross-Domain call and we can’t make it is as synchronous call.
      • Example : Following Example Shows how we can make Client-Side Ajax Call. Following Example shows how we can get twitter feed from www.twitter.com.
        <script type=”text/javascript”>
        function GetTwitterFeed()
        {
        $.ajax({
        url:“http://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=abc&count=5&callback=?”
        contentType: “application/json; charset=utf-8”,
        success: function (result) {
        if (result.length > 0) {
        }
        }
        });
        }
        </script>
    2. Server-Side Cross-Domain Call :
      • We can make Cross-Domain Call from Server Side when some task depend on resulted data.
      • Following example shows how we can make Cross-Domain Call from Server Side.
      • In this example we are requesting twitter feed data from www.twitter.com.
        public static string GetJsonDataByUserName(string UserName, string TwitterFeedCount)
        {
        string jsondata;
        try
        {
        WebClient web = new WebClient();
        jsondata = web.DownloadString(string.Format(“http://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name={0}&count={1}&callback=?”, UserName, TwitterFeedCount));if (jsondata.Contains(“([]);”))
        {
        return string.Empty;
        }
        jsondata = jsondata.Substring(1);
        jsondata = jsondata.Substring(0, (jsondata.Length – 2));
        return jsondata;
        }
        catch (Exception ex)
        {
        return string.Empty;
        }
        }

Cross-Domain Call in Different Context : (Sub-Domain)

  • When we are working in a scenario where Domain and Sub-Domains exists and it is require to call some services which recognize only Domain call and rejects Sub-Domain Call at that time there is need to maintain Context and Cross Domain Call explicitly.
  • Let’s take scenario of Facebook Login Pop-UP from Fancybox Pop-Up which is open from some page.
  • For example we are working in https://test.qbs.com(Sub-Domain of https://www.qbs.com) context and we are in page called LinkToFacebook.aspx.
  • Now LinkToFacebook.aspx page contains link from which Fancybox Pop-Up page FacebookLogin.aspx going to open and in that Pop-Up page we are putting Facebook Login plugin.
  • But here Facebook Login plugin will not allow context of Sub-Domain https://test.qbs.com/FacebookLogin.aspx, So we need to open FacebookLogin.aspx as
    https://www.qbs.com/FacebookLogin.aspx, which is different context from Sub-Domain Context.
  • Now in this scenario https://test.qbs.com/LinkToFacebook.aspxis detached from https://www.qbs.com/FacebookLogin.aspxbecause we are now in different context.
  • So now from https://www.qbs.com/FacebookLogin.aspxpage we can access any parent window https://test.qbs.com/LinkToFacebook.aspxpage elements or any functions. For example we can’t call window.parent.$.fancybox.close() function to close Fancybox Pop-Up when our works get done on https://www.qbs.com/FacebookLogin.aspxpage.
  • Here we will not be able to access any session data because https://www.qbs.com/FacebookLogin.aspx will be a different session.
  • Now when it is required to pass some data from https://www.qbs.com/FacebookLogin.aspxto https://test.qbs.com/LinkToFacebook.aspx, we must have to use Cookie in this Scenario because as we are in different context, Session will be also different So Session will not work here.
  • Cookie is the only way to maintain session within different context.
  • So we need to store required data from https://www.qbs.com/FacebookLogin.aspxpage in Cookie and need to access data from Cookie in https://test.qbs.com/LinkToFacebook.aspxpage.
  • Here we also need to ask User to explicitly close Fancybox Pop-Up.
  • In this way we can handle Cross-Domain call in different context.

By, Bipin Jain

Exploring "X-Frame- Options" in IFrame for web-based application

In our daily life as a web developer we generally use lots of HTML tags in our website. From H1 tag to FORM tag, each tag has their own functionality and has some limitations. In this blog we specifically focus on IFRAME tag and its Do’s and Don’ts. To know about How to implement an IFRAME tag in your website you can do google search and there are lots of documents are available for that.
There are several advantages and disadvantages of IFRAME. We are going to see some of that which is important. We will also learn about what the “X-Frame-Options” is and how to handle that.

 

IFRAME enable you to load external website or HTML page within your webpage. Most of the website and pages can run inside of the IFRAME. It has properties which enable you to customize its content like frameborder, scrolling etc. Earlier we can load any type of website in IFRAME but as popularity of IFRAME is increased new vulnerabilities like Cross Site Request Forgery (CSRF) also known as ClickJacking and Cross-Site-Scripting(Xss) and Cross-Site-Scripting(Xss) are came in picture.

Do’s: Always try to load same domain page in IFrame. Loading difference domain or sub-domain may not load all functionality or may harm your site.
Don’ts: Never try to execute javascript code which tries to access elements outside of the iframe. It known as XSS script attack and most of new version of browser block this type of execution.

To prevent these types of vulnerabilities new browser introduces security patches. One of them is “X-Frame-Options”. When browser loads website in an IFRAME first it checks for site domain that this option is available in header or not. If this option not found in header then it allow IFRAME to load given site. If browser found this value then it checks for its value. Generally header values are in key –value pair. There are two values found in “X-Frame-Options”. First is “DENY” and second is “SAMEORIGIN”. Figure 1 display the value.

“DENY” means this website is not allowed to load in IFRAME. If you don’t want anyone to load your site in any IFRAME then you can set values in header (X-Frame-Options:DENY) . See screen shots of IE-9 (Figure 2) and Chrome (Figure 3) security which block this type of loading.

“SAMEORIGIN” means the website content is allowed for same domain.
If such cases if you want to load any website in IFRAME then first you need to check header for that site. The code for checking header value of any site is given below.
C# function that retrieve specific header value

private string webFetch(string link, string parameter)
{
string responseFromServer = “”;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(link);
request.Method = “POST”;
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(parameter);
request.ContentType = “application/x-www-form-urlencoded”;
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (HttpStatusCode.OK == response.StatusCode)
{
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
response.Close();
}
return responseFromServer;
}

php function that retrieve specific header value

function getResponseHeader($url)
{
return get_headers($url);
}
$url = ‘http://www.google.com/’;
$res_arr = getResponseHeader($url);
print_r($res_arr);

(Note: Framing third-party information into another web page raises issues of copyright so please make sure that you are not in website copyright criteria)

By, Dharmendra Mistry