Developing a REST Web Service using C# - A walkthrough

REST stands for Representational State Transfer. The term was introduced by Roy Fielding in his doctorial dissertation. REST is an architectural style for designing networked applications. It is an alternate to using complex mechanisms like COBRA, RPC, and SOAP to connect between client and server. REST makes communication between remote computers easy by using the simple HTTP protocol which support for CRUD (Create, Read, Update, and Delete) operations on the server. In a way, our World Wide Web is also based on the REST architecture.

In a nutshell, REST is based on the representation of resources. A resource is an object that we can access over the World Wide Web. It can be a document, an image, or anything. When we request a resource (an object) from a server, the server returns the representation of that resource. In REST architecture, a client requests an operation (CRUD) on an object (resource) on the server, and the server returns data as per requirements.

Example – Let us consider a Web Service that returns Employee information. The Web Service responds to client calls by polling a database and returning a result. In classical Web Services or WCF Services, we would have a method exposed to clients, like GetEmployee(). The REST architecture is different from this as it does not work with the methods but with nouns (resources / objects) and allow verbs (HTTP Methods) to operate on them.

So if we want to get Employee information, we send an HTTP GET on the object Employee rather than query a method like GetEmployee(). The advantage is manifold, the most important being the power and flexibility that we get in our hands to play around with the object.

For further reading, see the References section at the end of the article. I will not go into the details of explaining REST, rather concentrate on how to code one from scratch.

Why use REST?

Let us consider a practical example. Imagine that you have to build a Web Service which should be cross functional and should be able to be consumed by any client. Traditional Web Services in .NET have to be consumed using a proxy. What if the client does not know how to create a proxy? Imagine that your Web Service needs to be consumed by a client running on an iPhone or Android. As far as I know, Objective C does not know how to create a proxy. It only knows to send basic HTTP verbs – GET, PUT, POST, and DELETE – to the server and expect XML or string as response. Enter the world of REST!!

 

HTTP verbs

At this time, it is worthwhile to revise our basic HTTP verbs. I will just give a brief introduction. Detailed information is easily available over the internet.

GET – GET is one of the simplest HTTP methods. Its main job is to ask the server for a resource. That resource may be an HTML page, a sound file, a picture file (JPEG) etc. We can say that GET method is for getting something from the server. In GET method, the data we send is appended to the URL.

Example:

GET /path/file.html HTTP/1.0
From: someuser@jmarshall.com
User-Agent: HTTPTool/1.0

POST – The POST method is used to submit data to be processed to the identified resource. The data is included in the body of the request. This may result in the creation of a new resource, or the updates of existing resources, or both.

Example:

POST /path/script.cgi HTTP/1.0
From: frog@jmarshall.com
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

home=Cosby&favorite+flavor=flies

PUT – The PUT method is used to submit data to be updated to the identified resource. Like the POST method, the data is included in the body of the request.

DELETE - The DELETE method is used to delete a specific resource.

 

HTTP handlers

We will be making use of HTTP handlers to configure our REST Web Service. HTTP handlers give us the power to configure our own web extensions by configuring the ISAPI filters in IIS. To explain briefly, the following happens under the hood:

IIS listens for any incoming requests on port 80 (default). When it receives a request for a web page, it invokes a web application. This routing of this request to the web application is done via ISAPI filters. For example, if it receives a request for a page called Default.aspx, a DLL called aspnet_isapi.dll actually goes and invokes the page Default.aspx. The Machine.Config file will have the mapping which will tell IIS how to handle a .aspx web request. Users can have their own calls – like .codeproject – by configuring the ISAPI filters of IIS. This is done through HTTP handlers. So, if I want to make a call, say, Default.codeproject, instead of Default.aspx, it would have to be done through HTTP handlers. More information about this can be found in the References section of this article. HTTP handlers is the key to build REST Web Services. We will see later how our Employee object will be exposed using HTTP handlers.

 

The project

To understand REST, let’s dig into a sample project and see what is happening under the hood. The project involves building a sample client – server database application which returns employee information. From the definition of REST above, we can conclude the following:

  1. The resource here will be the employee (object) which will be exposed to the client.
  2. The client should be able to perform CRUD operations (basic HTTP verbs) on the resource.

We have to design a system which will accomplish the above tasks. The project can be divided into the following:

  1. Create a simple database which contains an Employee table.
  2. Create a simple Employee class as a placeholder for the database employee information.
  3. Code basic database operations like Read, Update, Delete, Insert for Employee.
  4. Create a REST Web Service by exposing Employee to HTTP verbs.
  5. Deploy the application.
  6. Test the application.

It is time to define the way the client will be communicating with the server. The data exchange happens through XML format as it is widely accepted across all platforms.

  1. Get information about an employee – HTTP GET method. The server expects an HTTP GET method with the employee code passed in the query string. It then returns the employee information for that particular employee from the database in the form of XML.

    Example: http://localhost/RestWebService/employee?id=3550.

  2. Insert a new employee – HTTP POST method. The server expects an HTTP POST method to create a new employee. The client is required to pass the employee information as XML in the message body. The server then reads the message body and creates a new employee information in the database.

    Example - POST/employeeHTTP/1.1 Host: http://localhost/RestWebService

  3. Update an existing employee – HTTP PUT method. The server expects an HTTP PUT method to update an existing employee. The client is required to pass the information for the employee who is getting updated as XML in the message body. The server then reads the message body and updates the particular employee in the database.

  4. Delete an existing employee – HTTP DELETE method. The server expects an HTTP DELETE method to delete a particular employee from the database. The server expects the employee code for the employee to be deleted, in the query string of the URL.

    Example: http://localhost/RestWebService/employee?id=3550.

