Thursday, September 5, 2013

ASP.NET - Pass objects between server and client- using http handler, Ajax and JSON

This article shows an example of how to pass objects from client to server and from server to client. This helps to maintain state of object between server and client. Make sure you do not store sensitive data on client side.

1) Create a web application

2) Define a class in C#
   public class MyData
    {
        public int Prop1 { get; set; }
        public int Prop2 { get; set; }
        public int Result { get; set; }
    }

3) Create a web form and define Javascript class which matches C# class

MyData = function (prop1, prop2) {
            this.Prop1 = prop1,
            this.Prop2 = prop2
            this.Result = 0;
        }


4) Create request handler to handle Ajax requests

  public void ProcessRequest(HttpContext context)
        {
            string action = context.Request.QueryString["action"];
            string input;
            using (StreamReader sr = new StreamReader(context.Request.InputStream))
            {
                input = sr.ReadToEnd();
            }

            JavaScriptSerializer serializer = new JavaScriptSerializer();
            //Get object from client
            MyData data =(MyData)serializer.Deserialize(input,typeof(MyData));
            if (action == "add")
            {
                data.Result = data.Prop1 + data.Prop2;
            }
            context.Response.ContentType = "text/json";
            //Send object back to client
            context.Response.Write(serializer.Serialize(data));

        }
        public bool IsReusable
        {
            get { return true; }
        }

5) Call the server http handler from web form. Given below is the full javascript

<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script>
        MyData = function (prop1, prop2) {
            this.Prop1 = prop1,
            this.Prop2 = prop2
            this.Result = 0;
        }
        var myobject = new MyData(100, 2);

        $.ajax({ url: "RequestHandler.aspx?action=add",
            data: JSON.stringify(myobject),//Send object to server
            type: "POST",
            success: function (data) {//Get object from server
                alert(data.Result);
            }
        });

    </script>

6) Register http handler using web.config

<system.web>
    <httpHandlers>
      <add verb="GET,POST" path="RequestHandler.aspx" type="HttpHandlerTest.RequestHandler"/>
    </httpHandlers>
    <compilation debug="true"/>
  </system.web>

If you are running IIS7 you may have to register the handler as given below


<system.webServer>
 <handlers>   <add name="ajaxHandler" verb="GET,POST" path="RequestHandler.aspx" type="HttpHandlerTest.RequestHandler"/>
  </handlers>
</system.webServer>


Run the application and you can see object values being set in client side and passed to server. After server sets “Result” in object it is passed back to client.  

ASP.NET – Http handlers and AJAX

Given below is an example of implementing AJAX in asp.net using http handlers. Custom http handler with AJAX allows developers to add lot of features to classic ASP.NET application without postbacks. I personally find this way of development better than the MVC model.

Let’s implement an example. I used VS 2010 and .net 4.0
------------------------------------------------

1) Create a new web application – HttpHandlerTest

2) Create a new class file –‘RequestHandler’ . Make sure that the class implements “IHttpHandler”

    public class RequestHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            string action = context.Request.QueryString["action"];
            string input;
            using (StreamReader sr = new StreamReader(context.Request.InputStream))
            {
                input = sr.ReadToEnd();
            }
            int result = 0;
            if (action == "add")
            {
                result = Int32.Parse(input.Split(new char[] { ',' })[0]) + Int32.Parse(input.Split(new char[] { ',' })[1]);
            }
            context.Response.ContentType = "text/json";
            context.Response.Write(result.ToString());
        }
        public bool IsReusable
        {
            get { return true; }
        }
    }


3) Create an aspx page to call the handler. Enter below JS to the page. Make sure that you have reference to jQuery

  <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script>
        $.ajax({ url: "RequestHandler.aspx?action=add",
            data: "10,11",
            type: "POST",
            success: function (data) {
                alert(data);
            }
        });

    </script>


4) Register handler in web.config
<system.web>
    <httpHandlers>
      <add verb="GET,POST" path="RequestHandler.aspx" type="HttpHandlerTest.RequestHandler"/>
    </httpHandlers>
    <compilation debug="true"/>
 </system.web>

If you are running IIS7 you may have to register the handler as given below
<system.webServer>
  <handlers>
    <add name="ajaxHandler" verb="GET,POST" path="RequestHandler.aspx" type="HttpHandlerTest.RequestHandler"/>
  </handlers>

</system.webServer>



That’s it. Now run the application and you can see the result from handler as a JS alert message.
 --------------------------------
Wasn't that easy. Let me know what you think.  Not just about this article, but also about the blog if you have read the other articles I posted.


Happy coding 

Tuesday, July 9, 2013

ASP.NET - Render images dynamically with text overlay

