Saturday, May 9, 2015

Efficient DataTransfer via DataSet (especially over Network) through Webservice in .Net

Whenever we are exposing a webservice with a webmethod of return type DataSet, we usually don't care of what extra information dataset has kept. If we serialize this Dataset in XML; then we can have a look of all the information. So particularly, if we see Dataset sends the schema information also, which sometimes isn't required, and apparently it creates a heavy data transfer specially over network.

Normally, you don't feel the difference if Dataset have one to two tables. But surely, if will boost up the performance. Considering the below example; let's suppose we have one webserivce with a webmethod of return type dataset.

public class MyWebService : System.Web.Services.WebService
    {

        [WebMethod]
        public DataSet GetDataset()
        {
            using (MyDataSet ds = new MyDataSet())
            {
                ds.Tables.Add(CreateTableWithData("Table1"));
                ds.Tables.Add(CreateTableWithData("Table2"));
                ds.Tables.Add(CreateTableWithData("Table3"));
                ds.Tables.Add(CreateTableWithData("Table4"));
                return ds;
            }
        }
        DataTable CreateTableWithData(string tableName)
        {
            using (DataTable dt = new DataTable())
            {
                dt.TableName = tableName;
                dt.Columns.Add("Column1", typeof(string));
                dt.Columns.Add("Column2", typeof(string));
                DataRow drow = dt.NewRow();
                drow[0] = "Test1";
                drow[1] = "Test2";
                dt.Rows.Add(drow);
                return dt;
            }
        }
   }


public class MyDataSet : DataSet
    {
        public override SchemaSerializationMode SchemaSerializationMode
        {
            get { return SchemaSerializationMode.ExcludeSchema  }
        }

    } 

Now if you have noticed, we have created our custom DataSet class (MyDataSet); inherited with DataSet class, with overridden property SchemaSerialiazationMode. Because if you will directly set the property of SchemaSerialiazationMode to ExcludeSchema, it won't allow you to do so. By default it is set to IncludeSchema. Below is the actual property:



public virtual SchemaSerializationMode SchemaSerializationMode {
           
get {
               
return SchemaSerializationMode.IncludeSchema;
        }
           
set {
               
if (value != SchemaSerializationMode.IncludeSchema) {
                   
throw ExceptionBuilder.CannotChangeSchemaSerializationMode();
        }
    }
  }

We can check the data by serializing the Dataset into XML, which has the XML with removed schema. Here is the sample code:


MyWebService web = new MyWebService();

using (DataSet ds = web.GetDataset())
{

      XmlSerializer ser = new XmlSerializer(typeof(DataSet));

      TextWriter writer = new StreamWriter(@"C:\xm1.xml");

       ser.Serialize(writer, ds);

       writer.Close();

}
 
This is very useful if we have multiple tables in one dataset. Hence ExcludeSchema does the trick by overwhelming the load when sending dataset via WebSerivce. 
 

No comments:

Post a Comment