Thus we can see that by the above design, we have successfully exposed a state of an object – in this case, Employee – to the client applications calling it. As mentioned above, the objective of REST is to make the HTTP verbs operate on the nouns. The HTTP verbs here are GET, POST, PUT, and DELETE (CRUD), as explained above. The noun here is the resource Employee. If we can achieve this, we would have created a basic REST Web Service.

The code

Part # 1 - Create a simple database which contains an Employee table

This one is easy. You have to create a simple database called Company and create a table called Employee, as shown above. In the source code provided, I have included the scripts necessary to create a database and also create an Employee table. I have also provided scripts to insert some dummy data to get us started. Please look in the EmployeeDataBase project under the script folder. All you need to do is copy and run the scripts, and you should be all set.

Note: This will work with SQL Server 2008. You have to make adjustments if you are using any other version of SQL Server or any other database.

Let us also see the structure of the table that will hold the employee information. Below is the snapshot.

image001

Part # 2 – Create an Employee class as a placeholder for the database employee information

I have this in a class library project called Company. I have a class Employee which has the following properties:

  • FirstName
  • LastName
  • EmpCode
  • Designation

Let us see the structure of the Employee class:

<Employee>
<FirstName>Anshu</FirstName>
<LastName>Dutta</LastName>
<EmpCode>3550</EmpCode>
<Designation>SSE</Designation>
</Employee>

The XML is quite self explanatory. It has these attributes: first name, last name, employee code, and designation.


Refer the code below. The code again is self explanatory. We have defined the public properties of the class:

public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
public int EmpCode
{
get { return _empCode; }
set { _empCode = value; }
}
public string Designation
{
get { return _designation; }
set {_designation = value;}
}
public string getEmployeeName()
{
string fullName = FirstName + ‘ ‘ + LastName;
return fullName;
}

Part # 3 - Code basic database operations like Read, Update, Delete, Insert for Employee

This one includes coding of basic database operations namely – Update, Insert, Select, Delete.


I have a Data Access Layer specifically for this. It is called DAL, and it is again a set of class libraries. It has a class DAL which has the code for the database operations.


The constructor of the class takes the connection string and connects to the database.

public DAL(string _connString)
{
err = new ErrorHandler.ErrorHandler();
connString = _connString;
}

Database operations


I have used parameterized queries in all the cases as they are efficient.


Code for Insert operation:

try
{
using (conn)
{
//using parametirized query
string sqlInserString =
"INSERT INTO Employee (FirstName, LastName, ID, " +
"Designation) VALUES (@firstName, @lastName, @ID, @designation)";

conn = new SqlConnection(connString);

command = new SqlCommand();
command.Connection = conn;
command.Connection.Open();
command.CommandText = sqlInserString;

SqlParameter firstNameparam = new SqlParameter("@firstName", emp.FirstName);
SqlParameter lastNameparam = new SqlParameter("@lastName", emp.LastName);
SqlParameter IDparam = new SqlParameter("@ID", emp.EmpCode);
SqlParameter designationParam = new SqlParameter("@designation", emp.Designation);

command.Parameters.AddRange(new SqlParameter[]{
firstNameparam,lastNameparam,IDparam,designationParam});
command.ExecuteNonQuery();
command.Connection.Close();
}
}
catch (Exception ex)
{
err.ErrorMessage = ex.Message.ToString();
throw;
}

I have a query string which takes a parameterized query. For the insert statement, the parameters are first name, last name, employee code, and designation. I am then declaring SQL parameters for these and adding them to the command parameter collection. Then I execute the command using command.ExecuteNonQuery().


Other operations like Update, Delete, and Select are similar. For the Select operation, the method GetEmployees() returns an Employee class.


One thing that is worth mentioning is that the DAL class has a method called GetException(). This method passes on whatever exception that the method encounters to the calling client. I will explain the importance of this method in subsequent stages.

public string GetException()
{
return err.ErrorMessage.ToString();
}

Part # 4 - Create the REST Web Service

Now that we have set up the foundation for our Web Service, let’s dig deep into the code that actually implements the REST architecture. As explained earlier, REST is about exposing nouns (objects) to verbs. Any normal request to an ASP.NET Web Server looks like this: http://localhost/myWbPage.aspx.


Remember here, we want to expose the object Employee and not the page. Note that the operation can also be achieved by calling a .aspx web page through the client and then redirecting it to perform the CRUD operations. But this is not what REST is about. We have to expose the object Employee to the calling client and not the .aspx web page. How can this be achieved? Enter HTTP handlers!!


We would have to configure IIS to handle the employee web request. Let us create an HTTP handler for this. Refer the Service class in the RestWebService project. The class implements the IHTTPHandler interface.

public class Service:IHttpHandler

