Wednesday, May 30, 2012

Different ways for calling a code behind function from Javascript

Recently, one of my colleague asked about the different ways for calling a code behind function from JavaScript. There are different ways to call a code behind function and I decided to list down here each with example.

According to me, there are four main possible ways to call a function from Javascript:

1. Pagemethods in JS AND WebMethod in code behind class
2. IPostBackEventHandler in
codebehind class AND _doPostBack in JS 
3. ICallbackEventHandler in code behind class
4. Ajax/Jquery AND ASHX handler

Lets check each of above methods
with example and explanation.

1. Pagemethods in JavaScript AND WebMethod in cs

For using Pagemethods in JavaScript, we need to add Script Manager on aspx page. For using Ajax .Net (script manager, update panel) we need to add below settings in web.config and also System.Web.Extensions assembly is required.

<configuration>
    <system.web>
        <pages>
            <controls>
                <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
            </controls>
        </pages>   
    </system.web>
</configuration>
  

ASPX Page Code:

<script language="javascript" type="text/javascript">
    function GetCityValue() {
        PageMethods.GetCity("USA", onSucceeded, onFailed);
    }
    function onSucceeded(result, userContext, methodName) {
        document.getElementById("div1").innerHTML = result;
    }
    function onFailed(error, userContext, methodName) {
        alert("An error occurred")
    }
</script>

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
</asp:ScriptManager>
   
    <div>
<input type='button' name="btncity"  value="GetCityValue" onclick="javascript:GetCityValue()"/></div>
    <div id="div1"></div>
 


Codebehind Code:

[System.Web.Services.WebMethod()]
        public static string GetCity(String strCountry)
        {
            string strCity = string.Empty;
            if (strCountry == "USA")
                strCity = "NewYork";
            else
                strCity = "OtherCity";
            return strCity;
        }


Here 2 things need to take care:

1. Method in cs file must be public static and with attributes [System.Web.Services.WebMethod()]
2. Set EnablePageMethods="true" in Scriptmanager

2. IPostBackEventHandler in code behind class AND __doPostBack in JS

ASPX Page Code:

<script language="javascript" type="text/javascript">
    function GetCityValue() {
        var pageId = '<%=  Page.ClientID %>';
        __doPostBack(pageId, "USA");
    }
</script>
   
    <div>
<input type='button' name="btncity"  value="GetCityValue" onclick="javascript:GetCityValue()"/></div>
    <div id="div1"></div>
<asp:Label id="lblInfo" runat="server"></asp:Label>

Codebehind Code:

public partial class SampelForm : System.Web.UI.Page, IPostBackEventHandler
    {

        public string GetCity(String strCountry)
        {
            string strCity = string.Empty;
            if (strCountry == "USA")
                strCity = "NewYork";
            else
                strCity = "OtherCity";
            return strCity;
        }

        public void RaisePostBackEvent(string eventArgument)
        {
            string val = GetCity(eventArgument);
            lblInfo.Text += "City - " + val;
        }
    }


Here, with IPostBackEventHandler, Page is submitted to server (postback) and so user experience will NOT be as good compare to other methods.


3. ICallbackEventHandler in code behind class


ASPX Page Code:

<script language="javascript" type="text/javascript">
    function GetCityValue() {
        CallToServer('USA');
    }

    function ReceiveServerData(arg, context) {
        document.getElementById("div1").innerHTML = "Date from server: " + arg;
    }
</script>
   
    <div>
<input type='button' name="btncity"  value="GetCityValue" onclick="javascript:GetCityValue()"/></div>
    <div id="div1"></div>
<asp:Label id="lblInfo" runat="server"></asp:Label>

Codebehind Code:

public partial class SampelForm : System.Web.UI.Page, IPostBackEventHandler
{

        public string GetCity(String strCountry)
        {
            string strCity = string.Empty;
            if (strCountry == "USA")
                strCity = "NewYork";
            else
                strCity = "OtherCity";
            return strCity;
        }

        public void RaisePostBackEvent(string eventArgument)
        {
            string val = GetCity(eventArgument);
            lblInfo.Text += "City - " + val;
        }
}

Here, with ICallbackEventHandler, Page is NOT submitted to server and so user will experience a quick response from server (No Postback). 

4. Ajax/Jquery AND ASHX handler

ASPX Page Code:

//JQuery JS File is required.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>

<script language="javascript" type="text/javascript">

    function GetCityValue() {
        $.ajax({
            type: "POST",
            url: "AjaxHandler.ashx?method=getcity",
            dataType: "text",
            success: ReturnData2,
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                alert(textStatus);
            }
        });
    }

    function ReturnData2(data) {
        $("#div1").text(data);
    }

</script>
    <div>
