Tuesday, August 17, 2010

View Doctor Details Webpage

Doctor Details

Gridview

>asp:GridView ID="gvDoctors" runat="server" AutoGenerateColumns="false" AllowPaging="true"
PageSize="5" Width="100%" GridLines="Both" OnRowDataBound="gvDoctors_RowDataBound"
AllowSorting="true" OnSelectedIndexChanging="gvDoctors_SelectedIndexChanging"
OnSorting="gvDoctors_Sorting">


>Columns>
>asp:TemplateField>
>asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName"
HeaderStyle-CssClass="name" />
>asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName"
HeaderStyle-CssClass="name" />
>asp:BoundField DataField="City" HeaderText="City" SortExpression="City" HeaderStyle-CssClass="name" />
>asp:BoundField DataField="State" HeaderText="State" SortExpression="State" HeaderStyle-CssClass="name" />
>asp:BoundField DataField="ZipCode" HeaderText="ZipCode" SortExpression="ZipCode"
HeaderStyle-CssClass="name" />
>asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" HeaderStyle-CssClass="name" />
>asp:BoundField DataField="HomePhone" HeaderText="Home Phone" SortExpression="HomePhone"
HeaderStyle-CssClass="name" />
>asp:BoundField DataField="LicenceNumber" HeaderText="Licence Number" SortExpression="LicenceNumber"
HeaderStyle-CssClass="name" />
>%-- >asp:TemplateField ItemStyle-CssClass="hyperlink">
>ItemTemplate>
>asp:HyperLink ID="hlnkView" runat="server" CssClass="hyperlink" NavigateUrl='<%#String.Concat("/AMSWeb/ViewDoctors.aspx?stat=doct&did=",Eval("doctorid")) %>'>View
|>asp:HyperLink ID="hlnkEdit" runat="server" CssClass="hyperlink" NavigateUrl='>%#String.Concat("/AMSWeb/ModifyDoctor.aspx?stat=doct&did=",Eval("doctorid")) %>'>Edit>/asp:HyperLink>
|>asp:HyperLink ID="HyperLink2" runat="server" CssClass="hyperlink" NavigateUrl='>%#String.Concat("/AMSWeb/doctorappointments.aspx?stat=doct&did=",Eval("doctorid")) %>' >/asp:HyperLink>
>asp:HyperLink ID="HyperLink1" runat="server" CssClass="hyperlink" NavigateUrl='>%#String.Concat("/AMSWeb/doctorschedule.aspx?stat=doct&did=",Eval("doctorid")) %>'
Visible="false">Set Schedule>/asp:HyperLink>
>/ItemTemplate>
>/asp:TemplateField>--%>
>/Columns>
>/asp:GridView>


buttons


>input id="btnView" name="btnView" class="submitbutton" type="button" value="View"
onclick="return ViewDoctor();" />

>input id="btnEdit" name="btnEdit" class="submitbutton" type="button" value="Edit"
onclick="return EditDoctor();" />

Doctor Webpage.cs

Doctor.CS

INSERT


using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using AMS.BO;
using AMS.BLL;

public partial class adddoctor : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GetSpecilizations();
}
}

private void GetSpecilizations()
{
DoctorsBLL objCPBLL = new DoctorsBLL();
DataSet ds = objCPBLL.GetSpecilizations();
ddlSpecializationId.DataSource = ds;
ddlSpecializationId.DataBind();
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
DoctorsBLL objCPBLL = new DoctorsBLL();
UsersBLL objUserBLL = new UsersBLL();
DoctorsBO objDoctorBO = new DoctorsBO();
UsersBO objUserBO = new UsersBO();
int doctorid = -1;
int userid = AddUser();

if (userid != 0)
{
doctorid = AddDoctor(userid);
}

if (doctorid == -1)
{

objUserBO.Type = "Delete";
objUserBLL.UsersOperations(objUserBO);

string alert = ">script language=javascript>alert('Error Occured Doctor Details..');>/script>";
Page.ClientScript.RegisterStartupScript(typeof(Page), "Alert", alert);

}
else
{
string alert = ">script language=javascript>alert('Doctor Successfully Inserted');>/script>";
Response.Write(alert);
//Page.ClientScript.RegisterStartupScript(typeof(Page), "Alert", alert);
Response.Redirect("/AMSWeb/doctors.aspx");

}
}

private int AddUser()
{
UsersBLL objBLL = new UsersBLL();
UsersBO objBO = new UsersBO();
objBO.UserName = txtUserName.Text;
objBO.Password = txtPassword.Text;
objBO.Role = 1;
objBO.Email = txtEmail.Text;
if (chkStatus.Checked)
{
objBO.Status = 1;
}
else
{
objBO.Status = 0;
}
objBO.EnteredDate = Convert.ToString(DateTime.Now);
objBO.Type = "Insert";
objBO = objBLL.UsersOperations(objBO);
if (objBO.NewUserId != 0)
{
return objBO.NewUserId;
}
else
return 0;

}
private int AddDoctor(int userid)
{
DoctorsBLL objBLL = new DoctorsBLL();
DoctorsBO objBO = new DoctorsBO();
objBO.UserId = userid;
objBO.FirstName = txtFirstName.Text;
objBO.LastName = txtLastName.Text;
objBO.MiddleName = txtMiddleName.Text;
objBO.SSN = txtSSN.Text;
objBO.DOB = txtDOB.Text;
objBO.Gender = rdolstGender.SelectedItem.Text;
objBO.Age = Convert.ToInt32(txtAge.Text);
objBO.Address = txtAddress.Text;
objBO.City = txtCity.Text;
objBO.State = txtState.Text;
objBO.ZipCode = txtZipCode.Text;
objBO.Email = txtEmail.Text;
objBO.HomePhone = txtHomePhone.Text;
objBO.WorkPhone = txtWorkPhone.Text;
objBO.Mobile = txtMobile.Text;
objBO.Fax = txtFax.Text;
objBO.SpecilizationId = Convert.ToInt32(ddlSpecializationId.SelectedItem.Value);
objBO.RegistrationNumber = txtRegistrationNo.Text;
objBO.LicenceNumber = txtLicenceNo.Text;


objBO.Type = "Insert";
objBO = objBLL.DoctorOperations(objBO);
if (objBO.DoctorId == 1)
return 1;
else
return -1;
}
}

UPDATE

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
using AMS.BO;
using AMS.BLL;