This interface implements the following two methods:



  • bool IHttpHandler.IsReusable

    This property is called to determine whether this instance of the HTTP handler can be reused for fulfilling other requests of the same type. HTTP handlers can return either true or false in order to specify whether they can be reused.


  • void IHttpHandler.ProcessRequest(HttpContext context)

    For the time being, we will concentrate on the ProcessRequest() method. This is the method which gets invoked when IIS invokes the ISAPI filter after receiving the client request. This can be considered as the entry point of any application using HTTP handlers. The crux of the code lies here.


The first thing that we have to do is decide what kind of request has come to us and act accordingly. We will do the following:



  1. GET method – READ database for employee information
  2. PUT method – UPDATE database
  3. POST method – INSERT database
  4. DELETE method – DELETE database

The HTTPContext class has Request and Response objects. The code below uses them:

//Handling CRUD
switch (context.Request.HttpMethod)
{
case "GET":
//Perform READ Operation
READ(context);
break;
case "POST":
//Perform CREATE Operation
CREATE(context);
break;
case "PUT":
//Perform UPDATE Operation
UPDATE(context);
break;
case "DELETE":
//Perform DELETE Operation
DELETE(context);
break;
default:
break;
}

READ() method



  1. Get the employee code from the query string of the URL.
  2. Poll the database for that particular employee using the Data Access Layer discussed above.
  3. Serialize the Employee class into XML and write to the Response object.
int employeeCode = Convert.ToInt16(context.Request["id"]);

emp = dal.GetEmployee(employeeCode);
if (emp==null)
context.Response.Write(employeeCode + "No Employee Found");

string serializedEmployee = Serialize(emp);
context.Response.ContentType = "text/xml";
WriteResponse(serializedEmployee);

CREATE() method



  1. Extract the Employee class from the message body of the POST request. This is done by using the BinaryRead() method of the Request class which reads the message body as bytes.
  2. Deserialize employee information from bytes[] to the Employee class.
  3. Perform an Insert operation in the database using the Data Access Layer.
// Extract the content of the Request and make a employee class
// The message body is posted as bytes. read the bytes
byte[] PostData = context.Request.BinaryRead(context.Request.ContentLength);
//Convert the bytes to string using Encoding class
string str = Encoding.UTF8.GetString(PostData);
// deserialize xml into employee class
Company.Employee emp = Deserialize(PostData);
// Insert data in database
dal.AddEmployee(emp);

UPDATE() method



  1. Extract the Employee class from the message body of the PUT request. This is done by using the BinaryRead() method of the Request class which reads the message body as bytes.
  2. Deserialize employee information from bytes[] to the Employee class.
  3. Perform the Update operation in the database using the Data Access Layer.
byte[] PUTRequestByte = context.Request.BinaryRead(context.Request.ContentLength);
context.Response.Write(PUTRequestByte);

// Deserialize Employee
Company.Employee emp = Deserialize(PUTRequestByte);
dal.UpdateEmployee(emp);

DELETE() method



  1. Get the employee code from the query string of the URL.
  2. Perform the Delete operation in the database.
int EmpCode = Convert.ToInt16(context.Request["id"]);
dal.DeleteEmployee(EmpCode);
WriteResponse("Employee Deleted Successfully");

The Service class has association with the DAL class to handle database operations. I have the connection string stored in the project properties, and access it through the following line of code:

connString = Properties.Settings.Default.ConnectionString;

Also, I will briefly explain the methods responsible for XML serialization and deserialization.


The Serialize() method takes care of XML serialization. It uses the XmlSerializer class that uses the Serialize() method to write the XML into a memory stream. It then returns the XML Employee in a string using the ToArray() method of the memory stream. Refer the code below:

private String Serialize(Company.Employee emp)
{
try
{
String XmlizedString = null;
XmlSerializer xs = new XmlSerializer(typeof(Company.Employee));
//create an instance of the MemoryStream class since we intend to keep the XML string
//in memory instead of saving it to a file.
MemoryStream memoryStream = new MemoryStream();
//XmlTextWriter - fast, non-cached, forward-only way of generating streams or files
//containing XML data
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
//Serialize emp in the xmlTextWriter
xs.Serialize(xmlTextWriter, emp);
//Get the BaseStream of the xmlTextWriter in the Memory Stream
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
//Convert to array
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
return XmlizedString;
}
catch (Exception ex)
{
errHandler.ErrorMessage = ex.Message.ToString();
throw;
}
}

The Deserialize() method takes care of the deserialization. It accepts employee information as a byte array, uses the XmlSerializer class to deserialize it, and returns an Employee object.

private Company.Employee Deserialize(byte[] xmlByteData)
{
try
{
XmlSerializer ds = new XmlSerializer(typeof(Company.Employee));
MemoryStream memoryStream = new MemoryStream(xmlByteData);
Company.Employee emp = new Company.Employee();
emp = (Company.Employee)ds.Deserialize(memoryStream);
return emp;
}
catch (Exception ex)
{
errHandler.ErrorMessage = dal.GetException();
errHandler.ErrorMessage = ex.Message.ToString();
throw;
}
}

Exception handling


Handling and detecting errors can be a challenge as everything in the Web Service will happen behind the scenes. There is no way to debug the code using break points. I have used a project library called ErrorHandler which has a class called ErrorHandler:

public class ErrorHandler
{
static StringBuilder errMessage = new StringBuilder();

static ErrorHandler()
{
}
public string ErrorMessage
{
get {return errMessage.ToString();}
set
{
errMessage.AppendLine(value);
}
}
}

It has a public property which stores error messages and returns when called upon. Whenever an exception occurs, the error message property is set to the exception message. Being a StringBuilder, it can store error messages at various levels. Finally, this can be called at the final level to get all the error messages encountered in the code.


Another way of doing it will be to use Trace and Listeners. You can trace the flow of the code and log it in an XML or text file.

catch (Exception ex)
{
errHandler.ErrorMessage = dal.GetException();
errHandler.ErrorMessage = ex.Message.ToString();
}

Part # 5 - Deploying the application

Now that the code is in place, let’s talk about deploying the application. I have used IIS 7.5 in Windows 7. If you are using other versions, please make adjustments accordingly.



  1. Create a virtual directory in the root directory of your Default Web site. Convert this into a web application. In IIS 7.5, right click on the virtual directory in inetmgr and select “Convert To Application”.

    Example: C:\inetpub\wwwroot\RestWebService.


  2. Create a Bin folder inside your virtual directory so that it looks like this: C:\inetPub\wwwroot\RestWebService\Bin.
  3. Compile your application and place the DLLs in the Bin folder. You should have three DLLs:

    1. Company.dll – Employee class
    2. DAL.dll – Data Access Layer
    3. RestWebService.dll – REST Web Service

  4. Place a Web.config file in the root directory of your Web site, i.e., in the RestWebService folder:
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.web>
    <httpHandlers>
    <add type="RestWebService.Service, RestWebService" verb="*" path="employee" />
    </httpHandlers>
    </system.web>
    <system.webServer>
    <handlers>
    <add name="employee" path="employee" verb="*" modules="IsapiModule"
    scriptProcessor="C:\Windows\Microsoft.NET\Framework\
    v2.0.50727\aspnet_isapi.dll"

    resourceType="Unspecified" requireAccess="Script"
    preCondition="classicMode,runtimeVersionv2.0,bitness32" />
    </handlers>
    <directoryBrowse enabled="false" />
    </system.webServer>
    </configuration>

    In the httpHandler section:



    1. type represents the fully qualified class name – RestWebService.Service and the assembly name RestWebService.dll – Namespace.Class, Assembly.
    2. verb represents the HTTP verbs allowed on the service. * specifies all verbs are allowed.
    3. path – This is where we are exposing our employee object. The path specifies the call that IIS is going to handle for this application. In other words, any request with employee will be directed to our RestWebService.dll.

    In the handlers secttion, we are mapping a DLL (aspnet_isapi.dll) which will do the above work.


    This can be done through inetmgr also, as follows:



    1. In inetmgr, select your directory and double click on Handler Mapping.
    2. Click “Add Script Map” and do the following:

      image002


    3. You should have the HTTP Handler mapped:

      image003


  5. To test whether everything works fine, insert some data in the database and type the following in your web browser: http://localhost/RestWebService/employee?id=3550. If you have an employee with code = 3550, you will see the following:

    image004


    Note: For issues related to deployment, please see the References section at the end of the article.


Part # 6 - Testing the application

The GET method can be tested through the browser, but to test the other HTTP methods, we have to write our own code. I have created a console application called TestHarness for this.


Note that this application also performs testing for various parts of the project. I have written code to test the database operations to check that my Data Access Layer works fine.