This example shows how to render an image dynamically using aspx page with text overlay on top of it.


1) Create an aspx webform

2) Create a method as given below

public Bitmap OverlayText(Image oImage, string text)
        {
            Bitmap oBitmap = new Bitmap(oImage.Width, oImage.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            Graphics oGraphics = Graphics.FromImage(oBitmap);
            oGraphics.DrawImage(oImage, 0, 0);
            Font f = new Font(new FontFamily("Arial"), 20);
           
            SolidBrush oBrush = new SolidBrush(Color.FromArgb(255, System.Drawing.ColorTranslator.FromHtml("#000000")));

            RectangleF rect = new RectangleF(10, oImage.Height - 150, oImage.Width - 50, 100);
            StringFormat strFormat = StringFormat.GenericTypographic;

            oGraphics.DrawString(text, f, oBrush, rect, strFormat);

            oGraphics.Dispose();
            oBrush.Dispose();
            f.Dispose();

            return oBitmap;
        }



3) Call the method as given below in page_load by passing in the image object and overlay text. Make sure that you specify the virtual path of the image.

System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath("[SET PATH OF IMAGE HERE]"));
            Bitmap outputimage =OverlayText(img, overlaytext);

            using (MemoryStream ms = new MemoryStream())
            {
                outputimage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                ms.WriteTo(Response.OutputStream);
            }

            Response.ContentType = "image/png";
  

That's it. Run the app and you will see the text overlay on the image

Thursday, June 13, 2013

Parallel Task in C#

I was researching parallel task in C# and found that parallelism can be achieved in different ways, mainly by using "Task" and "Parallel" methods. But internally "parallel" uses "task" to do the process.

Anyway given below are some ways to run parallel tasks in C#

Create a class called 'Process'

public class Process1
{
    public int Add(int i, int j,int k)
    {
        return i + j + k;
    }
}


Given below are different ways to call the "Add" method in parallel

/*Parallel processing using "Task"*/
Process1 process1 = new Process1();
Task<int> task1 = Task<int>.Factory.StartNew(() => process1.Add(10, 11, 4));
Task<int> task2 = Task<int>.Factory.StartNew(() => process1.Add(29, 1, 2));
Response.Write(task1.Result.ToString() + "  " + task2.Result.ToString());


/*Parallel processing using "Parallel.ForEach"*/
List<Tuple<int, int, int>> data = new List<Tuple<int, int, int>>();//Generic list for Tuple
data.Add(new Tuple<int, int, int>(10, 11, 4));//add data to list
data.Add(new Tuple<int, int, int>(29, 1, 2));
ParallelLoopResult result = Parallel.ForEach(data, item => {//Para
int result1 = process1.Add(item.Item1, item.Item2, item.Item3);
Response.Write("Parallel result "+result1.ToString());
});


/*Parallel processing using "Parallel.Invoke"*/
Parallel.Invoke(
() => { int result1 = process1.Add(10, 11, 4); Console.Write(result1.ToString()); },
() => { int result1 = process1.Add(29, 1, 2); Console.Write(result1.ToString()); }
);

Run installations/apps remotely using Batch File


Today I had to install an app on multiple machines. So I used the below batch statement to copy and install the application to all machines without logging in to each box.

To use the below batch file you need psexec executable which can be downloaded from http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx

So how do you install apps on multiple machines without logging into each box?

1) Create test_copy.bat file with below statements. Replace [MSIFILE] with the installation file name

echo off
set arg1= %arg1%
xcopy /r /y "[MSIFILE].msi" \\"%arg1%"\e$\
psexec \\%arg1% cmd.exe /c msiexec /i e:\[MSIFILE].msi /L*v install.log /qn
del \\"%arg1%"\e$\[MSIFILE].msi
echo

2) Run "test_copy.bat" file from cmd line by specifying the machine name like "test_copy.bat -[machinename]"

That's it. You may have to provide additional parameters to "msiexec" statements to provide default installation directory etc. Also the windows user should have admin privilege on the installation box.

You can even run remote applications this way.


Thursday, March 28, 2013

How to get a website live using ASP.NET and SQL


OK, I know this is a big topic to discuss in one blog post but I want to start a post which I will update constantly as I learn and implement new ideas/concepts in developing/hosting a website. The reason why I wanted to start this post is because I created couple of websites in last few months and there were lot of interesting things that I learned. These are not really complex stuff, but more simple things like setting sitemap, robots etc.

I created a website using ASP.NET and SQL as backend. I am not going into the details of development; let me list what I had to do to deploy/host this site.

This is more like a checklist- some are minor stuff but things that really helped me to run a successful site.

1.  Website name – the first thing to do is to come up with a website name. You can check if the name is available in sites like register.com or godaddy.com

