







Protected Sub btnMultipleRowDelete_Click(ByVal sender As Object, ByVal e As EventArgs) ' Looping through all the rows in the GridView
For Each row As GridViewRow In GridView1.Rows Dim checkbox As CheckBox = CType(row.FindControl("cbRows"), CheckBox) 'Check if the checkbox is checked. 'value in the HtmlInputCheckBox's Value property is set as the //value of the delete command's parameter.
If checkbox.Checked Then
' Retreive the Employee ID
Dim employeeID As Integer = Convert.ToInt32(GridView1.DataKeys(row.RowIndex).Value)
' Pass the value of the selected Employye ID to the Delete //command.
SqlDataSource1.DeleteParameters("EmployeeID").DefaultValue = employeeID.ToString()
SqlDataSource1.Delete()
End If
Next row
End Sub
Use JavaScript to set up Microsoft's and the Mozilla-based browsers' different request objects.
Browser compatibility is an important consideration. You have to make sure the "engine" behind Ajax's server handshake is properly constructed, but you can never predict which browsers your users will favor.
The programming tool that allows Ajax applications to make HTTP requests to a server is an object that you can use from within JavaScript code. In the world of Firefox and Netscape (as well as Safari and Opera), this object is named XMLHttpRequest. However, continuing with the tradition established by IE 5.0, recent vintages of Internet Explorer implement the software as an ActiveX object named Microsoft.XMLHTTP or Msxml2.XMLHTTP.
Although Microsoft and the engineers on the Mozilla project have chosen to implement this object differently, we will refer to the ActiveX and XMLHttpRequest objects simply as "request objects" throughout this book, because they have very similar functionality.
As a first step in using Ajax, you must check if the user's browser supports either one of the Mozilla-based or ActiveX-related request objects, and then properly initialize the object.
Wrap the compatibility check inside a JavaScript function, then call this function before you make any HTTP requests using the object. For example, in Mozilla-based browsers such as Netscape 7.1 and Firefox 1.5 (as well as in Safari 2.0 and Opera 8.5), the request object is available as a property of the top-level window object. The reference to this object in JavaScript code is window.XMLHttpRequest. The compatibility check for these browser types looks like this:
if(window.XMLHttpRequest){
request = new XMLHttpRequest( );
request.onreadystatechange=handleResponse;
request.open("GET",theURL,true);
request.send(null);
}
The JavaScript variable request is to a top-level variable that will refer to the request object.
If the browser supports XMLHttpRequest, then:
if(window.XMLHttpRequest) returns true because the XMLHttpRequest is not null or undefined.
The object will be instantiated with the new keyword.
Its onreadystatechange event listener (see the section "XMLHttpRequest" earlier in this chapter) will be defined as a function named handleResponse( ).
The code calls the request object's open( ) and send( ) methods.
In this case, the window.XMLHttpRequest object will not exist in the browser object model. Therefore, another branch of the if test is necessary in your code:
else if (window.ActiveXObject){
request=new ActiveXObject("Microsoft.XMLHTTP");
if (! request){
request=new ActiveXObject("Msxml2.XMLHTTP");
}
if(request){
request.onreadystatechange=handleResponse;
request.open(reqType,url,true);
request.send(null);
}
}This code fragment tests for the existence of the top-level window object ActiveXObject, thus signaling the use of Internet Explorer. The code then initializes the request using two of a number of possible ActiveX program IDs (here, Microsoft.XMLHTTP and Msxml2.XMLHTTP).
You can get even more fine-grained when testing for different versions of the IE request object, such as Msxml2.XMLHTTP.4.0. In the vast majority of cases, however, you will not be designing your application based on various versions of the MSXML libraries, so the prior code will suffice.
The code then makes one final check for whether the request object has been properly constructed (if(request){...}).
Given three chances, if the request variable is still null or undefined, your browser is really out of luck when it comes to using the request object for Ajax!
Here's an example of an entire compatibility check:
/* Wrapper function for constructing a request object.
Parameters:
reqType: The HTTP request type, such as GET or POST.
url: The URL of the server program.
asynch: Whether to send the request asynchronously or not. */
function httpRequest(reqType,url,asynch){
//Mozilla-based browsers
if(window.XMLHttpRequest){
request = new XMLHttpRequest( );
} else if (window.ActiveXObject){
request=new ActiveXObject("Msxml2.XMLHTTP");
if (! request){
request=new ActiveXObject("Microsoft.XMLHTTP");
}
}
//the request could still be null if neither ActiveXObject
//initialization succeeded
if(request){
initReq(reqType,url,asynch);
} else {
alert("Your browser does not permit the use of all "+
"of this application's features!");
}
}
/* Initialize a request object that is already constructed */
function initReq(reqType,url,bool){
/* Specify the function that will handle the HTTP response */
request.onreadystatechange=handleResponse;
request.open(reqType,url,bool);
request.send(null);
}
While this article is placed in the upload subsection, it might not be the best place for ot. Because it's not a regular "how-to-upload- files-with-ASP.NET" article.
I might write such an article in the future but this is dealning with a problem you might encounter when using some sort of template-system on your site. I mean basically, all requests goes to a single ASPX page, such as default.aspx and depending on the context (for example sent in by a request variable) you load different user controls (ASCX) files.
For example:
default.aspx?page=start - might show start page
default.aspx?page=clientupload - might show a page when the client could upload a file to your server
Now, back to file upload. To upload a file you need to do two things:
1. Throw in a input type=file control
2. Set your forms enctype to multipart/form-data <form enctype="multipart/form-data" runat="server">
protected void EnsureEncType()
{
System.Web.UI.Control oParent = Parent;
while( oParent != null && oParent.GetType() != typeof( System.Web.UI.HtmlControls.HtmlForm ) && oParent.GetType().FullName != "System.Web.UI.Page" )
{
oParent = oParent.Parent;
}
System.Web.UI.HtmlControls.HtmlForm oForm = oParent as System.Web.UI.HtmlControls.HtmlForm;
if ( oForm != null )
oForm.Enctype = "multipart/form-data";
}
Setting up a live demo on your website is often important for your business - people want to see how the application looks and get a feeling of it and not all people are willing to download a trial version and go through a (painful?) install process just to get the first look. However, the problem is that you need to strip down the demo version a little bit. You don't want visitors to be able to change login password etc (after that noone would have access to the demo) or change information in your underlying database. Here's how I have solved it for my demosites for AdMentor and KBMentor. In short : I compile the application with an extra flag defined (DEMOVERSION) and in my code I insert some extra conditional code to behave differently when that flag DEMOVERSION is defined. First step is to create a custom project context Then we add the conditional variable (called DEMOVERSION): Now we can insert some conditional code.We do that by using the #if directive in our code. 