I will explain the testing of the GET, POST, PUT, and DELETE methods below:



  1. GenerateGetRequest() – Testing the GET method.

    1. Use HTTPWEbRequest.Create(Url) to create an instance of HTTPWebRequest.
    2. Set the Method property to GE,T and use the GetResponse() method to receive the response stream from the server.
    3. Print the result in the console to check the result:
      string url = "http://localhost/RestWebService/employee?id=3550";
      HttpWebRequest GETRequest = (HttpWebRequest)WebRequest.Create(url);
      GETRequest.Method = "GET";

      Console.WriteLine("Sending GET Request");
      HttpWebResponse GETResponse = (HttpWebResponse)GETRequest.GetResponse();
      Stream GETResponseStream = GETResponse.GetResponseStream();
      StreamReader sr = new StreamReader(GETResponseStream);

      Console.WriteLine("Response from Server");
      Console.WriteLine(sr.ReadToEnd());

  2. GeneratePOSTRequest() – Testing the POST method.

    1. Create the message body. The message body should contain the Employee class XML serialized. I am using a method GenerateXMLEmployee() which creates a stream of bytes containing the employee information. I am using XmlTextWriter to create the XML in a memory stream and return a byte array from that stream.
      private static byte[] GenerateXMLEmployee(string strFirstName, 
      string strLastName, int intEmpCode, string strDesignation)
      {
      // Create the xml document in a memory stream - Recommended
      MemoryStream mStream = new MemoryStream();
      //XmlTextWriter xmlWriter =
      // new XmlTextWriter(@"C:\Employee.xml", Encoding.UTF8);
      XmlTextWriter xmlWriter = new XmlTextWriter(mStream, Encoding.UTF8);
      xmlWriter.Formatting = Formatting.Indented;
      xmlWriter.WriteStartDocument();
      xmlWriter.WriteStartElement("Employee");
      xmlWriter.WriteStartElement("FirstName");
      xmlWriter.WriteString(strFirstName);
      xmlWriter.WriteEndElement();
      xmlWriter.WriteStartElement("LastName");
      xmlWriter.WriteString(strLastName);
      xmlWriter.WriteEndElement();
      xmlWriter.WriteStartElement("EmpCode");
      xmlWriter.WriteValue(intEmpCode);
      xmlWriter.WriteEndElement();
      xmlWriter.WriteStartElement("Designation");
      xmlWriter.WriteString(strDesignation);
      xmlWriter.WriteEndElement();
      xmlWriter.WriteEndElement();
      xmlWriter.WriteEndDocument();
      xmlWriter.Flush();
      xmlWriter.Close();
      return mStream.ToArray();
      }

    2. Once the message body is created (employee information in byte array), we can create the POST request in the same way. The only addition is that we have to write the data bytes in the stream of the request object and get the server response. See the code below:
      string strURL = "http://localhost/RestWebService/employee";
      byte[] dataByte =
      GenerateXMLEmployee(strFirstName,strLastName,EmpCode,strDesignation);

      HttpWebRequest POSTRequest = (HttpWebRequest)WebRequest.Create(strURL);
      //Method type
      POSTRequest.Method = "POST";
      // Data type - message body coming in xml
      POSTRequest.ContentType = "text/xml";
      POSTRequest.KeepAlive = false;
      POSTRequest.Timeout = 5000;
      //Content length of message body
      POSTRequest.ContentLength = dataByte.Length;

      // Get the request stream
      Stream POSTstream = POSTRequest.GetRequestStream();
      // Write the data bytes in the request stream
      POSTstream.Write(dataByte, 0, dataByte.Length);

      //Get response from server
      HttpWebResponse POSTResponse = (HttpWebResponse)POSTRequest.GetResponse();
      StreamReader reader =
      new StreamReader(POSTResponse.GetResponseStream(),Encoding.UTF8) ;
      Console.WriteLine("Response");
      Console.WriteLine(reader.ReadToEnd().ToString());

  3. GeneratePUTRequest() – Testing the PUT method.

    This is the same as the POST request. The employee information sent as XML here is an existing employee rather than a new one.


  4. GenerateDELETERequest() – Testing the Delete method.

    This is the same as the POST method as explained above.

C# Extension Method

An extension method has simplified calling syntax. It represents static methods as instance methods. An extension method uses the this-keyword in its parameter list. It must be located in a static class.

extension

Example

First, here is a custom extension method defined in a program written in the C# language. Generally, you will want to store your extension method class in a separate source file, such as "ExtensionMethods.cs" in your project.

Note:This file should store a static class with public static extension methods.

Then: In the rest of your source code, you can invoke these extension methods in the same way as instance methods.

using System;

public static class ExtensionMethods
{
    public static string UppercaseFirstLetter(this string value)
    {
    //
    // Uppercase the first letter in the string this extension is called on.
    //
    if (value.Length > 0)
    {
        char[] array = value.ToCharArray();
        array[0] = char.ToUpper(array[0]);
        return new string(array);
    }
    return value;
    }
}

class Program
{
    static void Main()
    {
    //
    // Use the string extension method on this value.
    //
    string value = "dot net perls";
    value = value.UppercaseFirstLetter(); // Called like an instance method.
    Console.WriteLine(value);
    }
}

In the first part of the program, you can see an extension method declaration in the C# programming language. An extension method must be static and can be public so you can use it anywhere in your source code.

Tip: the extension method is called like an instance method, but is actually a static method. The instance pointer "this" is a parameter.

And: you must specify the this-keyword before the appropriate parameter you want the method to be called upon.

The only difference in the declaration between a regular static method and an extension method is the "this" keyword in the parameter list. If you want the method to receive other parameters, you can include those at the end.

You can call an extension method in the same way you call an instance method. In Visual Studio, an extension method in IntelliSense has a downward arrow on it. This is a visual clue to how methods are represented.

How create a OFT file for HTML?

OFT file is a Outlook Template of an email. If you need to send a newsletter for example, it’s very useful to create this kind of file.

The procedure to make a OFT file is very simple:

  1. build html file
  2. open the file in Internet Exlorer
  3. in IE open the menu (don’t use the icon!) File | Send | Page by e-mail
  4. Outlook opens a new email with the page
  5. click on File | Save As, click dropdown and select Outlook Template (*.oft), save to desired location

Reading multiple excel sheets with different worksheet names

I would like to know how I can read multiple excel worksheet with different worksheet name in c# and with the used of oledb.

I have this existing way to read multiple sheets (but with fixed worksheet name):

            DataSet ds = new DataSet();
            var excelConnectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Excel 8.0", path);
            OleDbConnection connection = new OleDbConnection();
            connection.ConnectionString = excelConnectionString;

            var i = 1;
            while (i <= 4)
            {
                string query = "SELECT * FROM [Sheet" + i + "$]";
                ds.Clear();
                OleDbDataAdapter data = new OleDbDataAdapter(query, connection);
                data.Fill(ds);

                // other stuff
                i = i + 1;
            }