2.  Register name and set up hosting servers – Again these can be done using services provided by godaddy.com or register.com

3.  Create DB – I used SQL DB for backend. Run scripts to create tables, stored procedures and functions.

4.  Upload web application files – Upload the files of your application to the FTP server.
Make sure that pages have –
a Meaningful titles
b Meta tags with description/keywords
These are mainly for optimizing your site for search engine (SEO)

Don't forget to set a 'default' landing page for your site.

5.  Setup Email server – You need an email sever to send mails and to get mails from ‘contact us’ section of your website

6.  Track exceptions/errors – Track exceptions occurring from your site by logging in database and/or sending emails to you. Also make sure that you have a custom error page to handle all exceptions.

7.  Create a sitemap.xml – Sitemap lists the pages of your site. This will be used by crawlers

8.  Create a robots.txt – Robot file specifies which urls the crawler should exclude from crawling.

9.  User behavior/traffic -  If you want to know about the user traffic and behavior you should implement Google analytics in your site

10.  Favorite icon – Don’t forget to set an icon for your website

11.  Advertise!

I will be updating this post with more details later.

Wednesday, March 27, 2013

Auto Refresh Highcharts graph in regular intervals using ASP.NET



In last post we discussed how to render multiple series using highcharts. In this article we will look at how to refresh the chart in regular intervals. This feature can be used to refresh data in graph or to show real time data in graph using ASP.NET

We will use ‘updatepanel’ and ‘scriptmanager’ to do “AJAX” post back- so that the whole page will not be refreshed every time graph changes.

1. If have already haven’t done this- Do the steps in my previous post.

2. Add “ScriptManager” and “UpdatePanel” controls. Place the container div inside the update panel. Also add a timer inside update panel. We need timer to refresh graph in regular intervals

So controls will look like –

<asp:ScriptManager runat="server" id="scriptManager1"></asp:ScriptManager>
    <asp:UpdatePanel runat="server" ID="updatePanel1">
        <ContentTemplate>
            <!--Hidden controls for storing x and y axis data-->
            <asp:HiddenField runat="server" ID="hdnXaxis" />
            <asp:HiddenField runat="server" ID="hdnYaxis" />
            <!-- Container to render highchats graphs -->
            <div style="width:800px;height:400px;" id="container" > </div >
            <!-- Timer to refresh graph in regular intervals -->
            <asp:Timer runat="server" ID="graphRefreshTimer" Interval="5000"
                ontick="graphRefreshTimer_Tick" ></asp:Timer>
        </ContentTemplate>
    </asp:UpdatePanel>



3. In code behind page add code for timer tick event to refresh the graph

   protected void graphRefreshTimer_Tick(object sender, EventArgs e)
        {
            LoadData();
            ScriptManager.RegisterStartupScript(graphRefreshTimer, graphRefreshTimer.GetType(), "scriptname", "DrawMyGraph1();", true);
        }


That’s it! Run the app and the graph will refresh every 5 seconds without full page postback. You can change the data in ‘LoadData()’ method to show the updated data. You can connect to SQL database in the LoadData() method to show updated stats.

Rendering multiple series in Highcharts using ASP.NET


In this article we will create a web application to render multiple series using highcharts. I used visual studion 2010 for creating this app.

1) Create a ASP.NET web application

2) Get below 2 javascripts. Highcharts js can be downloaded from http://highcharts.com and latest jQuery can be downloaded from http://jquery.com/download/

a) Highcharts.js
b)  jquery-1.4.1.js

3) Create default.aspx page

4) Add references to these scripts . NOTE – add jQuery file reference before highcharts
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script src="js/highcharts.js" type="text/javascript"></script>

5) Create a class for chart series (Y-axis)
public class ChartEx
{
public string name { get; set; }
public List<int> data { get; set; }
}

6) Create 2 hidden fields in html to store X and Y axis data

<asp:HiddenField runat="server" ID="hdnXaxis" />
<asp:HiddenField runat="server" ID="hdnYaxis" />

7) Create a div for rendering graph and set id as “container”

<div style="width:900px;height:300px;" id="container" > </div >