public partial class ClaimantAdministrator : System.Web.UI.Page
{
int ClaimantAdminID
{
get
{
int claimantAdminID = 0;

if (Request.QueryString["cid"] != null && Request.QueryString["cid"].Length > 0)
{
claimantAdminID = Convert.ToInt32(Request.QueryString["cid"]);
Session["claimantID"] = claimantAdminID;
}
else if (Session["claimantID"] != null)
claimantAdminID = Convert.ToInt32(Session["cid"]);
return claimantAdminID;
}
}

protected void Page_Load(object sender, EventArgs e)
{
btnSubmit.Attributes.Add("onclick", "return validate();");

if (!Page.IsPostBack)
{
GetUSStates();
if (ClaimantAdminID != 0)
DisplayCalimantAdministrator();
}
}

private void DisplayCalimantAdministrator()
{
ClaimantAdminInformationBLL objCABLL = new ClaimantAdminInformationBLL();
ClaimantAdminInformationBO objCABO = new ClaimantAdminInformationBO();
objCABO.Type = "SelectByClaimantAdminID";
objCABO.ClaimantAdminID = ClaimantAdminID;
DataSet ds = new DataSet();
objCABLL.ClaimantAdminOperations(objCABO);
ds = objCABO.GetUSStates;
if (ds.Tables[0].Rows.Count > 0)
{
DataTable dt = ds.Tables[0];
ViewState["ClaimantAdminID"] = ds.Tables[0].Rows[0]["ClaimantAdminID"].ToString();
txtClaimantAdminName.Text = ds.Tables[0].Rows[0]["ClaimantAdminName"].ToString();
txtClaimantAdminAddress.Text = ds.Tables[0].Rows[0]["Address"].ToString();
txtClaimantAdminCity.Text = ds.Tables[0].Rows[0]["City"].ToString();
ddlState.Text = ds.Tables[0].Rows[0]["State"].ToString();
txtClaimantAdminPhone.Text = ds.Tables[0].Rows[0]["PhoneNo"].ToString();
txtClaimantAdminZipCode.Text = ds.Tables[0].Rows[0]["ZipCode"].ToString();
txtClaimantAdminFax.Text = ds.Tables[0].Rows[0]["Fax"].ToString();
txtClaimantAdminEmail.Text = ds.Tables[0].Rows[0]["Email"].ToString();

txtCPName.Text = ds.Tables[0].Rows[0]["ContactPersonName"].ToString();
txtCPSSN.Text = ds.Tables[0].Rows[0]["ContactPersonSSN"].ToString();
txtCPTitle.Text = ds.Tables[0].Rows[0]["ContactPersonTitle"].ToString();
txtCPPhone.Text = ds.Tables[0].Rows[0]["ContactPersonPhoneNo"].ToString();
txtCPMobile.Text = ds.Tables[0].Rows[0]["ContactPersonMobileNo"].ToString();
txtCPEmail.Text = ds.Tables[0].Rows[0]["ContactPersonEmail"].ToString();
}
}
private void GetUSStates()
{
ClaimantAdminInformationBLL objBLL = new ClaimantAdminInformationBLL();
ClaimantAdminInformationBO objBO = new ClaimantAdminInformationBO();

DataSet ds = new DataSet();
ds = objBLL.GetUSStates();
ddlState.DataSource = ds;

ddlState.DataTextField = "USStateName";
ddlState.DataValueField = "USStateCd";
ddlState.DataBind();

ddlState.Items.FindByText("California").Selected = true;
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
ClaimantAdminInformationBLL objCABLL = new ClaimantAdminInformationBLL();
ClaimantAdminInformationBO objCABO = new ClaimantAdminInformationBO();
objCABO.ClaimantAdminName = txtClaimantAdminName.Text;
objCABO.Address = txtClaimantAdminAddress.Text;
objCABO.City = txtClaimantAdminCity.Text;
objCABO.State = ddlState.SelectedItem.Value;
objCABO.ZipCode = txtClaimantAdminZipCode.Text;
objCABO.PhoneNo = txtClaimantAdminPhone.Text;
objCABO.Fax = txtClaimantAdminFax.Text;
objCABO.Email = txtClaimantAdminEmail.Text;
objCABO.ContactPersonName = txtCPName.Text;
objCABO.ContactPersonTitle = txtCPTitle.Text;
objCABO.ContactPersonSSN = txtCPSSN.Text;
objCABO.ContactPersonPhoneNo = txtCPPhone.Text;
objCABO.ContactPersonMobileNo = txtCPMobile.Text;
objCABO.ContactPersonEmail = txtCPEmail.Text;

if (ViewState["ClaimantAdminID"] == null)
objCABO.Type = "Insert";
else
{
objCABO.Type = "Update";
objCABO.ClaimantAdminID = Convert.ToInt32(ViewState["ClaimantAdminID"]);
}
objCABLL.ClaimantAdminOperations(objCABO);

Response.Redirect("ClaimantAdministrator.aspx?stat=comp");

//if (objCABO.ClaimantAdminID == 0)
//{
// string str = "";
// Page.ClientScript.RegisterStartupScript(typeof(Page), "success", str);
//}
//else
//{
// string str = "";
// Page.ClientScript.RegisterStartupScript(typeof(Page), "success", str);
//}
}
}

Doctor Webpage

Doctor Add page

textbox
>asp:TextBox ID="txtFirstName" runat="server" CssClass="TextBox">>/asp:TextBox>
rediobutton
>asp:RadioButtonList ID="rdolstGender" runat="server"
RepeatDirection="Horizontal">
>asp:ListItem Selected="True">Male>/asp:ListItem>
>asp:ListItem>Female>/asp:ListItem>
>/asp:RadioButtonList>
dropdownbutton
>asp:DropDownList ID="ddlSpecializationId" runat="server"
DataTextField="Specilization" DataValueField="SpecilizationId"
CssClass="TextBox">
>asp:ListItem Value="-1" >Select Specialization>/asp:ListItem>
>asp:ListItem Value="0">Cardiologist>/asp:ListItem>
>asp:ListItem Value="1">Physiotheraphist>/asp:ListItem>
>asp:ListItem Value="2">Dermatologist>/asp:ListItem>
>asp:ListItem Value="3">Gynaecologist>/asp:ListItem>
>/asp:DropDownList>
button
>asp:Button ID="btnSubmit" runat="server" Text="Submit" CssClass="Button"
onclick="btnSubmit_Click" />

>asp:Button ID="btnCancel" runat="server" Text="Cancel" CssClass="Button"
CausesValidation="False" />

DLL (Data Logic Layar )

DoctorDAL


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using AMS.BO;
using AMS.DAL;

namespace AMS.BLL
{
public class DoctorsBLL
{
public DoctorsBO DoctorOperations(DoctorsBO objBO)
{
DoctorsDAL objDAL = new DoctorsDAL();
return objDAL.DoctorOperations(objBO);
}
public DataSet GetSpecilizations()
{
DoctorsDAL objDAL = new DoctorsDAL();
return objDAL.GetSpecilizations();
}
}
}

DAL ( DATA ACCESS LAYAER )

DoctorDAL

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using AMS.BO;

namespace AMS.DAL
{
public class DoctorsDAL:DALTemplateClass
{
private SqlConnection myConn;
public DoctorsBO DoctorOperations(DoctorsBO objBO)
{
// Create Instance of Connection and Command Object

myConn = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["AMSDB"]);
SqlCommand myComm = new SqlCommand("AMS_Doctors_Operations", myConn);
SqlDataAdapter da = new SqlDataAdapter();

// Mark the Command as a SPROC

myComm.CommandType = CommandType.StoredProcedure;

myComm.Parameters.AddWithValue("@DoctorId", objBO.DoctorId);
myComm.Parameters.AddWithValue("@Hid", objBO.Hid);
myComm.Parameters.AddWithValue("@UserId", objBO.UserId);
myComm.Parameters.AddWithValue("@SalutationId", objBO.SalutationId);
myComm.Parameters.AddWithValue("@FirstName", objBO.FirstName);
myComm.Parameters.AddWithValue("@LastName", objBO.LastName);
myComm.Parameters.AddWithValue("@MiddleName", objBO.MiddleName);
myComm.Parameters.AddWithValue("@SSN", objBO.SSN);
myComm.Parameters.AddWithValue("@DOB", objBO.DOB);
myComm.Parameters.AddWithValue("@Gender", objBO.Gender);
myComm.Parameters.AddWithValue("@Age", objBO.Age);
myComm.Parameters.AddWithValue("@Address", objBO.Address);
myComm.Parameters.AddWithValue("@City", objBO.City);
myComm.Parameters.AddWithValue("@State", objBO.State);
myComm.Parameters.AddWithValue("@ZipCode", objBO.ZipCode);
myComm.Parameters.AddWithValue("@Email", objBO.Email);
myComm.Parameters.AddWithValue("@HomePhone", objBO.HomePhone);
myComm.Parameters.AddWithValue("@WorkPhone", objBO.WorkPhone);
myComm.Parameters.AddWithValue("@Mobile", objBO.Mobile);
myComm.Parameters.AddWithValue("@Fax", objBO.Fax);
myComm.Parameters.AddWithValue("@SpecilizationId", objBO.SpecilizationId);
myComm.Parameters.AddWithValue("@RegistrationNumber", objBO.RegistrationNumber);
myComm.Parameters.AddWithValue("@LicenceNumber", objBO.LicenceNumber);
myComm.Parameters.AddWithValue("@Type", objBO.Type);



// Open the connection and execute the Command

try
{

myConn.Open();
if (objBO.Type == "Insert" || objBO.Type == "Update")
{

myComm.ExecuteNonQuery();
objBO.DoctorId = 1;

}
if (objBO.Type == "SelectAll" || objBO.Type == "SelectById" || objBO.Type=="SelectByUserId"
|| objBO.Type == "SelectByHospitalId" || objBO.Type == "Search" )
{

DataSet ds = new DataSet();
da.SelectCommand = myComm;
da.Fill(ds);
objBO.DoctorsDS = ds;

}
return objBO;
}
catch (Exception ex)
{
MessageDescription = ex.Message;
return null;
}
finally
{
myConn.Close();
myComm.Dispose();
da.Dispose();
}


}

public DataSet GetSpecilizations()
{
// Create Instance of Connection and Command Object

myConn = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["AMSDB"]);
SqlCommand myComm = new SqlCommand("AMS_Specializations_Operations", myConn);
SqlDataAdapter da = new SqlDataAdapter();
// Mark the Command as a SPROC


// Open the connection and execute the Command

try
{


DataSet ds = new DataSet();
da.SelectCommand = myComm;
da.Fill(ds);


return ds;
}
catch (Exception ex)
{
MessageDescription = ex.Message;
return null;
}
finally
{
myConn.Close();
myComm.Dispose();
da.Dispose();
}

}
}
}