Elegant solutions is:

static DataTable GetSchemaTable(string connectionString)
{
using (OleDbConnection connection = new
OleDbConnection(connectionString))
{
connection.Open();
DataTable schemaTable = connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
new object[] { null, null, null, "TABLE" });
return schemaTable;
}
}

Your code would change to:

DataSet ds = new DataSet();
var excelConnectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Excel 8.0", path);
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = excelConnectionString;

DataTable sheets = GetSchemaTable(excelConnectionString);

foreach (dataRow r in sheets.rows)
{
string query = "SELECT * FROM [" + r.Item(0).ToString + "]";
ds.Clear();
OleDbDataAdapter data = new OleDbDataAdapter(query, connection);
data.Fill(ds);

}

Download page from web with encoding

Usually you can use WebClient to download a page from web but no always it’s a good way, sometimes the page encode is different. With this code you can download without problems!

#region " Download page "
public static string PageDownload(string url)
{
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

    using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
    {
        byte[] buffer;

        using (Stream s = resp.GetResponseStream())
        {
            buffer = ReadStream(s);
        }

        string pageEncoding = "";
        Encoding e = Encoding.UTF8;
        if (resp.ContentEncoding != "")
            pageEncoding = resp.ContentEncoding;
        else if (resp.CharacterSet != "")
            pageEncoding = resp.CharacterSet;
        else if (resp.ContentType != "")
            pageEncoding = GetCharacterSet(resp.ContentType);

        if (pageEncoding == "")
            pageEncoding = GetCharacterSet(buffer);

        if (pageEncoding != "")
        {
            try
            {
                e = Encoding.GetEncoding(pageEncoding);
            }
            catch
            {
                MessageBox.Show("Invalid encoding: " + pageEncoding);
            }
        }

        string data = e.GetString(buffer);

        string Status = "";

        return data;
    }
}

private static string GetCharacterSet(string s)
{
    s = s.ToUpper();
    int start = s.LastIndexOf("CHARSET");
    if (start == -1)
        return "";

    start = s.IndexOf("=", start);
    if (start == -1)
        return "";

    start++;
    s = s.Substring(start).Trim();
    int end = s.Length;

    int i = s.IndexOf(";");
    if (i != -1)
        end = i;
    i = s.IndexOf("\"");
    if (i != -1 && i < end)
        end = i;
    i = s.IndexOf("'");
    if (i != -1 && i < end)
        end = i;
    i = s.IndexOf("/");
    if (i != -1 && i < end)
        end = i;

    return s.Substring(0, end).Trim();
}

private static string GetCharacterSet(byte[] data)
{
    string s = Encoding.Default.GetString(data);
    return GetCharacterSet(s);
}

private static byte[] ReadStream(Stream s)
{
    long CurLength;
    try
    {
        byte[] buffer = new byte[8096];
        using (MemoryStream ms = new MemoryStream())
        {
            while (true)
            {
                int read = s.Read(buffer, 0, buffer.Length);
                if (read <= 0)
                {
                    CurLength = 0;
                    return ms.ToArray();
                }
                ms.Write(buffer, 0, read);
                CurLength = ms.Length;
            }
        }
    }
    catch (Exception ex)
    {
        return null;
    }
}
#endregion

What is the JavaScript Equivalent of print_r in PHP?

What is the JavaScript Equivalent of PHP print_r() function? In other words, how you can "print" a javascript object in a way that's readable by humans?

Code

You could use JSON.stringify, as following:

The HTML part

Let's create two links for demo:

<p><a id="print_demo" href="javascript:void(0);">Print object</a></p>

<p><a id="pretty_print_demo" href="javascript:void(0);">Pretty Print object</a>

The JAVASCRIPT part


Remark: I use jQuery to handle events, but you can use plain javascript (if you prefer).

<script type="text/javascript">

$(function() {

// create an object
var person = new Object();
person.firstname = "John";
person.lastname = "Doe";
person.age = "35";

// plain print
$("#print_demo").click(function() {
alert(JSON.stringify(person));
});

// pretty print
$("#pretty_print_demo").click(function() {
alert(JSON.stringify(person, null, ' '));
});

});

</script>

How to Detect Browser (and browser version) using JavaScript

Browser (and browser version) detection is an "all time classic" development requirement. jQuery.browser WAS an excellent solution, but it was removed in jQuery 1.9.

Actually, it would be better to try to detect a browser feature instead of browser name itself, where possible. An ideal solution for this is Modernizr (a JavaScript library that detects HTML5 and CSS3 features in the user’s browser).

But, if you still need to detect browser and browser version (using javascript), I suggest the following solutions (among many others): Bowser - A Browser detector and Browser detect provided by quirksmode. I prefer the first one.

Bowser - A Browser detector

Get bowser from https://github.com/ded/bowser. Add it to your document with something like this (change /url/to/... with the real url):

<script type="text/javascript" src="/url/to/bowser.min.js"></script>

Code


The HTML part


Let's create these links for demo:

<p>
Click to <a id="detect_browser"
href="javascript:void(0);">Detect browser properties</a>
</p>