<input type='button' name="btncity"  value="GetCityValue" onclick="javascript:GetCityValue()"/></div>
    <div id="div1"></div>


Codebehind Code:

First of all we need to create a Handler class file. To add http handler class file (.ashx), right click on Project Name in Solution explorer and click on Add New Item. Click on Generic Handler and click Add button. It will add .ashx file, here in our example we name it as AjaxHandler.ashx.


Now copy the below code in ProcessRequest method:


        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.QueryString["method"] == null)
                return;
            string methodname = context.Request.QueryString["method"];
            MsgResponse objResponse = new MsgResponse();
            string Returnmsg = string.Empty;
            switch (methodname)
            {
                case "getcity":
                    context.Response.ContentType = "text/plain";
                    Returnmsg = Getcity();
                    break;
            }
            context.Response.Write(Returnmsg);
        }

        private string Getcity()
        {
            return "NewJersey";
        }



Here, we pass the method name in querystring from Javascript Ajax call (url: "AjaxHandler.ashx?method=getcity",) and check that method name in ASHX handler. Finally, what we write to context.Response.Write will be send back to Javascript. Here, we can also use JSON to send objects in JSON format. 


Here, each way has its own advantage and disadvantage. In my opinion method 1 with Pagemethods is useful if you want to call codebehind method rarely. If you are calling server side functions more frequently, its better to use 4th method (Ajax and ASHX handler) to call server side function.


Happy Programming !!!

Sunday, January 29, 2012

Get Latest from TFS and Build project through batch file

Recently, We had requirement where Testing team required daily build of project for Testing. So I decided to automate the process with help of batch file.

Approach for making build process automated is to use Team Foundation Build Service. Team Foundation Build Service is a Windows service that is listed in different locations within the operating system. Where it is listed depends on whether Team Foundation Build Service is running as a Windows service or an interactive service.

For using Team Foundation build service, you need to learn about the build service, agents, and controllers. 

- One needs to configure and manage Team Foundation Build Service to enable your team to automatically and consistently build, test, and deploy your software in a distributed environment.
 

- Then need to install the build service and enable it to build projects that are under version control in team project. 

- Then create and manage build controllers, which handle requests for queued builds, and build agents, which handle the work of building, testing, and deploying your application. 


So overall approach is useful if you are developing Product with large code base and have large teams for developing different modules. Complete understanding of Team Foundation Build System on MSDN is available at

http://msdn.microsoft.com/library/dd793166%28VS.100%29.aspx

But we require something simple for our small project which creates Build for Testing Team as well as for release and I decided to make a batch file which
- Takes Latest from TFS
- Prepare build of project with MSBuild command
- Logs the error while building project
- Sends the email for success / failure.
- Then configured to run created batch file daily through Windows Task Scheduler.

Batch file works in below way:

- sets the enviornment variables so that Commands which can be run on VS Command prompt can also run from batch file with below command:


call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" (Set path based on installed VS Version)

- Get latest from TFS (Directory must be mapped with TFS)


- Get Latest operation is done through tf get command



tf get "%Solutiondir%" /force /recursive /login:Installshield,SHSH@kk5

- prepare build through msbuild command



msbuild "%Solutiondir%\WinTestApp.sln" /t:rebuild /p:Configuration=Release;Platform="x86";DefineConstants="SSWind SSAdmin SSNKDTT SSCompany10";OutDir=bin\BuildOutput\ /fileLogger /flp:logfile="%ErrLogFilePath%";errorsonly

- msbuild command sets Configuration, Platform and conditional compilation symbols
and logs the Error occurred during build process in text file

- copies all dlls / exe to specified destination directory (folder name created with DateTime format)


- Email is send to specified sender with successful or failure message


- Email send with Error Log as attachment


- Email send through Blat utility(Blat is a Win32 command line utility that sends eMail using SMTP)


Points to take care:


- Change the path of Project Directory and destination folder and also set the Email Variables (From, to, user, pwd)

- Spaces should be avoided in name of folders as spaces may create problem in batch files


- Blat official website for downloading exe and for sample examples: http://www.blat.net/


- For using Blat to send mail, download the files and copy blat.exe (and other supporting files) to some folder (say blat) and run command as below to send mail:



cd E:/tarak/blat :: move to installation folder


blat %tempmail% -to %tomail% -f %frommail% -server %serveradd% -subject "Build Exe Failed" -u %mailuser% -pw %mailpwd% -attacht D:\Projects\BuildErr\errors.txt

Batch file can be downloaded from below URL:
https://docs.google.com/open?id=0B0L2UE58PUp8YWUyNDU5NDItOTcyMC00NGVhLWEzODItMzcwZTA5YjRhYWMx

You can always send comments for any suggestions or any assistance for further enhancement.

Happy Programming !!!