Connection DB


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace AMS.DAL
{
public class ConnectionDB
{
private static SqlConnection _dbConnection;

public static void CloseConnection()
{
if (_dbConnection.State != ConnectionState.Closed)
{
_dbConnection.Close();
}
}

public static SqlConnection GetConnection()
{
_dbConnection = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["AMSDB"]);
_dbConnection.Open();
return _dbConnection;
}


}

}

web.config

>appSettings>
>add key="AMSDB" value="server=SYS;User Id=sa;Password=123456;database=AMSDBNew;Connection Timeout=10000;"/>
>!---->
>add key="autoSuggestConnectionString" value="server=.\SQLEXPRESS;Integrated Security=SSPI;database=northwind;provider=SQLNCLI.1"/>
>add key="DocId" value="1"/>
>add key="HId" value="2"/>
>add key="CompanyID" value="31"/>
>add key="ContactPersonID" value="23"/>
>add key="PhysicalPathofPDF" value="D:\AMS\\AMSWeb\\Documents\\"/>
>!-- EMail Credentials -->
>add key="networkCredentialMailId" value="gajulamk@gmail.com"/>
>add key="networkCredentialMailPassword" value="gajula"/>
>add key="defaultFromMailId" value="ams.gajulamk@gmail.com"/>
>add key="smtpClient" value="smtp.gmail.com"/>
>add key="port" value="587"/>
>!-- End EMail-->
>/appSettings>
>connectionStrings/>
>system.web>

>!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
>customErrors mode="Off"/>
>compilation debug="true">
>assemblies>
>add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
>add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
>add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
>add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
?add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
>add assembly="System.Web.Extensions.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

>/assemblies>
>/compilation>

BO ( Bussiness Objectives )

DoctorBO first

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace AMS.BO
{
public class DoctorsBO:ProfileBO
{
private int _DoctorId;
public int DoctorId
{
get { return _DoctorId; }
set { _DoctorId = value; }
}
private string _DOB;
public string DOB
{
get { return _DOB; }
set { _DOB = value; }
}
private string _Gender;
public string Gender
{
get { return _Gender; }
set { _Gender = value; }
}
private int _Age;
public int Age
{
get { return _Age; }
set { _Age = value; }
}

private string _Address;
public string Address
{
get { return _Address; }
set { _Address = value; }
}
private string _City;
public string City
{
get { return _City; }
set { _City = value; }
}
private string _State;
public string State
{
get { return _State; }
set { _State = value; }
}
private string _ZipCode;
public string ZipCode
{
get { return _ZipCode; }
set { _ZipCode = value; }
}
private int _SpecilizationId;
public int SpecilizationId
{
get { return _SpecilizationId; }
set { _SpecilizationId = value; }
}
private string _RegistrationNumber;
public string RegistrationNumber
{
get { return _RegistrationNumber; }
set { _RegistrationNumber = value; }
}
private string _LicenceNumber;
public string LicenceNumber
{
get { return _LicenceNumber; }
set { _LicenceNumber = value; }
}

private DataSet _DoctorsDS;
public DataSet DoctorsDS
{
get { return _DoctorsDS; }
set { _DoctorsDS = value; }
}

}
}


DoctorBO Second


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace AMS.BO
{
public class DoctorsBO:ProfileBO
{
public int DctorID { get; set; }
public string DOB{ get; set; }
public string Gender{ get; set; }
public string Age{ get; set; }
public string Address{ get; set; }
public string City{ get; set; }
public string ToDate { get; set; }
}
}

Monday, March 8, 2010

Using a WPF ListView as a DataGrid

Many people like to view data in a grid format of rows and columns. WPF did not come with a data grid control that automatically creates rows and columns for you based on the object you pass it. However, the WPF Toolkit can be downloaded from CodePlex.com that does contain a DataGrid control. This DataGrid gives you the ability to pass it a DataTable or a Collection class and it will automatically figure out the columns or properties and create all the columns for you and display the data.

The DataGrid control also supports editing and many other features that you might not always need. This means that the DataGrid does take a little more time to render the data. If you want to just display data (see Figure 1) in a grid format, then a ListView works quite well for this task. Of course, you will need to create the columns for the ListView, but with just a little generic code, you can create the columns on the fly just like the WPF Toolkit’s DataGrid.

ListView as a DataGrid - Figure 1

Figure 1: A List of Data using a ListView


A Simple ListView Control

The XAML below is what you would use to create the ListView shown in Figure 1. However, the problem with using XAML is you have to pre-define the columns. You cannot re-use this ListView except for “Product” data.


>ListView x:Name="lstData"
ItemsSource="{Binding}">
>ListView.View>
>GridView>
>GridViewColumn Header="Product ID"
Width="Auto"
DisplayMemberBinding="{Binding Path=ProductId}" />
>GridViewColumn Header="Product Name"
Width="Auto"
DisplayMemberBinding="{Binding Path=ProductName}" />
>GridViewColumn Header="Price"
Width="Auto"
DisplayMemberBinding="{Binding Path=Price}" />
>/GridView>
>/ListView.View>
>/ListView>

So, instead of creating the GridViewColumn’s in XAML, let’s learn to create them in code to create any amount of columns in a ListView.

Create GridViewColumn’s From Data Table

To display multiple columns in a ListView control you need to set its View property to a GridView collection object. You add GridViewColumn objects to the GridView collection and assign the GridView to the View property. Each GridViewColumn object needs to be bound to a column or property name of the object that the ListView will be bound to. An ADO.NET DataTable object contains a collection of columns, and these columns have a ColumnName property which you use to bind to the GridViewColumn objects.

Listing 1 shows a sample of reading and XML file into a DataSet object. After reading the data a GridView object is created. You can then loop through the DataTable columns collection and create a GridViewColumn object for each column in the DataTable. Notice the DisplayMemberBinding property is set to a new Binding to the ColumnName in the DataTable.

C#
private void FirstSample()
{
// Read the data
DataSet ds = new DataSet();
ds.ReadXml(GetCurrentDirectory() + @"\Xml\Product.xml");

// Create the GridView
GridView gv = new GridView();

// Create the GridView Columns
foreach (DataColumn item in ds.Tables[0].Columns)
{
GridViewColumn gvc = new GridViewColumn();
gvc.DisplayMemberBinding = new Binding(item.ColumnName);
gvc.Header = item.ColumnName;
gvc.Width = Double.NaN;
gv.Columns.Add(gvc);
}

// Setup the GridView Columns
lstData.View = gv;
// Display the Data
lstData.DataContext = ds.Tables[0];
}

VB.NET
Private Sub FirstSample()
' Read the data
Dim ds As New DataSet()
ds.ReadXml(GetCurrentDirectory() & "\Xml\Product.xml")

' Create the GridView
Dim gv As New GridView()

' Create the GridView Columns
For Each item As DataColumn In ds.Tables(0).Columns
Dim gvc As New GridViewColumn()
gvc.DisplayMemberBinding = New Binding(item.ColumnName)
gvc.Header = item.ColumnName
gvc.Width = [Double].NaN
gv.Columns.Add(gvc)
Next

' Setup the GridView Columns
lstData.View = gv
' Display the Data
lstData.DataContext = ds.Tables(0)
End Sub
Listing 1: Loop through the DataTable columns collection to create GridViewColumn objects

A Generic Method for Creating a GridView