<p>
Click to <a id="detect_version"
href="javascript:void(0);">Detect browser version</a>
</p>

The JAVASCRIPT part


Remark: I use jQuery to handle events, but you can use plain javascript (if you prefer).

<script type="text/javascript">

$(function() {

// detect browser properties
$("#detect_browser").click(function() {
alert(JSON.stringify(bowser, null, ' '));
});

// detect browser version
$("#detect_version").click(function() {
alert(bowser.version);
});

});

</script>

If you need help on JSON.stringify, read this post.


References


Suggested javascript solutions for browser detection



From jQuery docs



Browser Feature detection solutions


Render LocalReport using Microsoft ReportViewer DLL Version 11.0.3366.16

I downloaded the latest Microsoft ReportViewer from the link below and installed it. I want to be able to export (render) my Excel files in xlsx format. I'm referencing version 11.0.3366.16 of the following dll's in my project...

Microsoft.ReportViewer.Common
Microsoft.ReportViewer.ProcessingObjectModel
Microsoft.ReportViewer.WinForms

The download link
http://www.microsoft.com/en-us/download/details.aspx?id=35747

When specifying what you want your output to be, instead of sending WORD and EXCEL as the parameters for the output, send WORDOPENXML and EXCELOPENXML for the new office version.

To verify what output your version of assemblies support, use

<ReportObjec>.LocalReport.ListRenderingExtensions

For example:
RenderingExtension[] r = reportViewer.LocalReport.ListRenderingExtensions();

The complete list is:

  • Image (Tiff)
  • PDF
  • Excel 2003
  • Excel 2007-2010
  • Word
  • Word 2007-2010

Mime type for Microsoft Office 2007-2010

.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.xltx application/vnd.openxmlformats-officedocument.spreadsheetml.template
.potx application/vnd.openxmlformats-officedocument.presentationml.template
.ppsx application/vnd.openxmlformats-officedocument.presentationml.slideshow
.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
.sldx application/vnd.openxmlformats-officedocument.presentationml.slide
.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
.dotx application/vnd.openxmlformats-officedocument.wordprocessingml.template
.xlam application/vnd.ms-excel.addin.macroEnabled.12
.xlsb application/vnd.ms-excel.sheet.binary.macroEnabled.12

[A]System.Web.WebPages.Razor.Configuration.HostSection cannot be cast to… web.config issue

I have a problem like this on server

[A]System.Web.WebPages.Razor.Configuration.HostSection cannot be cast to [B]System.Web.WebPages.Razor.Configuration.HostSection. Type A originates from 'System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_2.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll'. Type B originates from 'System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_1.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidCastException: [A]System.Web.WebPages.Razor.Configuration.HostSection cannot be cast to [B]System.Web.WebPages.Razor.Configuration.HostSection. Type A originates from 'System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_2.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll'. Type B originates from 'System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_1.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll'.

Solution

  1. Backup your project. This walkthrough will require you to make changes  to your project file, package configuration, and web.config files.
  2. For upgrading from Web API to Web API 2, in global.asax, change:
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    to
    GlobalConfiguration.Configure(WebApiConfig.Register);

  3. Make sure all the packages that your projects use are compatible with  MVC 5 and Web API 2. The following table shows the MVC 4 and Web API related  packages than need to be changed. If you have a package that is dependent on  one of the packages listed below, please contact the publishers to get the  newer versions that are compatible with MVC 5 and Web API 2. If you have the  source code for those packages, you should recompile them with the new  assemblies of MVC 5 and Web API 2.




























































































    Package Id                                           


    Old version


    New version


    Microsoft.AspNet.Razor


    2.0.x.x


    3.0.0


    Microsoft.AspNet.WebPages


    2.0.x.x


    3.0.0


    Microsoft.AspNet.WebPages.WebData


    2.0.x.x


    3.0.0


    Microsoft.AspNet.WebPages.OAuth


    2.0.x.x


    3.0.0


    Microsoft.AspNet.Mvc


    4.0.x.x


    5.0.0


    Microsoft.AspNet.Mvc.Facebook


    4.0.x.x


    5.0.0


    Microsoft.AspNet.WebApi.Core


    4.0.x.x


    5.0.0


    Microsoft.AspNet.WebApi.SelfHost


    4.0.x.x


    5.0.0


    Microsoft.AspNet.WebApi.Client


    4.0.x.x


    5.0.0


    Microsoft.AspNet.WebApi.OData


    4.0.x.x


    5.0.0


    Microsoft.AspNet.WebApi


    4.0.x.x


    5.0.0


    Microsoft.AspNet.WebApi.WebHost


    4.0.x.x


    5.0.0


    Microsoft.AspNet.WebApi.Tracing


    4.0.x.x


    5.0.0


    Microsoft.AspNet.WebApi.HelpPage


    4.0.x.x


    5.0.0


    Microsoft.Net.Http


    2.0.x.


    2.2.x.


    Microsoft.Data.OData


    5.2.x


    5.6.x


    System.Spatial


    5.2.x


    5.6.x


    Microsoft.Data.Edm


    5.2.x


    5.6.x


    Microsoft.AspNet.Mvc.FixedDisplayModes


     


    Removed


    Microsoft.AspNet.WebPages.Administration


     


    Removed


    Microsoft-Web-Helpers


     


    Microsoft.AspNet.WebHelpers



    Note: Microsoft-Web-Helpers has been replaced  with Microsoft.AspNet.WebHelpers. You should remove the old package first,  and then install the newer package.

    There is no cross version  compatibility among major ASP.NET packages. For example, MVC 5 is compatible  with only Razor 3, and not Razor 2.

  4. Open your project in Visual Studio 2013.
  5. Remove any of the following ASP.NET NuGet packages that are installed.  You will remove these using the Package Manager Console (PMC). To open the  PMC, select the Tools menu and then select Library  Package Manager, then select Package Manager Console.  Your project might not include all of these.

    1. Microsoft.AspNet.WebPages.Administration
      This package is typically added when upgrading from MVC 3 to MVC 4.  To remove it, run the following command in the PMC:
      Uninstall-Package -Id Microsoft.AspNet.WebPages.Administration
    2. Microsoft-Web-Helpers
      This  package has been rebranded as Microsoft.AspNet.WebHelpers.  To remove it, run the following command in the PMC:
      Uninstall-Package -Id Microsoft-Web-Helpers
    3. Microsoft.AspNet.Mvc.FixedDisplayMode 
      This package contains a work around for a bug in MVC 4 that has been  fixed in MVC 5. To remove it, run the following command in the PMC:
      Uninstall-Package -Id Microsoft.AspNet.Mvc.FixedDisplayModes

  6. Upgrade all the ASP.NET NuGet packages using the PMC. In the PMC, run  the following command:
    Update-Package
    The Update-Package command without any parameters will update every  package. You can update packages individually by using the ID argument. For  more information about the update command, run get-help update-package.


