Wednesday, May 21, 2014

C# Sort generic list by column name


Data in DataTable can be sorted using string column name

DataView dv = new DataView(ds.Tables[0], "","SortExpression" + " " + "SortDirection", DataViewRowState.CurrentRows);

For list we cannot pass sort expression and direction in string format. We have to find the column using reflection and then sort the column as given below

PropertyInfo pi = typeof(Employee).GetProperty("[ColumnName]");
lstData.OrderBy(i => pi.GetValue(i, null)).ToList();


Given below is an example in ASP.NET
-------------------------------------------------------------
HTML (Add inside ‘form’ tags)
    <asp:DropDownList runat="server" ID="ddlSortColumn"></asp:DropDownList>
    <asp:DropDownList runat="server" ID="ddlSortDirection">
        <asp:ListItem Text="asc"></asp:ListItem>
        <asp:ListItem Text="desc"></asp:ListItem>
    </asp:DropDownList>
    <asp:Button runat="server" ID="btnReport" Text="Report"
        onclick="btnReport_Click" />
    <br />
    <asp:GridView runat="server" ID="grvData"></asp:GridView>

C# (CodeBehind)
protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                IList<PropertyInfo> props = new List<PropertyInfo>(typeof(Employee).GetProperties());
                ddlSortColumn.DataSource = props;
                ddlSortColumn.DataTextField = "Name";
                ddlSortColumn.DataValueField = "Name";
                ddlSortColumn.DataBind();

                grvData.DataSource = GetData();
                grvData.DataBind();
            }
        }
        protected void btnReport_Click(object sender, EventArgs e)
        {
            PropertyInfo pi = typeof(Employee).GetProperty(ddlSortColumn.SelectedValue);
            if (ddlSortDirection.SelectedItem.Text == "asc")
            {
                grvData.DataSource = GetData().OrderBy(i => pi.GetValue(i, null)).ToList();
            }
            else
            {
                grvData.DataSource = GetData().OrderByDescending(i => pi.GetValue(i, null)).ToList();
            }
            grvData.DataBind();
        }
        public List<Employee> GetData()
        {
            List<Employee> employees = new List<Employee>();
            employees.Add(new Employee() { Id = 1, Name = "Employee 1", Age = 25 });
            employees.Add(new Employee() { Id = 2, Name = "Employee 2", Age = 35 });
            employees.Add(new Employee() { Id = 3, Name = "Employee 3", Age = 39 });
            return employees;
        }
        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
        }


Wednesday, February 26, 2014

How to return error messages in AJAX calls

In AJAX calls exception can occur mainly due to 1) communication error 2) server error. We will look at how to handle these exceptions

Given below is a simple AJAX application – both client code and server handler

JS Code
  <script>

        $.ajax({ url: "NewRequestHandler.aspx?val1=10&val2=11",
            success: function (data) {//Get result object from server
                alert(data.Result);
                if (data.Error!= null) {
                    alert(data.Error); //Get error returned by server
                }
            },
error: function (xhr, errorType, exception) { //Triggered by communication error, like http 404  etc
                alert(xhr.responseText);
                return false;
            }
        });

    </script>

Server Code
public class NewRequestHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            //this object will be returned in the response
            NewData data = new NewData();
            try
            {
                int val1 = Int32.Parse(context.Request.QueryString["val1"]);
                int val2 = Int32.Parse(context.Request.QueryString["val2"]);
                data.Result = val1 + val2;
            }
            catch (Exception ex)
            {
                //capture any exceptions and add it to the response object
                data.Error = ex.Message;
            }
            //convert the object to JSON and return
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            context.Response.ContentType = "text/json";
            context.Response.Write(serializer.Serialize(data));
        }
        public bool IsReusable
        {
            get { return true; }
        }
        public class NewData
        {
            public int Result;
            public string Error;
        }
    }

Any error in communicating with the server will be captured by the below line of code in JS

error: function (xhr, errorType, exception) { //Triggered by communication error, like http 404  etc

Errors occurring in server is captured by the C# and returned in the JSON object. JS code can check for this ‘error’ property to display exceptions from server

if (data.Error!= null) {
                    alert(data.Error); //Get error returned by server
                }

Tuesday, January 21, 2014

How to crawl websites in multiple languages using C#

In this article we will create a console app to crawl a webpage and read data using c#. We can use HttpWebRequest and HttpWebResponse also to get response from a webpage but I used httpagilitypack to read data in the example given below. It is much more easier to read the title, header and other html tags using htmlagility.

1)      Create a console application.

2)      Download htmlagilitypack from http://htmlagilitypack.codeplex.com/

3)      Copy htmlagility pack DLL to folder inside the project and add reference to HtmlAgilityPack.dll

4)      Next create a webclient and pass the URL to read to webclient. To read content in all languages (like Chinese, Japanese, Indonesian, Russian etc) make sure that the encoding is UTF8.

Complete code for crawling and reading data from webpage is given below

class Program
    {
        static void Main(string[] args)
        {
            WebClient webclient = new WebClient();
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.Load(webclient.OpenRead("http://deebujacob.blogspot.com/2013/03/rendering-multiple-series-in-highcharts.html"), Encoding.UTF8);

            Console.WriteLine(htmlDoc.DocumentNode.SelectSingleNode("//title").InnerText);
            Console.WriteLine(htmlDoc.DocumentNode.SelectSingleNode("//body//h1").InnerText);

            Console.ReadLine();

        }
    }


How to store different languages in SQL Server

To store different languages (like Chinese, Japanese etc)  in SQL server the data type of the column should be NVARCHAR.

Also make sure that the stored procedure used to store data also has NVARCHAR parameter. If you are using SQL statement to directly insert data into the table then use "N" before the data.

Example given below


Create table #temp(data nvarchar(100))

INSERT INTO #temp(data) values (N'ハロウィンの飾りつけになっているJVCケンウッド丸の内ショールームに行ってきました。')

SELECT * FROM #temp

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