Instead of having to write the code shown in Listing 1 for each ListView you wish to create, you can create a generic method that given any DataTable will return a GridView column collection. Listing 2 shows how you can simplify the code in Listing 1 by setting up a class called WPFListViewCommon and create a method called CreateGridViewColumns that returns your GridView.

C#
private void DataTableSample()
{
// Read the data
DataSet ds = new DataSet();
ds.ReadXml(GetCurrentDirectory() + @"\Xml\Product.xml");

// Setup the GridView Columns
lstData.View =
WPFListViewCommon.CreateGridViewColumns(ds.Tables[0]);
lstData.DataContext = ds.Tables[0];
}

VB.NET
Private Sub DataTableSample()
' Read the data
Dim ds As New DataSet()
ds.ReadXml(GetCurrentDirectory() & "\Xml\Product.xml")

' Setup the GridView Columns
lstData.View = _
WPFListViewCommon.CreateGridViewColumns(ds.Tables(0))
lstData.DataContext = ds.Tables(0)
End Sub
Listing 2: Call a generic method to create GridViewColumns.

The CreateGridViewColumns Method

The CreateGridViewColumns method will take a DataTable as a parameter and create a GridView object with a GridViewColumn object in its collection for each column in your DataTable.

C#
public static GridView CreateGridViewColumns(DataTable dt)
{
// Create the GridView
GridView gv = new GridView();
gv.AllowsColumnReorder = true;

// Create the GridView Columns
foreach (DataColumn item in dt.Columns)
{
GridViewColumn gvc = new GridViewColumn();
gvc.DisplayMemberBinding = new Binding(item.ColumnName);
gvc.Header = item.ColumnName;
gvc.Width = Double.NaN;
gv.Columns.Add(gvc);
}

return gv;
}

VB.NET
Public Shared Function CreateGridViewColumns _
(ByVal dt As DataTable) As GridView
' Create the GridView
Dim gv As New GridView()
gv.AllowsColumnReorder = True

' Create the GridView Columns
For Each item As DataColumn In dt.Columns
Dim gvc As New GridViewColumn()
gvc.DisplayMemberBinding = New Binding(item.ColumnName)
gvc.Header = item.ColumnName
gvc.Width = [Double].NaN
gv.Columns.Add(gvc)
Next

Return gv
End Function

Listing 3: The CreateGridViewColumns method takes a DataTable and creates GridViewColumn objects in a GridView.
By separating this method out into a class you can call this method anytime you want to create a ListView with a collection of columns from a DataTable.

Saturday, February 20, 2010

Highlight button during Asynchronous PostBack

If you don’t want to use UpdateProgress during Asynchronous Postback from UpdatePanel ,There is an idea to highlight the button that fire the Asynchronous inside UpdatePanel.

To start with this approach you must be familiar with PageRequestManager class and it's events , PageRequestManager registered by ScriptManager. With PageRequestManager you can manages partial-page rendering in the browser.
On other hand you can’t access PageRequestManager event’s directly, just you can access it through getInstance method.

The most popular events, as well I use it in my example here are beginRequest and endRequest events.

beginRequest:Raised before the processing of an asynchronous postback starts.

endRequest: Raised after an asynchronous postback is finished and control has been returned to the browser.

Now lets take a look to the example:

>html xmlns="http://www.w3.org/1999/xhtml">
>head runat="server">
>title> check it >/title>
>/head>
>body>
>form id="form1" runat="server">
>div>
>asp:ScriptManager ID="sm1" runat="server" />
>script language="javascript" type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(update_begin);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(update_end);
var btn = null;
var Counter = 0;
var timer;

function MyTimer() {
Counter++;
if (Counter % 2 == 0)
btn.style.background = "#dddddd";
else
btn.style.background = "#eeeeee";
timer = window.setTimeout("MyTimer()", 500);
}

function ClearTimer() {
window.clearTimeout(timer);
Counter = -1;
btn.style.background = "#dddddd";
}

function update_begin(sender, args) {
btn = args.get_postBackElement();
MyTimer();
}

function update_end() {
ClearTimer();
}
>/script>

>asp:UpdatePanel ID="UpdatePanel1" runat="server">
>ContentTemplate>
>asp:Button ID="btnSubmit1" runat="server" Text="Submit 1" BackColor="#dddddd"
OnClick="btnSubmit1_Click" />
>asp:Button ID="btnSubmit2" runat="server" Text="Submit 2" BackColor="#dddddd"
OnClick="btnSubmit2_Click" />
>br />
>asp:Label ID="lblMessage" runat="server" Text="">
>/ContentTemplate>
>/asp:UpdatePanel>
>/div>
>/form>
>/body>
>/html>

In code behind :

protected void btnSubmit1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2400);
lblMessage.Text = "You Press button 1";
}
protected void btnSubmit2_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
lblMessage.Text = "You Press button 2";
}

In the previous example we catch which Element caused the Asynchronous PostBack by args.get_postBackElement(), In this way you can get the Control ID throw args.get_postBackElement().id. And you can catch if the control which cased the Asynchronous PostBack not a button, in case your UpdatePanel contain many controls which cause Asynchronous PostBack.

On the other hand you can use your own style to highlight your controls.

The last note here that I add System.Threading.Thread.Sleep(3000); to the Click handler, which artificially creates a three-second delay and then displays the button Highlighted.

Sunday, February 7, 2010

ASP.NET SECURITY: AUTHENTICATION AND AUTHORIZATION

ASP.NET gives developers very flexible and powerful capabilities in to secure to make decisions considering user actions.To apply settings we want, we can edit web.config, machine.config, IIS.Besides this settings there are great classes and namespaces in .NET ( we will use generally system.web.security ).Let's start with element in web.config. (Authentication is the process that determines the identity of a user, in other words asking user his/her credentials.Authorization,on the other hand, after validating credential, giving the user access to any specific part of the application)

>authentication mode="Forms"> //possible values are "Windows|Forms|Passport|Name

>/authentication>
90% we use authentication mode "Forms" so no need to focus on other types.By using >authorization> we define accession rules for specific folders or pages or website as a whole.

>authorization>

>deny users="*"/>

>allow roles="administrator"/>

>/authorization>

This setting first of all denies all users (*) then gives the access right to the role administrator.If we place this xml in web.config on the root of the application then it uses these settings for whole website.But in specific folders it is applied only to that folder. ie in our example, it seems that this code is for admin directory ( it gives access rights just for administrator(s).) We have deny and allow tags and users and roles attributes.For our need we can use them appropriate combination.And an example of how to use system.web.security and its basic functionalities:

using System.Web.Security;
protected void LoginButton_Click(object sender, EventArgs e)
{
if (Membership.ValidateUser(TextBox1.Text, TextBox2.Text)) //this method takes two arguments username,password
{
FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, true); //go to page which was intended
//before redirected to loginpage
}
else
FormsAuthentication.RedirectToLoginPage(); //otherwise go to loginpage again
}
}

ADO.NET HIERARCHY

Whether we use ADO.NET or not generally we don't know about hierarcy of ADO.NET namespaces and classes. Therefore, I want to write its general hierarcy:

ADO.NET NAMESPACES

* System.Data
* System.Data.Common
* System.Data.SqlClient

System.Data: The core of ADO.NET. Tables, Rows, Columns and DataSet are all tools that are in System.Data. This namespace implements IDbCommand, IDbConnection, IDbDataAdapter interfaces.

System.Data.Common: This namespace is generally for custom data providers because it includes base classes of all providers in ASP.NET. For example if you want to write your own SQL provider, then you should use System.Data.Common.

System.Data.SqlClient: Data Provider for SQL. SqlCommand,SqlConnection etc. are in this class.

Now let's group ADO.NET classes considering their base features.

* Classes don't need live connection to database
* Classes do need live connection to database
* Base classes for Data Providers
* and Data Providers

Classes don't need live connection to database: Their most important and basic future is to recreate tables (with its rows, columns, functional dependencies and all its futures) in memory and manipulate them. When needed they send this tables to client side. These classes includes DataSets, DataTables.

Classes do need live connection to database: Like DataReader class, gets the actual form of database and sends it to the client. If there is an update on the server side it should be resent. To do so, it requires live connection.

Base classes for Data Providers : These classes are in System.Data.Common and are base classes for all Data Providers. (including our own custom providers)