Update the Application web.config File


Be sure to make these changes in the app web.config file, not the web.config file in the Views folder.


Locate the <runtime>/<assemblyBinding> section, and  make the following changes:



  1. In the elements with the name attribute “System.Web.Mvc”, change the  version number from “4.0.0.0” to “5.0.0.0”. (Two changes in that element.)
  2. In elements with the name attribute "System.Web.Helpers” and  "System.Web.WebPages" change the version number from “2.0.0.0” to “3.0.0.0”.  Four changes will occur, two in each of the elements.
    <runtime>   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">     <!--Two elements removed for Clarity -->     <dependentAssembly>       <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />       <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />     </dependentAssembly>     <dependentAssembly>       <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />       <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />     </dependentAssembly>     <dependentAssembly>       <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />       <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />     </dependentAssembly>     <!--WebGrease element removed for Clarity -->   </assemblyBinding

  3. Locate the <appSettings> section and update the  webpages:version from 2.0.0.0.0 to 3.0.0.0 as shown below:
      <appSettings>     <add key="webpages:Version" value="3.0.0.0" />     <add key="webpages:Enabled" value="false" />     <add key="PreserveLoginUrl" value="true" />     <add key="ClientValidationEnabled" value="true" />     <add key="UnobtrusiveJavaScriptEnabled" value="true" />   </appSettings>

  4. Remove any trust levels other than Full. For example:
      <securityPolicy>    <!--<trustLevel name="Medium"  policyFile="web_mediumtrust.config"/>-->
    </securityPolicy>

Update the web.config files under the Views folder


If your application is using areas, you will also need to update each web.config file in the Views sub-folder of each Area folder.



  1. Update all elements that contain “System.Web.Mvc” from version “4.0.0.0”  to  version“5.0.0.0”.
    <system.web.webPages.razor>   <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />   <pages pageBaseType="System.Web.Mvc.WebViewPage">     <namespaces>       <add namespace="System.Web.Mvc" />       <!--Elements removed for Clarity.-->     </namespaces>   </pages>
    </system.web.webPages.razor>
      -->   <pages       validateRequest="false"       pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"       pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"       userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">     <controls>       <add assembly="System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />     </controls>   </pages>
    </system.web>

  2. Update all elements that contain “System.Web.WebPages.Razor”  from  version “2.0.0.0”  to  version“3.0.0.0”. If this section contains “System.Web.WebPages”,  update those elements from  version “2.0.0.0” to  version“3.0.0.0”
    <configuration>   <configSections>     <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">       <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />       <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />     </sectionGroup>   </configSections>

  3. If you removed the Microsoft-Web-Helpers NuGet package in a  previous step, install Microsoft.AspNet.WebHelpers  with  the following command in the PMC:
    Install-Package -Id  Microsoft.AspNet.WebHelpers
  4. If your app uses the  User.IsInRole() method, add the following to the Web.config file.
    <system.webServer>
    <modules>
    <remove name="RoleManager" />
    </modules>
    </system.webServer>

Final Steps


Build and test the application.


Remove the MVC 4 project type GUID from the project files.



  1. In Solution Explorer, right-click the project name and then select Unload Project.
  2. Right-click the project  and select Edit ProjectName.csproj.
  3. Locate the ProjectTypeGuids element and then remove  the MVC 4 project GUID, {E3E379DF-F4C6-4180-9B81-6769533ABE47}.
  4. Save and close the open project file.
  5. Right-click the project and select Reload Project.


Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  November 2017  >>
MonTueWedThuFriSatSun
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

Month List