9) Populate data for X and Y axis in page_load event in code behind. You can connect to SQL Server Database to get data in the LoadData() method.


    protected void Page_Load(object sender, EventArgs e)
        {
            LoadData();
        }

        public void LoadData()
        {
            //X axis data
            List<int> lstXaxis = new List<int>() { 9, 10, 11, 12 };
            List<ChartEx> lstseries = new List<ChartEx>();

            //Y axis - series 1
            ChartEx series1 = new ChartEx();
            series1.name = "Revenue";
            series1.data = new List<int>() { 100, 200, 150, 175 };

            //Y axis - series 2
            ChartEx series2 = new ChartEx();
            series2.name = "Profit";
            series2.data = new List<int>() { 50, 120, 80, 95 };

            //Add 2 series to list
            lstseries.Add(series1);
            lstseries.Add(series2);

            //Convert X axis data to JSON
            JavaScriptSerializer oSerializer1 = new JavaScriptSerializer();
            hdnXaxis.Value = oSerializer1.Serialize(lstXaxis);

            //Convert Y axis data to JSON
            JavaScriptSerializer oSerializer2 = new JavaScriptSerializer();
            hdnYaxis.Value = oSerializer1.Serialize(lstseries);
        }

8)  Now- the last step- copy the below javascript function to render chart

    <script type="text/javascript">
        $(document).ready(DrawMyGraph1);

        function DrawMyGraph1() {
            var xaxis = $.parseJSON($("#hdnXaxis").val());
            var series1 = $.parseJSON($("#hdnYaxis").val());
            chart = new Highcharts.Chart({
                chart: {
                    type: 'column',
                    renderTo: 'container',
                    defaultSeriesType: 'area'
                },
                title: {
                    text: 'Revenu Profit'
                },
                subtitle: {
                    text: 'revenu profit graph'
                },
                xAxis: {
                    categories: xaxis
                },
                yAxis: {
                    title: {
                        text: 'Revenue/Profit'
                    }
                },
                tooltip: {
                    formatter: function () {
                        return '$' +
Highcharts.numberFormat(this.y, 0) + ' ' + this.series.name + ' in ' + this.x + ' hour';
                    }
                },
                series: series1
            });
        }
</script>


Done ! Run the application and you can see multiple series rendered in your graph.

Let me know if this worked for you. 

Tuesday, March 19, 2013

ASP.NET UpdatePanel and Gridview


Using update panel parts of webpage can be updated without refreshing the entire page. In the below example we will check how to edit contents in a gridview without refreshing the entire page.

1)  Create an ASP.NET web application

2)  Add default.aspx page

3)  Add scriptmanager
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>


4)Add updatepanel
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    </asp:UpdatePanel>

5)Add datagrid inside the update panel
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
       <ContentTemplate>
            <asp:GridView runat="server" ID="grvEmp" AutoGenerateColumns="false"
                onrowcancelingedit="grvEmp_RowCancelingEdit" onrowediting="grvEmp_RowEditing"
                onrowupdating="grvEmp_RowUpdating">
                <Columns>
                    <asp:TemplateField>
                        <HeaderTemplate>
                            Employee Name
                        </HeaderTemplate>
                        <ItemTemplate>
                            <%# Eval("employee_name")%>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:TextBox runat="server" Text='<%# Eval("employee_name")%>' ID="txtName" ></asp:TextBox>
                        </EditItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Action">
                        <ItemTemplate>
                            <asp:Button ID="btnEdit" Text="Edit" runat="server" CommandName="Edit" /><br />
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:Button ID="btnUpdate" Text="Update" runat="server" CommandName="Update" /><br />
                            <asp:Button ID="btnCancel" Text="Cancel" runat="server" CommandName="Cancel" />
                        </EditItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
       </ContentTemplate>
    </asp:UpdatePanel>


6)Add a text box outside the update panel
<asp:TextBox runat="server" ID="txtTime"></asp:TextBox>
              
7)Create a function to return dataset to bind to datagrind
public DataSet GetEmpData()
        {
            DataSet ds = new DataSet();
            DataTable dt = new DataTable();
            dt.Columns.Add("employee_name");

            DataRow dr = dt.NewRow();
            dr[0] = "Employee 1";

            dt.Rows.Add(dr);

            ds.Tables.Add(dt);
            return ds;
        }


8) On page load set time and bind the gridview

  protected void Page_Load(object sender, EventArgs e)
        {
            txtTime.Text = DateTime.Now.ToString();
            if (!IsPostBack)
            {
                grvEmp.DataSource = GetEmpData();
                grvEmp.DataBind();
            }
        }

9)Handle the row edit,update and cancel events
  protected void grvEmp_RowEditing(object sender, GridViewEditEventArgs e)
        {
            grvEmp.EditIndex = e.NewEditIndex;
            grvEmp.DataSource = GetEmpData();
            grvEmp.DataBind();
        }

        protected void grvEmp_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {

        }
   

        protected void grvEmp_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        {
            grvEmp.EditIndex = -1;
            grvEmp.DataSource = GetEmpData();
            grvEmp.DataBind();
        }


And we are done. Run the application and click on edit button on the gridview. You can see that only the grid is refreshed, time on the text box on main page does not change.