DataProvider classes: For each Data Provider, we have a unique DataProvider class. We do all operation related to a specific data source by its own DataProvider. Each and every Data Provider has its own DataConnection, Command, Adapter and Reader objects.

Let's examine a portion of a data access layer class. (This is a general ADO.NET example. In subsequent entries, I'll give more specific examples)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Configuration;
using System.Data.SqlClient; //This is for MSSQL operations.

public static void Insert_Customers(Guid? userID, string name, string surname, string tel_no)
{
SqlConnection conn = null; //for database connection
SqlCommand cmd = null;
// with this object we send necessary commands (sql queries)
// to database
SqlTransaction trans = null; //SqlTransaction is used for insert and delete
//when there is an exception, we can undo our operations
//with this object
try
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ImaletConnectionString"].ConnectionString);
conn.Open();
trans = conn.BeginTransaction();
cmd = new SqlCommand("Insert_Customer",conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Transaction = trans;
cmd.Parameters.Add("@UserID", SqlDbType.UniqueIdentifier);
//add sql parameters with the same name in sql queries
cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 20);
cmd.Parameters.Add("@Surname", SqlDbType.NVarChar, 20);
cmd.Parameters.Add("@Tel_No", SqlDbType.NVarChar, 20);
cmd.Parameters[1].Value = name;
cmd.Parameters[2].Value = surname;
cmd.Parameters[3].Value = tel_no;
cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception pr)
{
if (trans != null)
trans.Rollback();
//if there is an exception undo current operation
throw new Exception();
}
finally
{
if (conn != null)
conn.Close();
// with Dispose() we prompt C# compiler to delete our objects
cmd.Dispose();
trans.Dispose();
conn.Dispose();
}
}

NET IO - 1 ( Creating and Deleting Files and Directories and Listing subfiles and subdirectories )

There are advanced classes in .NET for IO processing. Even though we have some classes that allow us to carry out low level IO operations, we can usually do our work with several static methods. Now let's see how a directory and a file is created, deleted and how directory hierarchy in a disk volume or in a directory can be displayed in tree view. Although IO operations are same in all .NET projects, to make easier our article I use ASP.NET. Hence you can easily copy and paste code below in, for example, WPF. Classes, we will use, are:
· DriveInfo
· DirectoryInfo
· FileInfo
· Directory
· File
To create a directory or file
Directory and File classes in System.IO namespace allow us to create and delete directories or files:

Directory.Create(@"C:\exampleDirectory");
Directory.Delete(@"C:\exampleDirectory");
If we want to work on files and directories in current project folder,
Directory.Create(@"Server.MapPath("exampleDirectory"));
Directory.Delete(@"Server.MapPath("exampleDirectory"));
we can use. When operating on files, use File class:
File.Create(@"C:\exampleFile.doc")
File.Delete(@"C:\exampleFile.doc")
or
File.Create(@"Server.MapPath("exampleFile"));
File.Delete(@"Server.MapPath("exampleFile"));
Now let's work on displaying directory and file hierarchy in treeView like "windows explorer" style. We will use these classes:
· System.IO.DriveInfo //allows us to access the name, available space, total space etc. of a disk volume
· System.IO.DirectoryInfo //allows us to access the name, available space, total space etc. of directory
Create a new site, add TreeView and wrote below code in Page_Load event:
rotected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
System.IO.DriveInfo drive = new System.IO.DriveInfo(@"D:\");
//work on local disk D
TreeNode node = new TreeNode();
//we create TreeNode's dinamically

node.Value = drive.Name;
TreeView1.Nodes.Add(node);
//add local disk D to main node

loadDirectories (node, drive.Name);//in this recursive method,
// we pass name and full address of the local disk
// as parameters
}
}

private void loadDirectories(TreeNode parent, string path)
{
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(path);
//now we don't work on drives but directories

try
{
//with GetDirectories(), we get all sub directories
foreach (System.IO.DirectoryInfo d in directory.GetDirectories())
{
TreeNode node = new TreeNode(d.Name, d.FullName);

parent.ChildNodes.Add(node);

//call the same method (call "loadDirectories()" recursively )
loadDirectories(node, d.FullName);
}
}
catch (System.UnauthorizedAccessException e)
{
parent.Text += "(acces forbiddeni)";
}

catch (System.IO.IOException e)
{
parent.Text += "(unknown error hata: " + e.Message + ")";
}
}
We displayed just content of volume D by writing ”System.IO.DriveInfo drive = new System.IO.DriveInfo(@"D:\");". If we wanted to display all files and directories in computer hard disk, we would write:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
foreach (System.IO.DriveInfo drive in System.IO.DriveInfo.GetDrives())
//to work on all volumes
{
TreeNode node = new TreeNode();
node.Value = drive.Name;

if (drive.IsReady)
{
node.Text = drive.Name;
loadDirectories(node, drive.Name);
}

TreeView1.Nodes.Add(node);
}
}
}
The code below takes several minutes. As you can estimate, our recursive method "loadDirectories()" needs many IO operations.

Now add a GridView to the project. We want to select a file from the TreeView we just created, and see alll subfiles and subdirectories with their name, space, last access time etc. Select SelectedNodeChanged event in "Properties Window" after clicking on TreeView and write the code below.
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
DirectoryInfo directory = new DirectoryInfo(TreeView1.SelectedNode.Value);

GridView1.DataSource = directory.GetFiles();
GridView1.DataBind();
}
We learned how to create and delete files and directories and displaying all subdirectories and files in a disk, hierarchically in a TreeView.

NEW FEATURES COME WITH ASP.NET 4.0

Like ASP.NET 3.5, ASP.NET 4.0 comes with many new features. In Mix09 there were several sessions, I haven't yet written about, about new features ASP.NET will make available in version 4.0 We'll see them but to show you the path ASP.NET has pursuit, first, which improvements ASP.NET 3.5 made:
  1. Microsoft Entity Framework
  2. ADO.NET Data Services
  3. Dynamic Data
  4. Microsoft Ajax Improvements
--Browser History
--Script Combining

Now new features of ASP.NET 4.0 in its all sub-framework:

Web Forms:.net hierachy
  • .. tags. This is important because almost all developers use
    ..
    tags with .css files to control the layout of their pages.

  • ..... Although clearly defining the layout sometimes can be very useful event crucial, in many situations developers use ListView for simple and easy situations and don't need it.

  • ViewState is disabled default. ViewState is a major improvement of ASP.NET in web technologies. However many developers use it in situations that actually don't require ViewState and this results in waste of bandwidth (in big web pages, ViewState can be very big in terms of amount) So we have now for each ASP.NET control and also for Page ( Page is also a control ), "ViewStateMode=enabled,disabled,inherit" so we have more control over it.

  • More control on Client IDs. ASP.NET has produce Client IDs for html output sent to the client considering layout and containers of the specific controls. This is useful because we can't control all the ids of all controls (especially for controls in data binding containers) However when we try to work on these controls, whose name is not known by us, with JavaScript problems start to arise. For example, when we refer to a control like "document.getElementByID(controlID)" we can't do anything. ASP.NET 4.0 solves this problem with (control.clientIdMode -->> legacy,static,predictable,inherit(default)). ( Static means "use the id I gave. I am responsible all errors) (Predictable means "give an id considering containers but in a more clear way)

  • Description and Keyword attributes for @Page for better search engine optimization.

  • Enhancements in web standards (xhtml standarts,accessibility standarts section508,wcag,aria) and checking them in VS2010.

  • A new ASP.NET control, QueryExtender, makes easy to query on entities that implements IQueriable

  • In ASP.NET 4.0 developers will be able to write their own custom cache providers.

  • Session state compression (out-of-proc) with GZip.
ASP.NET Ajax 4.0
  • New data binding features on client side by using templates like ASP.NET databinding controls.

  • jquery comes as part of the visual studio 2010

  • More enhanced Ajax Control Toolkit (there is also client side libraries)
ASP.NET MVC
  • Comes as a separate, stand-alone framework
ASP.NET Dynamic Data
  • New controls and more control for developer

Taking Snapshots in ASP.NET

Taking snapshots of web pages is used by many applications, for example Wordpress shows a small snapshot image of the page that a link directs to. In this post, I'll show how can we get snapshot image of a web page by using a small program, an .exe executable. Hence, it is the executable that creates the image actually and our asp.net page will make use of that .exe. First create a website, add a textbox and a button like below:



Define a class level string imageName code button's click event:

  1. public partial class _Default : System.Web.UI.Page
  2. {
  3. string imageName = "shot.png";

  4. protected void Button1_Click(object sender, EventArgs e)
  5. {
  6. string path = this.GetImage(TextBox1.Text, imageName, Request.PhysicalApplicationPath , 200, 100);

  7. Response.Redirect("~/Default2.aspx?path=" + path);
  8. }

Click event above uses GetImage() method, we will talk about soon, and assigns the path of the image to the QueryString of Default2.aspx, the page responsible for displaying snapshot image.

  1. public string GetImage(string url, string name, string rootDir, int width, int height)
  2. {
  3. string fName = rootDir + "\\" + imageName;
  4. Shot(url, rootDir);
  5. System.Drawing.Image snapshotImage = System.Drawing.Image.FromFile(fName);

  6. fName = rootDir + "\\" + "snapshots" + "\\" + name + ".png";
  7. if (File.Exists(fName))
  8. File.Delete(fName);
  9. snapshotImage .Save(fName, ImageFormat.Png);
  10. return name;
  11. }

The GetImage() method, uses Shot() by assigning relative path of the image and root directory. After invoking Shot() method, it gets the image file that Shot() got and saved.

  1. private void Shot(string url, string rootDir)
  2. {
  3. try
  4. {
  5. Process p = new Process();
  6. p.StartInfo.FileName = rootDir + "IECapt.exe";
  7. p.StartInfo.Arguments = String.Format("\"{0}\" \"{1}\"", url, rootDir + "\\" + imageName);
  8. p.StartInfo.UseShellExecute = false;
  9. p.StartInfo.CreateNoWindow = false;
  10. p.Start();
  11. p.WaitForExit();
  12. p.Dispose();

  13. Label1.Text = "Success :) !!!!!";
  14. }
  15. catch (Exception ex)
  16. {
  17. Label1.Text = ex.ToString();
  18. }
  19. }

This method defines a Process to start and execute a file. Then it sets up arguments (the sequence of them are same with the ones if you would use this .exe in command line).

If you want to add the feature of Wordpress (showing snapshots when hovering on links) you can implement the code above as a Web Service. Then using that service via JavaScript, or with JQuery library to make it more easy, you can get that functionality.

Note: IECapt.exe can be downloaded from here
Note: Because IECapt.exe takes snapshot of the whole page with very big resolution you should scale it in many scenarios.

Our simple Default2.aspx just has a Image control and two lines of code in Page_Load event handler to show the image:

  1. protected void Page_Load(object sender, EventArgs e)
  2. {
  3. if (!string.IsNullOrEmpty(Request.QueryString["path"]))
  4. {
  5. Image1.ImageUrl = "~//" + Request.QueryString["path"].ToString();
  6. Response.Write(Image1.ImageUrl);
  7. }
  8. }
protected void Page_Load(object sender, EventArgs e)
{
    if (!string.IsNullOrEmpty(Request.QueryString["path"]))
    {
        Image1.ImageUrl = "~//" + Request.QueryString["path"].ToString();
        Response.Write(Image1.ImageUrl);
    }
}

Sunday, January 24, 2010

The Most Important WCF Class

Even fairly experienced WCF programmers may never have had to deal with this little gem, however, it is the single most important class in the WCF framework. Why is that? Because the message class provides the fundamental abstraction which represents all data sent or received from any WCF endpoint.

Key Parts

There are four key parts to the message class:

  • Version - The version property contains information about the SOAP and Addressing versions used by the message. WCF fully supports use of non-SOAP messages for which this property is will be None to indicate the lack of any special formatting.
  • Properties - Message properties contain processing information about the message which will not be written to the underlying transport stream as part of the message content. One example of what message properties can be used for is controlling things like HTTP verbs and status codes.
  • Headers - A collection of message headers. A few common headers such as To and Action can be accessed via shortcut properties in the headers collection.
  • Body - You can’t actually access the message body because the Message class abstraction is mean to be used as if the content of the Message was a stream.

It’s Abstract

This will come as a surprise to many people, because the WCF framework does a very good job of hiding this fact, but the Message class itself is an abstract class. So put away any preconceived notions you might have had about how WCF at it’s core can only be used for web services and XML based communication. The fact is that you could create a message class backed directly by a raw binary array if you didn’t want any kind of performance hit for loading the data… as a matter of fact you probably wouldn’t want to even waste your time doing that, because WCF does exactly that when you are using many of the default settings! Actually… it does it even more efficiently than you would probably do it on your own by taking advantage of buffer managers to reduce the number of allocations that need to be made as messages are being created and disposed. So, despite the fact that the underlying abstraction is streaming, WCF actually buffers messages into a byte array by default to allow for higher performance.

It’s Streaming

Once you read the message, it cannot be read again. For this reason, all custom message classes must also provide a MessageBuffer implementation. I won’t talk much about the MessageBuffer class at this point, other than to say that it is also abstract and it is responsible for creating additional “copies” of the message. I say “copies” because the default implementations that are most commonly used by the standard bindings won’t actually “copy” anything. They just return another instance backed by the same internal byte array. This makes for ultra efficient message copying, but is only possible because of another trait of the message… The reason Message implementers must provide their own MessageBuffer implementations is so that the copy operation itself can be as optimized as possible.

It’s Immutable

Well… sort of. The properties and headers of the message can be modified at will, making things like routing logic and header processing much easier to deal with, but the message body itself cannot be modified using the Message or MessageBuffer classes. For this reason, many hooks in the WCF internals where a Message might need to by modified will pass the message as a ref parameter so it can be swapped for another message.

It’s Not XML

The last basic thing you need to know about the Message class which I already touched on, but should make clear again… the Message class does have to not represent XML data! This may seem like a strange statement if you’ve looked casually at the methods provided by the message class. However, this is only due to the unfortunate naming that the WCF team chose for XmlDictionaryReader and XmlDictionaryWriter, which have a lot of methods for reading and writing XML data, but fully support reading and writing raw binary content as well.

Thursday, January 21, 2010

ADO.NET

Most applications need data access at one point of time making it a crucial component when working with applications. Data access is making the application interact with a Database, where all the data is stored. Different applications have different requirements for database access. VB .NET uses ADO .NET (Active X Data Object) as it's data access and manipulation protocol which also enables us to work with data on the . Let's take a look why ADO .NET came into picture replacing ADO.

Evolution of ADO.NET

The first data access model, DAO (data access model) was created for local databases with the built-in Jet engine which had performance and functionality issues. Next came RDO (Remote Data Object) and ADO (Active Data Object) which were designed for Client Server architectures but, soon ADO took over RDO. ADO was a good architecture but as the language changes so is the technology. With ADO, all the data is contained in a recordset object which had problems when implemented on the network and penetrating firewall. ADO was a connected data access, which means that when a connection to the database is established the connection remains open until the application is closed. Leaving the connection open for the lifetime of the application raises concerns about database security and network traffic. Also, as databases are becoming increasingly important and as they are serving more people, a connected data access model makes us think about its productivity. For example, an application with connected data access may do well when connected to two clients, the same may do poorly when connected to 10 and might be unusable when connected to 100 or more. Also, open database connections use system resources to a maximum extent making the system performance less effective.

Why ADO.NET?

To cope up with some of the problems mentioned above, ADO .NET came into existence. ADO .NET addresses the above mentioned problems by maintaining a disconnected database access model which means, when an application interacts with the database, the connection is opened to serve the request of the application and is closed as soon as the request is completed. Likewise, if a database is Updated, the connection is opened long enough to complete the Update operation and is closed. By keeping connections open for only a minimum period of time, ADO .NET conserves system resources and provides maximum security for databases and also has less impact on system performance. Also, ADO .NET when interacting with the database uses and converts all the data into XML XML Format for database related operations making them more efficient.


The ADO.NET Data Architecture

Data Access in ADO.NET relies on two components: DataSet and Data Provider.

DataSet

The dataset is a disconnected, in-memory representation of data. It can be considered as a local copy of the relevant portions of the database. The DataSet is persisted in memory and the data in it can be manipulated and updated independent of the database. When the use of this DataSet is finished, changes can be made back to the central database for updating. The data in DataSet can be loaded from any valid data source like Microsoft SQL Server database, an Oracle database or from a Microsoft Access database.

Data Provider

The Data Provider is responsible for providing and maintaining the connection to the database. A DataProvider is a set of related components that work together to provide data in an efficient and performance driven manner. The .NET Framework currently comes with two DataProviders: the SQL Data Provider which is designed only to work with Microsoft's SQL Server 7.0 or later and the OleDb DataProvider which allows us to connect to other types of databases like Access and Oracle. Each DataProvider consists of the following component classes:

The Connection object which provides a connection to the database
The Command object which is used to execute a command
The DataReader object which provides a forward-only, read only, connected recordset
The DataAdapter object which populates a disconnected DataSet with data and performs update


Data access with ADO.NET can be summarized as follows:

A connection object establishes the connection for the application with the database. The command object provides direct execution of the command to the database. If the command returns more than a single value, the command object returns a DataReader to provide the data. Alternatively, the DataAdapter can be used to fill the Dataset object. The database can be updated using the command object or the DataAdapter.

ADO .NET Data Architecture

Component classes that make up the Data Providers

The Connection Object

The Connection object creates the connection to the database. Microsoft Visual Studio .NET provides two types of Connection classes: the SqlConnection object, which is designed specifically to connect to Microsoft SQL Server 7.0 or later, and the OleDbConnection object, which can provide connections to a wide range of database types like Microsoft Access and Oracle. The Connection object contains all of the information required to open a connection to the database.

The Command Object

The Command object is represented by two corresponding classes: SqlCommand and OleDbCommand. Command objects are used to execute commands to a database across a data connection. The Command objects can be used to execute stored procedures on the database, SQL commands, or return complete tables directly. Command objects provide three methods that are used to execute commands on the database:

ExecuteNonQuery: Executes commands that have no return values such as INSERT, UPDATE or DELETE
ExecuteScalar: Returns a single value from a database query
ExecuteReader: Returns a result set by way of a DataReader object


The DataReader Object

The DataReader object provides a forward-only, read-only, connected stream recordset from a database. Unlike other components of the Data Provider, DataReader objects cannot be directly instantiated. Rather, the DataReader is returned as the result of the Command object's ExecuteReader method. The SqlCommand.ExecuteReader method returns a SqlDataReader object, and the OleDbCommand.ExecuteReader method returns an OleDbDataReader object. The DataReader can provide rows of data directly to application logic when you do not need to keep the data cached in memory. Because only one row is in memory at a time, the DataReader provides the lowest overhead in terms of system performance but requires the exclusive use of an open Connection object for the lifetime of the DataReader.

The DataAdapter Object

The DataAdapter is the class at the core of ADO .NET's disconnected data access. It is essentially the middleman facilitating all communication between the database and a DataSet. The DataAdapter is used either to fill a DataTable or DataSet with data from the database with it's Fill method. After the memory-resident data has been manipulated, the DataAdapter can commit the changes to the database by calling the Update method. The DataAdapter provides four properties that represent database commands:

SelectCommand
InsertCommand
DeleteCommand
UpdateCommand

When the Update method is called, changes in the DataSet are copied back to the database and the appropriate InsertCommand, DeleteCommand, or UpdateCommand is executed.

.Net Framework

1. What is .NET?
.NET - is the Microsoft Web services strategy to connect information, people, systems, and devices through software. Integrated across the Microsoft platform, .NET technology provides the ability to quickly build, deploy, manage, and use connected, security-enhanced solutions with Web services. .NET-connected solutions enable businesses to integrate their systems more rapidly and in a more agile manner and help them realize the promise of information anytime, anywhere, on any device. Reference


2. Which versions of .NET have been released so far?

The final version of the .NET 1.0 SDK & runtime were made publically available on 15 - Jan -2002. At the same time, the final version of Visual Studio.NET was made available to MSDN subscribers.

.NET 1.1 was released in April 2003, with bugs fixed. Visual Studio 2003 supports development of applications in version 1.1.

.NET 2.0 was launched in October 2005 for MSDN subscribers, and officially released in Nov 2005.

On - Jun - 2006, .NET 3.0 was launched. This version was earlier called WinFX. Visual Studio 2005 supports development of .NET 2.0 and .NET 3.0 applications. .NET 3 is comprised of the following:

Windows Communication Foundation
Windows Presentation Foundation
Windows Workflow Foundation
Windows Cardspace

The next version of Visual Studio, code named Orcas, Beta 1 has been released as a Beta Version. The .NET Framework 3.5 Beta is also available as a download.


3. Which versions of .NET have been released so far?

The final version of the .NET 1.0 SDK & runtime were made publically available on 15 - Jan -2002. At the same time, the final version of Visual Studio.NET was made available to MSDN subscribers.

.NET 1.1 was released in April 2003, with bugs fixed. Visual Studio 2003 supports development of applications in version 1.1.

.NET 2.0 was launched in October 2005 for MSDN subscribers, and officially released in Nov 2005.

On - Jun - 2006, .NET 3.0 was launched. This version was earlier called WinFX. Visual Studio 2005 supports development of .NET 2.0 and .NET 3.0 applications. .NET 3 is comprised of the following:

Windows Communication Foundation
Windows Presentation Foundation
Windows Workflow Foundation
Windows Cardspace

The next version of Visual Studio, code named Orcas, Beta 1 has been released as a Beta Version. The .NET Framework 3.5 Beta is also available as a download.

4. Which tools can be used for .NET Development?

The .NET Framework SDK is free and includes command-line compilers for C++, C#, and VB.NET and various other utilities to aid development.

SharpDevelop is a free IDE for C# and VB.NET.

Microsoft Visual Studio Express editions are cut-down versions of Visual Studio, for hobbyist or novice developers and are available for FREE Download at Microsoft site. Note that .NET 2.0 Framework gets downloaded along with Visual Studio Express & All versions above Visual Studio Express. Download Visual Studio Express

There are different versions for C#, VB, web development etc. Microsoft Visual Studio Standard 2005 is around $300, or $200 for the upgrade.

Microsoft VIsual Studio Professional 2005 is around $800, or $550 for the upgrade. At the top end of the price range are the Microsoft Visual Studio Team Edition for Software Developers 2005 with MSDN Premium and Team Suite editions. Visual Web Developer Express is available as a free download.

The next version of Visual Studio, code named Orcas, Beta 1 has been released as a Beta Version and is available for download. Download Orcas


5. Explain CLI, CIL, CTS, Metadata, CLS, IL and VES in .NET

CLI - Common Language Infrastructure. Microsoft has a piece of shared source, its the public implementation of ECMA Common Language Infrastructure. This shared code is code-named "Rotor". It has around 3 million lines of code. Those who are interesed in development of a language that targets the .NET Framework, may extensively make use of this CLI. The following topics are covered in the Shared Source CLI :

* The CLI type system
* Component packing & assemblies
* Type Loading & JIT Compilatino
* Managed code & Execution Engine (CLR)
* Description of Garbage Collection process & memory management
* The Platform Adaptation Layer (PAL): a portability layer for Win32®, Mac OS® X, and FreeBSD

Its been written by the Microsoft Team that has developed the .NET Framework.

Note: A compiled managed assembly is comprised of IL, Metadata and Manifest.

CIL Stands for Common Intermediate Language. Its actually a low level human readable language implementation of CLI. All .NET-aware languages compile the source oode to an intermediate language called Common Intermediate Language using the language specific compiler. It is also possible to build .NET assemblies direclty using CIL using the ilasm.exe compiler. This compiler is shipped along with the .NET Framework 2.0 SDK. CIL is the only language that allows access to each aspect of the CTS. CIL is the definition of the fundamentals of the .NET framework.

CTS - stands for Common Type Specification. It is at the core of .NET Framework's cross-language integration, type safety, and high-performance code execution. It defines a common set of types that can be used with many different language syntaxes. Each language (C#, VB.NET, Managed C++, and so on) is free to define any syntax it wishes, but if that language is built on the CLR, it will use at least some of the types defined by the CTS.

Metadata - is code that describes the compiled IL. A .NET language compiler will generate the metadata and store this in the assembly containing the CIL. Metadata describes all class members and classes that are defined in the assembly, and the classes and class members that the current assembly will call from another assembly. The metadata for a method contains the complete description of the method, including the class (and the assembly that contains the class), the return type and all of the method parameters. When the CLR executes CIL it will check to make sure that the metadata of the called method is the same as the metadata that is stored in the calling method. This ensures that a method can only be called with exactly the correct number of parameters and exactly the correct parameter types.

CLS - Common Language Specification. A type that is CLS compliant, may be used across any .NET language. CLS is a set of language rules that defines language standards for a .NET language and types declared in it. While declaring a new type, if we make use of the [CLSCompliant] attribute, the type is forced to conform to the rules of CLS.

IL - Intermediate Language, is the compiled form of the .NET language source code. When .NET source code is compiled by the language specific compiler (say we compile C# code using csc.exe), it is compiled to a .NET binary, which is platform independent, and is called Intermediate Language code. The .NET binary also comprises of metadata.

Its important to note here that metadata describes the IL, whereas manifest describes the assembly.

VES - Virtual Execution System. The Virtual Execution System(VES) provides an environment for executing managed code. It provides direct support for a set of built-in data types, defines a hypothetical machine with an associated machine model and state, a set of control flow constructs, and an exception handling model.To a large extent, the purpose of the VES is to provide the support required to execute the Common Intermediate Language instruction set.


6. What is CLR in .NET?

Common Language Runtime - It is the implementation of CLI. The core runtime engine in the Microsoft .NET Framework for executing applications. The common language runtime supplies managed code with services such as cross-language integration, code access security, object lifetime management, resouce management, type safety, pre-emptive threading, metadata services (type reflection), and debugging and profiling support. The ASP.NET Framework and Internet Explorer are examples of hosting CLR.

The CLR is a multi-language execution environment. There are currently over 15 compilers being built by Microsoft and other companies that produce code that will execute in the CLR.

The CLR is described as the "execution engine" of .NET. It's this CLR that manages the execution of programs. It provides the environment within which the programs run. The software version of .NET is actually the CLR version.

When the .NET program is compiled, the output of the compiler is not an executable file but a file that contains a special type of code called the Microsoft Intermediate Language (MSIL, now called CIL, Common Intermediate Language). This MSIL defines a set of portable instructions that are independent of any specific CPU. It's the job of the CLR to translate this Intermediate code into a executable code when the program is executed making the program to run in any environment for which the CLR is implemented. And that's how the .NET Framework achieves Portability. This MSIL is turned into executable code using a JIT (Just In Time) complier. The process goes like this, when .NET programs are executed, the CLR activates the JIT complier. The JIT complier converts MSIL into native code on a demand basis as each part of the program is needed. Thus the program executes as a native code even though it is compiled into MSIL making the program to run as fast as it would if it is compiled to native code but achieves the portability benefits of MSIL.

7. What is a Class Library in .NET?

Class library is the another major entity of the .NET Framework. This library gives the program access to runtime environment. The class library consists of lots of prewritten code that all the applications created in .NET aware languages and Visual Studio .NET will use. The code for all the elements like forms, controls and the rest in VB .NET applications actually comes from the class library.

Code in class libraries may be shared & reused. One of the core . NET libraries is mscorlib.dll. .NET language compilers reference this library automatically as it contains core types. A class library, contains types, that may be used by external applications. A class library may be a DLL or an EXE. Note that the .NET class libraries, even though have a same extension as the old COM Win32 binaries, yet they are very different internally.


8. Explain Managed code, managed class and managed data in .NET

Managed Code - The .NET framework provides lots of core runtime services to the programs that run within it. For example - security & exception handling. Such a code has a minimum level of information. It has metadata associated with it. Such a code is called Managed Code. VB.NET, C#, JS.NET code is managed by default. In order to make C++ code managed, we make use of managed extensions, which is nothing but a postfix _gc after the class name.

Managed Data - Data that is allocated & freed by the .NET runtime's Garbage collecter.

Managed Class - A class whose objects are managed by the CLR's garbage collector. In VC++.NET, classes are not managed. However, they can be managed using managed extentions. This is done using an _gc postfix. A managed C++ class can inherit from VB.NET classes, C# classes, JS.NET classes. A managed class can inherit from only one class. .NET does'nt allow multiple inheritance in managed classes.


9. What is an assembly in .NET? What is ILDASM?

Assembly - An assembly may be an exe, a dll, an application having an entry point, or a library. It may consist of one or more files. It represents a group of resources, type definitions, and implementation of these types. They may contain references to other assemblies. These resources, types & references are compacted in a block of data called manifest. The manifest is a part of the assembly, which makes it self-describing. Assemblies also increase security of code in .NET. An assembly maybe shared(public) or private. The assembly, overall comprises of 3 entities: IL, Manifest, Metadata. Metadata describes IL, whereas Manifest describes the assembly.

An assembly may be created by building the class(the .vb or .cs file), thereby producing its DLL.

ILDASM - The contents of an assembly may be viewed using the ILDASM tool, that comes with the .NET SDK or the Visual Studio.NET. The ildasm.exe tool may also be used in the command line compiler.


10. What is Reflection in .NET?

Reflection - The process of getting the metadata from modules/assemblies. When .NET code is compiled, metadata about the types defined in the modules is produced. These modules are in turn packaged as assemblied. The process of accessing this metadata in called Reflection.

The namespace System.Reflection contains classes that can be used for interrogating the types for a module/assembly. We use reflection for examining data type sizes for marshalling across process & machine boundaries.

Reflection is also used for:

1) To dynamically invoke methods (using System.Type.InvokeMember)
2) To dynamically create types at runtime (using System.Reflection.Emit.TypeBuilder).


11. What are the different types of assemblies in .NET?

An assembly may be Public or Private. A public assembly is also called a Shared Assembly.

A Satellite Assembly - is an assembly that contains only resources, and no code. The resources are location specific. A satellite assembly is associated with a main assembly, the one that actually contains the code.

11a. What is the difference between a Public Assembly and a Private Assembly?

An assembly is the basic building block in .NET. It is the compiled format of a class, that contains Metadata, Manisfest & Intermediate Language code.

An assembly may be either Public or Private. A public assembly means the same as Shared Assembly.

Private Assembly - This type of assembly is used by a single application. It is stored in the application's directory or the applications sub-directory. There is no version constraint in a private assembly.

Shared Assembly or Public Assembly - A shared assembly has version constraint. It is stored in the Global Assembly Cache (GAC). GAC is a repository of shared assemblies maintained by the .NET runtime. It is located at C:\Windows\Assembly OR C:\Winnt\Assembly. The shared assemblies may be used by many applications. To make an assembly a shared assembly, it has to be strongly named. In order to share an assembly with many applications, it must have a strong name.

A Strong Name assembly is an assembly that has its own identity, through its version and uniqueness.

In order to convert a private assembly to a shared assembly, i.e. to create a strongly named assembly, follow the steps below...

1) Create a strong key using the sn.exe tool. This is used to created a cryptographic key pair. The key pair that is generated by the Strong Name tool can be kept in a file or we can store it our your local machine's Crytographic Service Provider (CSP). For this, goto the .NET command interpreter, and type the following...

sn -k C:\samplekey.snk

This will create a strong key and save it to the location C:\samplekey.snk 2) If the key is stored in a file, just like we have done above, we use the attribute AssemblyKeyFileAttribute. This belongs to the namespace System.Reflection.AssemblyKeyFileAttribute. If the key was in the CSP, we would make use of System.Reflection.AssemblyKeyNameAttribute.

Go to the assemblyinfo.vb file of your project. Open this file. Make the following changes in this file...



We may write this in our code as well, like this...

Imports System.Reflection

Namespace StrongName
Public class Sample
End Class
End Namespace

3) Build your project. Your assembly is now strongly named.
Installing the Shared assembly in GAC...
Go to .NET command interpreter, use the tool gacutil.exe
Type the following...
gacutil /i sampleclass.dll
To uninstall it, use... gacutil /u sampleclass.dll. Visual Studio.NET provides a GUI tool for viewing all shared assemblies in the GAC.