#if (DEMOVERSION)
here we can add code which only will be compiled in the special demoversion
#endif
I want to throw up a JavaScript when the user tries something not allowed - for example when trying to change password:

So, this is done by adding a JavaScript alert box to the onclick event:
private void Page_Load(object sender, System.EventArgs e)
{
EnsureEncType();
EnsureChildControls();
if ( !IsPostBack )
{
#if (DEMOVERSION)
btnUpdate.Attributes.Add("onclick", "alert('Not possible in demo version'); return false;");
btnDelete.Attributes["onclick"] = "alert('Not possible in demo version'); return false;";
#endif
Now, this is done in Page_Load and while this example is pretty easy to understand you might have a more finegrained structure of how to enable/disbale controls, for example based on current user rights, and/or after a lot of postbacks a certain button might be enabled etc. The easiest way to override such code without needing to make the original code much more complex is to leave it at is and make your changes in OnPreRender: protected override void OnPreRender(EventArgs e)
{
#if (DEMOVERSION)
btnDelete.Enabled = false;
btnDoUpload.Enabled = false;
btnOK.Enabled = false;
#endif
Here it doesn't matter what code has been executed and checked against all different kind of state - we just disable the buttons regardless of which. Now, the last thing to do. Not all people have JavaScript enabled - so those people must also be stopped. Here we need to add some serverside code in the actual handler functions: private void btnOK_Click(object sender, System.EventArgs e)
{
#if (DEMOVERSION)
return;
#endif
..regular code to save etc
While I bet you all know how to (from your own webpage) read another webpage, even located on another site/server, so while I will show you the code for it, I also want to show you a very practical use of it.
Background
As you might have seen I have created a new layout for this site, ASPCode.net. I am using the beta version of KBMentor but that's not what I want to talk about here. However, for reasons I won't get into, I wanted to create the site in directory aspcode.net/articles/ and therefore I naturally created a vdir (own application) in the articles drectory and thereaftter installed my KBMentor CMS.
Problem
One of the functions of KBMentor is to produce a Google SiteMap out of all the articles and pages. So I wanted to test it out - but ran into a big problem. The page to submit to Google SItemap is http://www.aspcode.net/articles/googl...map.ashx - but it wouldn't let me - simply because it is not located in the root of my domain. Moving the ashx page to the root wouldn't help at all, simply because another application is installed in that location.
Solution
Now to the solution. I did add a new ashx page in the root domain - and what is does is simply "screenscrape" the ashx file in the articles directory.
public void ProcessRequest (HttpContext context)
{
//Screenscrape
CookieContainer CC = new CookieContainer();
HttpWebRequest Req = (HttpWebRequest) WebRequest.Create("http://www.aspcode.net/articles/googlesitemap.ashx");
Req.CookieContainer = CC;
WebResponse webResponse = Req.GetResponse();
string sTxt = new System.IO.StreamReader(webResponse.GetResponseStream(),
System.Text.Encoding.Default).ReadToEnd();
webResponse.Close();
context.Response.ContentType = "text/xml";
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.Write( sTxt);
//
// TODO: Add constructor logic here
//
}
When moving your pages from one place to another it is very tempting to handle old inlinks by creating a simple Response.Redirect( sNewPage, true );
This sure will work, but this type of redirect is a 302 and is meant for temporary relocations of pages. But your pages are permanently moved and therefore you should use a 301 Moved Permanently status code. This should preserve your search engine rankings for that particular page.
To solve it you could install some sort of redirect filter(ISAPI dll). I was looking into those type of solutions and found IISMods URL Rewrite Filter for IIS.
Such a solution is very flexible and since it is a IIS filter it is possible to rewrite URL:s for all kind of filetypes, not only for aspx pages but say images (ex http://www.hello.com/*.gif could be transferred to http://www.hello.com/test/*gif ).
It is however not possible for everyone to install a ISAPI filter on their website, therefore I here present a solution on how you can achieve 301 redirects with pure ASP.NET code instead.
In your old page you can write code such as
private void Page_Load(object sender, System.EventArgs e)
{
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location","http://www.aspcode.net/newpage");
}
For me who wanted to redirect all calls to http://kbmentor.aspcode.net/whatever/it/could/be/foo.aspx to http://www.aspcode.net/articles/whatever/it/could/be/foo.aspx took and didn't have to think about pictures, cause they were "base" linked with the application took the idea one step further.
I created a new web application to install on kbmentor.aspcode.net. Basically it only contains a global.asax which handles Application_BeginRequest like this:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string sOldPath = HttpContext.Current.Request.Path.ToLower();
string sPage = "http://www.aspcode.net/articles/" + sOldPath;
Response.Clear();
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location",sPage);
Response.End();
}
The ASP.NET cache is simply fantastic, but there are some shortcomings. While it is so easy to create a cache item dependent on, say for example a XML file (meaning the cache item will expire when the file xxx.xml is changed) it is not so common for such scenarios in my opinion. Also, now in .NET 2.0 you can create SqlCacheDependencys, meaning an cached item will be expired (and therefore a fresh read fromthe database will be executed) when something in the database is changed (could be set on query level actually).
However, to me such solutions are so much overkill, lots of overhead and also (for SqlCacheDependency ) you tie your solution pretty much to SQL 2005.
Most often you just want to cache some data in your application, example
string sTxt = "";
if ( context.Cache["RSSFEED123"] == null )
{
sTxt = BuildXmlString(context);
context.Cache.Insert( "RSSFEED123", sTxt, ..some depencency object... );
}
else
sTxt = context.Cache["RSSFEED123"].ToString();
work with txt...
My point is that most often YOU have the control of knowing when the Cache item should expire. In 99.99% of my cases it should trigger when an administrator enters a new/changes an existing article or whatever in the admin GUI.
So, my solution (here I show it with no cachedependency at all, living for the lifetime of the whole application) but you can of course use it in conjunction with a cachedependency.
Code using it:
string sTxt = "";
if ( context.Cache["RSSFEED123"] == null )
{
sTxt = BuildXmlString(context);
context.Cache.Insert( "RSSFEED123", sTxt );
}
else
sTxt = context.Cache["RSSFEED123"].ToString();
Admin GUI:
private void btnUpdate_Click(object sender, System.EventArgs e)
{
//Save to database, then call global static function
HelpClasses.Context.InvalidateAllCache();
}
HelpClasses.Context:
public static void InvalidateAllCache()
{
if ( System.Web.HttpContext.Current.Cache["RSSFEED123"] != null )
System.Web.HttpContext.Current.Cache.Remove("RSSFEED123");
}
So inessence, when the administrator clicks the Save button we go to HelpClasses.Context.InvalidateAllCache() and it simply removes the item(s) from the cache.
I know I could maybe create a specialized cache dependency class derived from CacheDependency - but then the problem is that the GUI needs to communicate with it. I always take the easy way out, cause in the end it is all about delivering a working solution for the customer - not creating the most .NETed solution possible :)
I'm publishing this list for my own sake actually, never seem to remember which variable gives you what. Sourcecode and description behind the scenes to generate this table is available in Related articles.
ALL_HTTP HTTP_CONNECTION:Keep-Alive HTTP_ACCEPT:*/* HTTP_ACCEPT_ENCODING:gzip, deflate HTTP_ACCEPT_LANGUAGE:sv HTTP_HOST:localhost:1229 HTTP_USER_AGENT:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1) ALL_RAW Connection: Keep-Alive Accept: */* Accept-Encoding: gzip, deflate Accept-Language: sv Host: localhost:1229 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1) APPL_MD_PATH APPL_PHYSICAL_PATH D:\code\web\demos\membership\ AUTH_TYPE NTLM AUTH_USER SYSTEMEN-D9AE02\Stefan Holmberg AUTH_PASSWORD LOGON_USER SYSTEMEN-D9AE02\Stefan Holmberg REMOTE_USER SYSTEMEN-D9AE02\Stefan Holmberg CERT_COOKIE CERT_FLAGS CERT_ISSUER CERT_KEYSIZE CERT_SECRETKEYSIZE CERT_SERIALNUMBER CERT_SERVER_ISSUER CERT_SERVER_SUBJECT CERT_SUBJECT CONTENT_LENGTH 0 CONTENT_TYPE GATEWAY_INTERFACE HTTPS HTTPS_KEYSIZE HTTPS_SECRETKEYSIZE HTTPS_SERVER_ISSUER HTTPS_SERVER_SUBJECT INSTANCE_ID INSTANCE_META_PATH LOCAL_ADDR 127.0.0.1 PATH_INFO /membership/servervariables.aspx PATH_TRANSLATED D:\code\web\demos\membership\servervariables.aspx QUERY_STRING REMOTE_ADDR 127.0.0.1 REMOTE_HOST 127.0.0.1 REMOTE_PORT REQUEST_METHOD GET SCRIPT_NAME /membership/servervariables.aspx SERVER_NAME localhost SERVER_PORT 1229 SERVER_PORT_SECURE 0 SERVER_PROTOCOL HTTP/1.1 SERVER_SOFTWARE URL /membership/servervariables.aspx HTTP_CONNECTION Keep-Alive HTTP_ACCEPT */* HTTP_ACCEPT_ENCODING gzip, deflate HTTP_ACCEPT_LANGUAGE sv HTTP_HOST localhost:1229 HTTP_USER_AGENT Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)
While this solution might seems a little odd (or more correctly the problem might seem very odd) but this technique has sure solved a lot of problems for me. What I'm gonna show you is a was to manipulate the resulting HTML and ASP.NET page has generated just before it's sent to the browser. Now you might ask, isn't that what ASP Server controls are made for? To generate the HTML for you? Because there are certain times when the HTML or JavaScript it generates are not right and you might even not (if using a third party control) be able to modify the underlying control generating the code. For example I've had problems with some thirdparty components where I was unable to get it to render the correct paths for including images etc (it simply couldn't point to the specific location I had them stored). So, the plan is to somehow intercept the rendering, make my modifications to the HTML generated and then just pass my modified copy on to the browser. One other example (which I actually have used in some projects) is to create some sort of "template replacer", where others can create their own templates and also write some special tags that your application is supposed to replace with some meaningful - for example Thats the type of example I am gonna show you, consider this layout: Now, we are supposed to replace the $CURRENT_DATETIME text with current date and time. I.e we want this result when running: So first the code - all the magic happens in Render:
$currentarticle_name might be replaced with
the name of the current article (the one the user is browsing)

protected override void Render(HtmlTextWriter writer)
{
using(System.IO.MemoryStream msOur = new System.IO.MemoryStream())
{
using(System.IO.StreamWriter swOur = new System.IO.StreamWriter(msOur))
{
HtmlTextWriter ourWriter = new HtmlTextWriter(swOur);
base.Render(ourWriter);
ourWriter.Flush();
msOur.Position = 0;
using(System.IO.StreamReader oReader = new System.IO.StreamReader(msOur))
{
string sTxt = oReader.ReadToEnd();
sTxt = sTxt.Replace("$CURRENT_DATETIME", DateTime.Now.ToString());
Response.Write(sTxt);
oReader.Close();
}
}
}
}
What are we doing? Our overridden Render method gets called (not the Page.Render - which would render it to the browser). We create a new HtmlTextWriter ourWriter - which we send to the base.Render (i.e Page.Render()). However, ourWriter is connected to the streamwriter swOur - which in turn is connected to the memorystream msOur (instead of the outputstream of the response object). This way, ASP.NET does handle all the rendering the way it usually does - but the resulting HTML ends up in the memorystream msOur.
We then set the reading position of msOur to 0 - which means we can read from it from the beginning.And now we read everything from it (using the streamreader object) to our sTxt variable.
And now we have all the rendered HTML in sTxt - we can just replace the fabricated template tag $CURRENT_DATETIME with the current time.
And finally send it to the browser by Response.Write.
While there aren't much code for you to copy to get it going in your own project I have included a download zip file containing the solution and code files.
This function can be used to retrieve the current page:s name, i.e default.aspx, hello.aspx or whatever.
public string GetCurrentPageName()
{
string sPath = System.Web.HttpContext.Current.Request.Url.AbsolutePath;
System.IO.FileInfo oInfo = new System.IO.FileInfo(sPath);
string sRet = oInfo.Name;
return sRet;
}
By going through System.Web.HttpContext.Current object we are able to have this function in a generic dll or class - and not in each and every page needing to call it.
In this article we will create a simple one page ASP.NET web application, implementing paging using the cool MySQL feature LIMIT and SQL_CALC_FOUND_ROWS.
One of the coolest things about MySQL is some of its non standard features. It might sound like a weird thing to say, but being a web developer I just love the simplicity and performance MySQL gives me when it comes to paging. Cause in the typical web app you need paging.
The two problems a developer faces in such a paged web application
1. Two questions.
It's pretty neat to present a list of links to all pages available to the user, instead of just a next/prev link. Typically that means two questions.
select count(*) from bla bla ALL WHERE CONDIITIONS
select * from bla bla ALL WHERE CONDIITIONS
2. Just retrieving the rows for current page from the database.
It a waste memory to read 100000 records into a dataset and the use a pagedatasource. It's of course better to let the database engine do the filtering and having it just return the actual records to be displayed on the current page.
And also - you probably need to show the total number of pages available.
However when using the LIMIT clause in MySQL you solve the problem number two. As for number one - since we still need to get the total number of records, there is a feature for that as well, SQL_CALC_FOUND_ROWS.
So in short here's the code for reading the data:
public DataTable GetData
{
get
{
//Where to start???
long lStart = 0;
if (Request["p"] != null && Request["p"].Length > 0)
{
lCurrentPage = Convert.ToInt32(Request["p"]);
}
if ( lCurrentPage < 1 )
lCurrentPage = 1;
lStart = (lCurrentPage * lPageSize) - lPageSize;
string sSQL = "select SQL_CALC_FOUND_ROWS table_schema, table_name from information_schema.tables ";
sSQL += " order by table_schema, table_name ";
sSQL += "limit " + lStart.ToString() + "," + lPageSize.ToString() + ";";
sSQL += "select found_rows();";
DataSet ds = MySql.Data.MySqlClient.MySqlHelper.ExecuteDataset(System.Configuration.ConfigurationManager.AppSettings["ConnectionString"],
sSQL);
m_Data = ds.Tables[0];
lTotalCount = Convert.ToInt32(ds.Tables[1].Rows[0][0]);
return m_Data;
}
}
We add the SQL_CALC_FOUND_ROWS select modifier before the column list. This will tell MySQL to calculate the TOTAL number of rows and make it available in a special variable - which we get with select found_rows(). As you can see we do send both the queries in one command top the server and get them back in a dataset with the result in one table and the count in the second. That's so cool.
The rest of the code is just a matter of some math to calculate the current page (`query params ?p=12 etc) and of course rendering (the example uses a simple repeater)


ADO.NET Entity Framework is an object-relationship management (ORM) tool like Hibernate in java or N Hibernate for .net. ADO.NET Entity Framework is included with .NET Framework 3.5 Service Pack 1 and Visual Studio 2008 Service Pack 1. Please make sure you have and Visual Studio 2008 Service Pack 1 installed in your system. For more information about ADO.NET Entity Framework you can refer to Microsoft site.
One practical is worth more than a thousand words. So let us start with creating a very simple example.
Step 1: Create a database table.
Create a database in SQL Server 2005 and name it as Payroll.
On the payroll database create an Employee table as follows.
USE [Payroll]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Employee](
[EmployeeID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Title] [nvarchar](50) NOT NULL,
[BirthDate] [datetime] NOT NULL,
[MaritalStatus] [nchar](1) NOT NULL,
[Gender] [nchar](1) NOT NULL,
[HireDate] [datetime] NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[EmployeeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Step 2: Data Layer
In the visual studio 2008 Make a new Blank solution and name it as Payroll. In the solution add a new class library project. Name it as Payroll.Entities as shown in following image.
Remove the class1.cs from project. Add a new item to project a select. ADO.NET Entity data Model.
Rename it as Payroll.edmx. Click on add. Select generate from the database and click on next choose database connection and the given textbox for connection string rename it with PayrollDAO
From the next screen select the employee table and click on finish. Compile the project. Now data layer is ready for you.
Step 3: Business/Service Layer
In the solution Payroll add a new class library project. Name it as Payroll.Service. Rename the class1.cs as EmployeeService.cs. Make the reference to System.Data.Entity. and also add the refrence to Payroll.Entities project we have created. Now add two methods GetEmployee and AddEmployee. Your class should look like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Payroll.Entities;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
namespace Payroll.Service
{
public class EmployeeService
{
public List<Employee> GetEmployee()
{
PayrollDAO payrollDAO = new PayrollDAO();
ObjectQuery<Employee> employeeQuery = payrollDAO.Employee;
return employeeQuery.ToList();
}
public string AddEmpoyee(Payroll.Entities.Employee e1)
{
PayrollDAO payrollDAO = new PayrollDAO();
payrollDAO.AddToEmployee(e1);
payrollDAO.SaveChanges();
return "SUCCESS";
}
}
}
Compile the project. Service layer is ready for you.
Step 4: Presentation Layer
Add a new web site with name "WebApp" to the payroll solution and set it as startup project. In the default.aspx add a gridview and button as shown in following figure
Set button text to Add Employee. Make the reference to System.Data.Entity and also add the refrence to Payroll.Service project we have created in step 3.
Add the code on page load and buttion1_click, Default.aspx.cs should look like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Payroll.Service;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
EmployeeService es= new EmployeeService();
GridView1.DataSource = es.GetEmployee();
GridView1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
EmployeeService es = new EmployeeService();
DateTime dt = new DateTime(2008, 12, 12);
Payroll.Entities.Employee e1 = Payroll.Entities.Employee.CreateEmployee(0, "Anand", "Thakur", dt, "M", "M", dt);
es.AddEmpoyee(e1);
}
}
Copy the connectionStrings from App.config of Data Layer(Payroll.Entities) project and paste in web.config of web application
<connectionStrings>
<add name="PayrollDAO" connectionString="metadata=res://*/Payroll.csdl|res://*/Payroll.ssdl|res://*/Payroll.msl;provider=System.Data.SqlClient;provider connection string="Data Source=ATHAKUR;Initial Catalog=Payroll;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
connectionStrings>
Now build and run the web application.
Click on add employee, new employee should be added to database.
Conclusion:
This is a very basic example with single table. In the next part, I will try to include more tables with CRUD operations.
In my last article "Getting started with ADO.NET Entity Framework in .NET 3.5", we have done select and add operations, now let us extend with update and delete operations.
Now I have added there textboxes fro employee ID, name and title as follows. (you can find it with attached project)
Update:
There is no change in Data layer
In the business layer add the UpdateEmployee method
public string UpdateEmployee(Payroll.Entities.Employee e1)
{
PayrollDAO payrollDAO = new PayrollDAO();
try
{
Employee e2 = null;
e2 = (from emp in payrollDAO.Employee
where emp.EmployeeID == e1.EmployeeID
select emp).First();
e2.Name = e1.Name;
e2.Title = e1.Title;
payrollDAO.SaveChanges();
}
catch
{
return "ERROR";
}
return "SUCCESS";
}
In the Presentation layer, add the following code in update button click
protected void Button2_Click(object sender, EventArgs e)
{
EmployeeService es = new EmployeeService();
DateTime dt = new DateTime(2008, 12, 12);
Payroll.Entities.Employee e1 = Payroll.Entities.Employee.CreateEmployee(Convert.ToInt32(empID.Text), empName.Text, empTitle.Text, dt, "M", "M", dt);
Result.Text = es.UpdateEmployee(e1);
GridView1.DataSource = es.GetEmployee();
GridView1.DataBind();
}
Delete:
There is no change in Data layer
In the business layer add the DeleteEmployee method
public string DeleteEmployee(Payroll.Entities.Employee e1)
{
try
{
PayrollDAO payrollDAO = new PayrollDAO();
Employee e2 = (from emp in payrollDAO.Employee
where emp.EmployeeID == e1.EmployeeID
select emp).First();
payrollDAO.DeleteObject(e2);
payrollDAO.SaveChanges();
}
catch
{
return "ERROR";
}
return "SUCCESS";
}
In the Presentation layer, add the following code in delete button click
protected void Button3_Click(object sender, EventArgs e)
{
EmployeeService es = new EmployeeService();
DateTime dt = new DateTime(2008, 12, 12);
Payroll.Entities.Employee e1 = Payroll.Entities.Employee.CreateEmployee(Convert.ToInt32(empID.Text), "", "", dt, "M", "M", dt);
Result.Text = es.DeleteEmployee(e1);
GridView1.DataSource = es.GetEmployee();
GridView1.DataBind();
}
Now our CRUD operations are over, in next article we will try to include more tables with relationships.
Now in the example given in last tutorial update the GetEmployee method as follows
public static List<Employee> GetEmployee()
{
int skipValue = 50;
int limitValue = 25;
PayrollDAO payrollDAO = new PayrollDAO ();
ObjectQuery<Employee> employeeQuery = payrollDAO.Employee
.Where("it.Name = @eName", new ObjectParameter ("eName", "aaa"))
.Where("it.EmployeeID > @EmpID1 ", new ObjectParameter("EmpID1", 20083))
.Where("it.EmployeeID < @EmpID2 ", new ObjectParameter("EmpID2", 20099))
.Skip("it.Name", "@skip", new ObjectParameter("skip", skipValue))
.Top("@limit", new ObjectParameter("limit", limitValue));
return employeeQuery.ToList();
}
Conditional Query
As you can see from the code WHERE condition
.Where("it.Name = @eName", new ObjectParameter("eName", "aaa"))
Select the name whose value equal to eName parameter and next is the parameter passed in case it is 'aaa'. Please note that "it" is the default name given by Entity Framework. This will select all the employees with name 'aaa'.
You can add as much as WHERE conditions as you can see in the above example.
More information http://msdn.microsoft.com/en-us/library/bb896238.aspx
Paging
Paging in Entity framework is done by SKIP and TOP.
SKIP tells that from where the data should be picked up and TOP tells how many rows to be selected
int skipValue = 50;
int limitValue = 25;
.Skip("it.Name", "@skip", new ObjectParameter("skip", skipValue))
.Top("@limit", new ObjectParameter("limit", limitValue));
In this example it will skip first 50 rows, then starting from 51st row; it will show up to 75th row .You can also explore LIMIT method for paging
Introduction
Today data binding techniques are very easy to apply using IDE such as Microsoft Visual Studio.NET and Oralce JDeveloper. In this article, I will show how to develop a client/server enterprise application by applying the Model-View-Controller (MVC) design pattern and using development tools such as Microsoft Visual.NET and Oracle JDeveloper.
Data binding in Visual Studio.NET
In this section, we're going to build a two-tier enterprise application using Visual Studio.NET and the underlying data binding framework. The first step is to start the Visual Studio.NET, and then create a connection to the underlying database using Data Connection tree in the Server Explorer. Go to the Server Explorer window, right-click on the Data Connections node and choose Add Connection from the context menu. In the Add Connection dialog, enter the information to connect to the AdventureWorks database shipped with the installation of Microsoft SQL Server 2005 (see Figure 1).
Figure 1
Now let's create a solution and two projects: one as class library to package the business logic layer's components (see Figure 2) and the other as Windows Application (see Figure 3) to package the presentation layer's components.
Figure 2
Figure 3
Now we're going to create the business components for the business logic module. As illustrative, we're going to use the Production.Product and Production.ProductModel tables in the AdventureWorks. For this purpose, we're going to create the business entities using Dataset object model. In the Solution Explorer window, right-click on the BusinessLogicCompPkg project, select Add | New Item from the context menu and select Dataset item from the Add New Item dialog box (see Figure 4).
Figure 4
Once the DataSet designer is open, you can define business entities by right-clicking on the DataSet designer and selecting Add | TableAdapter option from the context menu. When the Table Adapter Configuration Wizard appears, in the Step 1, you choose the created data connection (see Figure 5). Click on Next button.
Figure 5
In the Step 2, you specify how to store the connection string in the configuration file. Click on Next button. In the Step 3, you can specify the access method to the database. In this case, we're going to write SQL statements (see Figure 6).
Figure 6
In the Step 4, you must write the underlying SQL SELECT statement (see Figure 7). Click on the Next button.
Figure 7
The final step is for choose the methods associated to the Data Adapter in order to interact with the data source (see Figure 8).
Figure 8
Repeat this step in order to create the ProductModel entity. After that, the data set resembles as in Figure 9.
Figure 9
Finally, compile this project and we're read to use these business components. Now let's move on to the presentation project. Let's add a MenuStrip control from the Toolbox onto the main form. In the menu, create a sub-menu named Entities with two inner child menus named Product and Product Model. Finally, let's add an event handler for the Click event for the Product and Product sub-menu (see Figure 10).
Figure 10
Now let's add two child forms to display data of the Product and ProductModel entities and a reference to the BusinessLogicCompPkg assembly in order to invoke its objects (see Figure 11).
Figure 11
Now let's work on the ProductForm. Go to the Data Sources window and click on Add New Data Source icon in order to open the Data Source Configuration Wizard. In the first step, we choose to consume the data from the objects (the business entities created before). Click on Next button. In the Step 2, choose the data objects to bind to the GUI application, in this case the ProductDS object (see Figure 12).
Figure 12
Now you can see the Product and ProductModel entities in the Data Sources window. The next step in the application is to configure the Product to be displayed in details mode (see Figure 13) and the.
Figure 13
You must configure the ProductModelID attribute as a combo box (Figure 14).
Figure 14
Drag and drop the ProductModel node from the Data Sources window onto the ProductModelID attribute.
Now we need to add the business logic using C# to fill the data set and update the data source from the changes from the data set (see Listing 1)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using BusinessLogicCompPkg;
using BusinessLogicCompPkg.ProductsDSTableAdapters;
namespace AppGUI
{
public partial class ProductForm : Form
{
public ProductForm()
{
InitializeComponent();
}
private void ProductForm_Load(object sender, EventArgs e)
{
ProductTableAdapter taProduct = new ProductTableAdapter();
taProduct.Fill(productsDS.Product);
ProductModelTableAdapter taProductModel = new ProductModelTableAdapter();
taProductModel.Fill(productsDS.ProductModel);
}
private void productBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.productBindingSource.EndEdit();
ProductTableAdapter taProduct = new ProductTableAdapter();
taProduct.Update(productsDS.Product);
}
}
}
Listing 1
Now let's go to the ProductModelForm form how to create a master/detail oriented form. Let's configure the ProductModel node as Details (see Figure 15).
Figure 15
Then drag and drop the ProductModel onto the ProductModelForm. Then, drag and drop the Product node inside the ProductModel node onto the ProductModelForm. Now we need to add the business logic to fill and update the Product and ProductModel (see Listing 2).
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using BusinessLogicCompPkg;
using BusinessLogicCompPkg.ProductsDSTableAdapters;
namespace AppGUI
{
public partial class ProductModelForm : Form
{
public ProductModelForm()
{
InitializeComponent();
}
private void ProductModelForm_Load(object sender, EventArgs e)
{
ProductTableAdapter taProduct = new ProductTableAdapter();
taProduct.Fill(productsDS.Product);
ProductModelTableAdapter taProductModel = new ProductModelTableAdapter();
taProductModel.Fill(productsDS.ProductModel);
}
private void productModelBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.productModelBindingSource.EndEdit();
this.productBindingSource.EndEdit();
ProductTableAdapter taProduct = new ProductTableAdapter();
taProduct.Update(productsDS.Product);
ProductModelTableAdapter taProductModel = new ProductModelTableAdapter();
taProductModel.Update(productsDS.ProductModel);
}
}
}
Listing 2
Data binding in JDeveloper
In this section, we're going to build a two-tier enterprise application using ADF Business Components as the business layer containing the business logic, validations and business rules and ADF Swing as the presentation layer for gathering and displaying information.
The first step is to start the JDeveloper, and then create a connection to the default ORCL database (shipped with Oracle database installation) using JDBC as the main API to access the relational data source from your application. Go to the Connections Navigator window, right-click on the Database node and choose New Database Connection from the context menu. The Create Database Connection Wizard appears then; click on Next button and in the Step 1 set a name for the connection (see Figure 16). Then click on the Next button.
Figure 16
In the Step 2, you must enter the authentication information (see Figure 17). Click on Next button.
Figure 17
In the Step 3, you must specify the connection details (see Figure 18). Click on Next button.
Figure 18
And finally, you test the created connection.
Now let's create the application by going to the Applications Navigator, right-click on the Applications node and select New Application from the context menu. In the Create Application dialog box, enter the name for the application, the working directory and the application package prefix (see Figure 19).
Figure 19
Then, create a project for the business logic components (see Figure 20).
Figure 20
Now we're going to create the business components for the business logic module. As illustrative, we're going to use the SCOTT schema shipped with the default installation of Oracle. For this purpose, we're going to create the business entities using ADF Business Components based on tables. In the Application Navigator window, right-click on the business_logic project and select New from the context menu and select Business Components from Tables from the New Gallery dialog box (see Figure 21). Click on OK button.
Figure 21
Then, a window appears where you have to select the connection to the database and click on OK button and then the Create Business Components Wizard appears. Click on Next button; and in the Step 1, you must select a list of tables for which you want to create entity objects. You can also change the name of the business entities by clicking on Selected list and typing the new name in the Entity Name field (see Figure 22). Click on the Next button.
Figure 22
In the Step 2, you can create the views associated to the entities created in the Step 1. Select all the entities and change the name of the views as well as to add them to a new package (see Figure 23). Click on the Next button.
Figure 23
In the Step 3, you can create read-only business entities. In our example, we don't need to create this kind of view. Then click on the Next button. In the Step 4, you set the name for the application module (see Figure 24). The application module bundles together the components and enables transaction support as well as other important data-centric services. Click on the Next button.
Figure 24
In the Step 5, you can specify the diagram of the components and their relationships (see Figure 25).
Figure 25
Click on the Next button, and you can see the result of the Wizard, and finally click on the Finish button.
Before you create to the presentation layer, let's implement several business logic, format and validation code according to our business requirements. Go to the Applications Navigator and double-click on the Department entity and the Entity Object Editor window appears. Go to the Attributes node to select the attributes to be customized then go the Control Hits tab which enables to specify its format for the graphical presentation of the entity.
For the Deptno attribute, we have (see Figure 26).
Figure 26
And for the Dnam attribute, we have (see Figure 27).
Figure 27
Finally, for the Loc attribute, we have. We can go on using the same approach for the rest of the attributes of the Employee entity (see Figure 28).
Figure 28
Now let's develop the Presentation Layer components. Go to the Application Navigator and add a new project named client_presentation (see Figure 29).
Figure 29
The right-click on the project and select New from the context menu, go to the Client Tier/ ADF Swing node and select Empty Form as the main form (see Figure 30).
Figure 30
Disable the Generate a menu bar checkbox (because we're going to create a customized menu bar) and set a name for the main form in the Wizard such as MainForm (see Figure 31).
Figure 31
Now let's design the main menu of the application by drag and drop JMenuBar from Components Palette to the form. Then, create a sub-menu named Entities with inner child menus named Employee and Department. Finally, let's add an event handler for the actionPerformed event for the Employee and Department sub-menus (see Figure 32).
Figure 32
Now it's time to add the child forms by right-clicking on the project and selecting New from the context menu (see Figure 33 and Figure 34).
Figure 33
Figure 34
Let's work on the EmployeeForm. First of all, select the navigation bar (this is generic for each table) and delete it. Now, go to the Data Control palette, and drag and drop the EmployeeVO1 onto the form, and from the Context Menu select Add Child | Navigation Bar. The go to the Data Control palette and drag and drop the Empno attribute from the EmployeeVO1 node onto the form, and from the Context Menu select Child | Text Field. Repeat this step for each attribute of the EmployeeVO1 node.
Now let's add a label for each text field to describe it. Go to the Component Palette, select the ADF Swing Controls library, and drag and drop a JULabel onto the form in front of the Empno textfield. Right-click on the JULabel and select Create Binding | Label For from the context menu in order to bind this control to metadata defined on the Business Component Entity Object. When the Attribute Binding Editor window is open, then go to the EmployeeVO1, and choose the Empno attribute (see Figure 35).
Figure 35
Now let's repeat this step for each attribute of the EmployeeVO1 node. It's remarkable to say that in the case of the Depno attribute, actually we don't want to display the department number, instead we want to display the department name using a combo box control which allows to select a from a list of department name. Drag and drop the Deptno attribute on EmployeeVO1 from the Data Control Palette onto the form and then choose Add Child | Combo box. If you run the application, you can see a list of department number.
In order to bind the department number to department name, you need to set up the underlying binding. Go to the Applications Navigator window, and navigate to the EmployeeFormPageDef.xml and then go to the Structure window, and double-click on the EmployeeVO1Deptno node and the List Binding Editor appears. Select the Dynamic List option, then click on Add… button and inside the Add Data Source window, select the DepartmentVO1 node (see Figure 36).
Figure 36
Next, you have to map the attributes from the Base Data Source and the List Data Source. Finally, set the Display Attribute to Dept to DName (see Figure 37).
Figure 37
When you run this application which resembles as shown in Figure 38.
Figure 38
The last part of this solution is to show how to create a master/detail oriented form. The first step is to create a form to display department data along with the associated employees using the master/detail concepts related to data binding. This approach is similar to the previous data binding tasks, the only difference is that you will base the binding on the DepartmentVO1 and its inside view EmployeeVO2 (see Figure 39).
Figure 39
After the form is created, we drag and drop the DepartmentVO1 onto the form and select Add Edit Form from the context menu (see Figure 40).
Figure 40
Then, in order to add a child entity in this case the employees associated to their department (the parent), drag and drop the EmployeeVO2 inside the DepartmentVO1 node onto the form and select Add Child | Table from the context menu. In order to navigate inside the table as well, we need to drag and drop the EmployeeVO2 inside the DepartmentVO1 node onto the form and select Add Child | Navigation Bar. Now let's test the application and see how it resembles as shown in Figure 41.
Figure 41
As you can see the last column of the table (showing the department number) is displaying a number and not the department name. We can solve this problem like we did before. Right-click on the Table control and select ADFm Binding Properties and then the Table Binding Editor appears. Then go to the Attribute Properties tab and select the Deptno and map it to a combo box. Finally, click on the configuration button, and the Editor Properties appears (see Figure 42).
Figure 42
By clicking on Create button, the List Binding Editor window appears, and we can configure the same way as we did in the employee form (see Figure 43).
Figure 43
The final step is to deploy the solution to the production environment using a Java Archive file (JAR). To create JAR in JDeveloper, you have to go to the client_presentation project, right-click over it and choose New from the context menu. In the New Gallery window, go to the Deployment Profiles node and select JAR file (see Figure 44).
Figure 44
Then a new profile with the specified name is created on the project and you have to edit it to customize your deployment. In order to create the JAR file from this customized deployment, you go to the project, right-click on the deploy extension file inside the Resources folder and select Deploy to JAR file option (see Figure 45).
Figure 45
Conclusion
In this article, I explain how to create data binding oriented applications using Microsoft Visual Studio.NET and Oracle JDeveloper. You can compare both solutions and apply this techniques to your own business scenario.
How to add an autonumber column in a DataGridView control that is populated with a DataTable in simple steps ?
Figure.1
The first column in Figure.1 displays sequential row numbers. I have achieved this output by using the following function.
private DataTable AutoNumberedTable(DataTable SourceTable)
{
DataTable ResultTable = new DataTable();
DataColumn AutoNumberColumn = new DataColumn();
AutoNumberColumn.ColumnName="S.No.";
AutoNumberColumn.DataType = typeof(int);
AutoNumberColumn.AutoIncrement = true;
AutoNumberColumn.AutoIncrementSeed = 1;
AutoNumberColumn.AutoIncrementStep = 1;
ResultTable.Columns.Add(AutoNumberColumn);
ResultTable.Merge(SourceTable);
return ResultTable;
}
Refer http://msdn.microsoft.com/en-us/library/yctw654b.aspx on How to: Create an Autonumber DataColumn
Explanation
The function receives a DataTable as parameter. It create a Data Table, ResultTable. Then add a Data Column,AutoNumberColumn with auto incrementing behaviour. Then the SourceTable is merged with the ResultTable. The Merge method will add the rows of the source table to the destimation table one by one. Consequently, autonumber column values are generated as sequential row numbers
Implementation
In a few minutes, we will create a Windows Forms Application to test the case. Create a Windows Form and add a DataGridView. Write the following code in the Load event of the form.
private void Form1_Load(object sender, EventArgs e)
{
using(SqlConnection Connection=new SqlConnection(this.ConnectionString))
{
using (SqlCommand Command= Connection.CreateCommand())
{
Command.CommandText = "SELECT * FROM [myTable]";
SqlDataAdapter dataAdapter=new SqlDataAdapter(Command);
DataTable dataTable = new DataTable();
dataAdapter.Fill(dataTable);
this.dataGridView1.DataSource = AutoNumberedTable(dataTable);
}
}
}
Then add the ConnectionString property given below and AutoNumberedTable function given above in the body of the form. Run the program. See what happens!
private string ConnectionString
{
get
{
SqlConnectionStringBuilder ConnectionBuilder = new SqlConnectionStringBuilder();
ConnectionBuilder.DataSource = "myDataSource";
ConnectionBuilder.InitialCatalog = "myDatabase";
ConnectionBuilder.UserID = "myUserID";
ConnectionBuilder.Password = "myPassword";
return ConnectionBuilder.ToString();
}
}
SqlConnectionStringBuilder provides a simple way to create and manage the contents of connection strings.
Refer http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder(VS.80).aspx on SqlConnectionStringBuilder Class
Details of Sample Application Seen in Figure.1
Database : Pubs
Query : "SELECT au_fname + ' ' + au_lname as [Name of Author],City FROM AUTHORS"
Add the following namespaces on top.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
Happy Coding! Happy Dotneting!
Adding a C# image button became incredibly easy with .NET Framework 2.0 and up. An image-button is a way to create a user-friendly .NET user interface.
As with many .NET controls, the key is setting the correct Properties.
The first property you want to modify is Image. The image will have to be a resource of the Form. However it is a good idea in most cases to let it be a project resource so the image can accessed anywhere in the project.
This is a great .NET control property: TextImageRelation. It has 5 options and they are pretty self-explanatory. Basically it denotes the order in which text and image of a C# button are rendered. Here is some different looks that can be achieved:

It is not a good idea to set TextImageRelation to Overlay if your .NET button has both text and an image since the text won't be readable. However if the button has no text, it looks good:
![]()
Of course since these are .NET control properties we are talking about, they can updated run-time, opening up a world of possibilites. For example, a series of menu buttons can have the option of displaying text along side each icon or just displaying the icon.
So as you can see it does not take too much work to have a great looking .NET image button. Starting from the .NET Framework 2.0 these image buttons are fairly constant with different FlatStyle and versions of Windows.
However one "problem" is that the button is tied to Windows' version. An image button might look very good in Windows Vista or Windows 7 but might not look as eye-candy in older versions of Windows. For those looking for a more constant look across versions would have to turn to code-generated .NET buttons.
And finally, in order to get a good-looking C# image button you are going to need good icons. Here is where many programmers considering investing in professional icons.
© All Rights Reserved. DOTNET TUTORIALS
Theme by : PHP Web Hosting | Converted into Blogger Templates by Theme Craft | Falcon Hive
