Vous êtes sur la page 1sur 46

You should know that IIS is not used to host the website instead Visual Studio 2005

starts an ASP.Net Development Server(Cassini). This server chooses a port randomly


for hosting the website. If you test a website and then restart the Visual Studio 2005
then the port used changes and hence the tests recorded earlier would become
invalid. It is possible to configure Visual Studio 2005 to use a particular port all the
time. Press F4 and go to the Properties window. Here you can see that the ‘Use
Dynamic Ports’ value is set to True. Change this to False and select a port number to
use.

Forms in ASP.NET

Web pages in ASP.Net are called ASP.NET Web Forms which have certain server
controls such as text, dropdown list, checkboxes, and buttons. An ASP.NET Web
Form looks similar to the web forms in HTML. The only difference is that in ASP.NET,
the Web Forms runs at the server side and in HTML the web forms runs at the client
side. Apart from this difference an ASP.NET Web Form has more features than an
ordinary HTML web form such as:

• The code blocks are processed on the server.


• The entire page in ASP.NET is compiled when it is requested for the first time.
When you make subsequent requests, the page is not compiled but shown directly in
your browser.
• ASP.NET Web Forms can contain page directives. Page directives allow you to set
the default language and user controls tags for the entire page. You can also turn off
session state and ViewState management using page directives.
• An ASP.NET Web Form can contain both user controls and Server side Includes
(SSIs).
• An ASP.NET Web Form though run on the server can contain client side script such
as JavaScript or Jscript.

ASP.NET user controls have extension .acsx and can be used in any page after
they are made (similar to server-side includes). It is like a “black box”.

You can create a user control by using the Register directive. This process is called
registering the user control. For instance, you can use this code to register a user
control:

<%@ Register TagPrefix="sampNamespace" TagName="Myname"


Src="mypage.ascx" %>

The TagPrefix is the exclusive namespace provided to the user control so that
multiple ASP.NET User Controls with similar name can be discriminated from each
other. The TagName is the name of the user control and the Src is the virtual path to
the user control. After registering the user control you can place the tag of the user
control in an appropriate location on the web form. You have to include the
runat=”server” attribute with the tag.
SOME ADMINISTRATION PART

When you install IIS after .NET framework, you have may have to do the following
things

For Error: Failed to access IIS metabase

aspnet_regiis –I

For Error: A name was started with an invalid character. Error processing resource
'http://localhost/IssueTracker/Default.aspx'. Line...

Go to IIS Manager > Your Virtual Folder > Properties > ASP.NET Tab > Set the
ASP.NET version to 2.(……)

For Error: Mutex could be created

It seems like Visual studio 2005 and the web application pool running ASP.NET 2.0 are
having a conflict over the temporary folder.
The workaround I have got for now is:
- If you have visual studio 2005 is open, close it
- Go tot the ASP.NET temporary folder for v2.0 of the framework
<Windows dir>\Microsoft.Net\Framework\v2.0<extra numbers>\Temporary ASpNET
pages
- Remove the folder for your application (or all of them)
- Reset IIS (on a command line window, >iisreset) [not always needed, but I had to use it
sometimes]
- First Browse your page from IE (http://localhost/your app)
- Then reopen Visual studio

And it should work now


ASP.NET and HTML DOM

HTMLDocument and HTMLElement are the primary classes.

HTMLDocument can take the html file from webBrowser control of Visual Studio.

HTMLElement (Explanation of some properties)

For Example for:

<DIV ID="test"><B>This is a demo for inner/outer text/html


combinations</B></DIV>

a) innerText This is a demo for inner/outer text/html combinations


b) outerText no difference when read
c) innerHTML <B>This is a demo for inner/outer text/html
combinations</B>
d) outerHTML <DIV ID="test"><B>This is a demo for inner/outer
text/html combinations</B></DIV>

HTMLDocument.All Property returns a collections of all HTML tags and can be parsed
in a foreach loop. For example if used with a normal HTML page. First it will show the
full HTML tag part (that would cover the entire doc itself), then it would show for HEAD
part , then BODY…..and so on.

STREAMS AND STREAMREADERS/WRITERS AND FILESTREAM

When you are using these, do not forget to flush() and close(). Otherwise it will not work.

StreamWriter writer = File.CreateText(@"c:\feed1.xml");


writer.WriteLine(textBox1.Text);

writer.Flush(); //these two lines


writer.Close(); /// are very important
BASICS OF STREAMS AND USING BUFFER

Suppose you want to read from a stream named “str” and write it
to a file c:\newfeed.xml.

Stream str = wres.GetResponseStream();


FileStream fstr = new FileStream(@"c:\newfeed.xml",
FileMode.OpenOrCreate, FileAccess.Write);
int length=10000;
Byte[] buffer = new byte[length];
int bytesRead = str.Read(buffer, 0, length);
while (bytesRead > 0)
{
fstr.Write(buffer, 0, bytesRead);
bytesRead = str.Read(buffer, 0, length);
}
str.Close();
fstr.Close();

Here “str” is the inputstream from where we have to read. First we read
10,000 bytes from the “str” and put in the buffer(0 denotes—we are using the buffer from
starting). This read operation automatically takes the position to 10,000 in the stream.
bytesRead contains 10000 (the nos. of bytes we have read). Then we write the contents of
the buffer to the outputstream “fstr” (0 denotes we are reading from staring of buffer).

↑ This is “str” stream

After first str.Read(buffer, 0, length); (diagram above)

We repeat this operation and pointer advances. fstr.Write(buffer, 0, bytesRead)


appends the existing output stream.

AMPERSAND SIGN and WEB/APP.XML

While writing any url (for instance the value of key-value pair) in the web/app.xml
replace & with &amp; (encoding).

Eg: http://amdus:Py197eWkl@feedpartnerus.pricerunner.com/Feed.jsp?
f=amdus&categories=682&show=properties&alllinks=1&limit=200

has to be written as

http://feedpartnerus.pricerunner.com/Feed.jsp?
f=amdus&amp;categories=682&amp;show=properties&amp;alllinks=1&amp;limit
=200
READING FROM AND WRITING TO A FILE (with some changes)

FileStream fstr_for_replace = new FileStream(@”c:\file_to_be_read”,


FileMode.Open, FileAccess.ReadWrite);

//FileMode has to be "open" so that file just got is opened for reading

StreamReader rdr = new StreamReader(fstr_for_replace);


StreamWriter wtr = new StreamWriter(@”c:\destination_file”);

//two steams –one for reading and one for writing

while (!rdr.EndOfStream)
{
string line = rdr.ReadLine(); //reading line by line and storing it
line = line.Replace("™", ""); //in string so that string functions
/////////can be done
wtr.WriteLine(line);
}
wtr.Flush(); ///to dump the contents of “wtr” to “c:\destination_file”
wtr.Close();
fstr_for_replace.Close();

REGISTERSTARTUPSCRIPT / REGISTERCLIENTSCRIPTBLOCK

RegisterStartupScript places the JS on the bottom of the page while


RegisterClientScriptBlock places the js on the top of the page.

So RegisterStartupScript is used when some script has some dependencies on the server
controls otherwise it will show object not found error.

SYNTAX:
String Script = "";
//Script += "<script type='text/javascript'>\n";
Script += "alert('The first statement of javascript');\n";
Script += "alert(document.getElementById('TextBox1').value);\n";
Script += "function checkNoSelection() {\n";
Script += "if ((document.getElementById('rb1').checked == false) &&
(document.getElementById('rb2').checked == false) &&
(document.getElementById('rb3').checked == false))\n";
Script += "{\n";
Script += "alert('Please select a choice');\n";
Script += "}\n";
Script += "}\n";// end of function1
Script += "function checkTextBox1() {\n";
Script += "if (document.getElementById('TextBox1').value == '') {\n";
Script += "alert('Please fill TextBox1');}};\n";//end of if,second func
//Script += "</script>\n";
if (!Page.ClientScript.IsStartupScriptRegistered("clientscript"))
{
Page.ClientScript.RegisterStartupScript(this.GetType(),
"clientscript", Script, true);
/// true adds <script> tags
}

Button1.Attributes.Add("onclick","checkNoSelection();checkTextBox1();");

-----------------------------------------------------------------------

ADDING CHECKBOX TO A GRIDVIEW

Drag n Drop a Gridview. Attach a DataTable to the DataSource property of it.


Gv1.datasource=GetDataTable();

- Add “Columns” to it. Add a “TemplateField” to it.


- “Edit Templates”.- “Item Templates”- Add a Checkbox control…

Practical Scenario: A Datatable is returned from the back-end. You want to perform
operations in some selected rows. This is done through Checkbox. To perform some
operations, first add a column to DataKeyNames property. This acts like a Primary Key.
This is very important.

To do all of the above dymanically (through cs file), make separate class for template
which derives from ITemplate. It will control the Checkbox control

-------------------------------------------------------------------------------------------------------
DEBUGGING IN ASP.NET

Debugging only a particular function (like a button click) that also which does not
executes directly (like a class library……..WebPart). Use "attach to process" debug
process, then select the concerned process….then attach a breakpoint…… then do "step
over" to move on. For Webparts, process could be wss.

-------------------------------------------------------------------------------------------------------

MEMBERSHIP AND ROLES IN ASP.NET

1) Create a ASP.NET Application.


2) Click on the ASP.NET Configuration icon in the Solution Explorer.
3) Select Security”Select Authentication type”Select “From the Internet”
4) Enable Roles. Create 3 roles: administrator,users,power users.
Create a user “srout” as admin.
5) Hit “Refresh” in the solution explorer. You will see a new folder APPDATA
under which ASPNETDB.MDF would be present. Check the tables. You will the
users and roles data.
6) Lets make the default.aspx page. We need to check if the user is authenticated and
no need to re-login if he is authenticated. For this use the “LoginView” control.
Click the ► of the control.
a) Anonymous You are not logged in. Add link to Login.aspx and
CreateAccount.aspx.
b) Logged-inWelcome “LoginName” control. Add link to
ChangePassword.aspx
7) Lets make the Login.aspx page. Drag the “Login” control. For
PasswordRecoveryText property write “Forgot Password?”. For
PasswordRecoveryURL give the link to ForgotPassword.aspx.
8) Drag the “PasswordRecovery” control to ForgotPassword.aspx and the change the
“Mail Defination” property of it. Again to use mails ->Go to ASP.NET
configurationApplication tabconfigure SMTP mail settings.
9) Implement the “ChangePassword” control in ChangePassword.aspx
10) Implement the “Create User Wizard” in Create Account Page. Here we can add a
new wizard step (say choose your role). Write “Choose your Role” and add a
listbox.
Then go the source page go the “Wizard Step” part add a property
onactivate=”ActivateStep” and onDeactivate=”DeactivateStep”. Define the methods
ActivateStep and DeactivateStep as below.
protected void ActivateStep(object sender, EventArgs e)
{
ListBox1.DataSource = Roles.GetAllRoles();
ListBox1.DataBind();
}
protected void DeactivateStep(object sender, EventArgs e)
{
Roles.AddUserToRole(User.Identity.Name,ListBox1.SelectedValue);
}

11) Create a user “mike” with role “User”.


12) Now suppose there are 2 dummy pages ManageAccounts.aspx and
DisplayReports.aspx which should only be accessible to Admins and not to
normal users. To do this add a folder named “Admin” in the Solution Explorer
and move the 2 files into it. Open ASP.NET Configuration
ManagerSecurityCreate Access RuleClick Admin Folder, Role Admin,
Allow. Create another access ruleAdmin Folder, All Users, Deny.
Behind the scenes it creates a web.config in the Admin Folder and writes this.
<system.web>
<authorization>
<allow roles="administrators" />
<deny users="*" />
</authorization>
SQL Server SSIS and SSRS

To install SQL Server Reporting Services first install SQL Server 2005 Express
with Advanced Services as it has reporting services/SQLExpress Database
Engine/Management Studio in it. The only problem is it does not have SSRS/SSIS
templates for Visual Studio. To achieve that uninstall SQL Server 2005 from Add
Remove programs –> Select Workstation Components (Do not uninstall the
DatabaseEngine and Reporting Services) and install the SQL server 2005
Standard/Enterprise Edition Client Tools. (\SQL Server 2005
Enterprise\Tools\Setup.exe)Your purpose will be fulfilled however SQLExpress
Reporting Services do not have the Report Builder (does not matter )

Tutorial link: http://www.accelebrate.com/sql_training/ssis_tutorial.htm

To open SSRS from SQL Mgmt Studio use


http://localhost/ReportServer$SQLExpress for ServerName

Use http://localhost/Reports$SQLExpress for browsing reports in Internet Browser

Configuring SSRS 2008 Express on Vista ( a pain in ass)


1) After installing SQL Server 2008 Express with Advanced Services on Visa , When
you will try to publish a report from BIDS. It ll say “Access denied”.
Solution
Open BIDS by right-click  Run as Administrator. It ll work out fine. (vista sucks)

2)When you ll open http://localhost/Reports_SQLExpress in IE 7/8 Browser you ll not


see any menu. Cause is vista Protected mode is on. Solution right click  Run as
Administrator. If it still does not work try right click  Run as Administrator with
Mozilla/Chrome, it ll work out fine. After that explicitly give that specific user rights
through “Site Settings”.

3)If you have any Sym Key/Signing issue, just go to SQL Server Config. Manager,
Delete all Encryped keys/data. It ll work out fine.

SSIS

A SSIS Package will contain mainly 4 things.

1. Connections to data sources.


2. Data flows- includes Source, Destination, Transformation and their paths.
3. Control flows- contains tasks (such as executing SQL or transfer objects
from one SQL server to another) and Data flow Task (no. 2). Thus Data
flows are a part of Control flows.
4. Event handlers, which are workflows that runs in response to the events
raised by a package, task, or container

Deploying SSIS package in SQL Server

Click File  “Save copy of package as..” Choose SSIS package store or Choose
SQL Server. If you choose SSIS package store, the package will be
stored as /File System/Package1. If you choose SQL Server, the
package will be stored as /MSDB/Package1.

Some points regarding SSIS

1)foreach loop "container"

2)format-->auto format

3)format-->auto layout

4)variables , add variables , namespace

5)try part 1, chap 4, quickstart of book MS SQL Server 2005 IS by Kirk

6)try the SSIS menu item

7)double clicking on "join" of two task in "Data flow" gives data flow path editor
(contains mapping metadata). Try changing its "name" and "path annotation"

8)Check the "Data Viewer" tab in "data flow path editor". Its cool. kinda Debugger.

9)Enable logging thru SSIS menu. give the provider (flat file). You can even view in
the "Log Events" window thru View-->Other Windows.

Unpivoting a Table means converting a row having multiple fields to multiple rows.
Q-) why SSIS package stored in server pc cannot be run through Mgmt Studio in
Client PC (w/o having SSIS installed in the client PC)

A-) When you execute the package from Management Studio, it runs the package on
the client. Since you don't have SSIS server

components on workstation, you can't run the package this way from the
workstation.

You can however schedule the package as a job on the server from Management
Studio on workstation, and then start this job -

also from workstation. The job and the package will run on server in this case.

This leads us to the second question: if I want to run my package on a remote


machine, without installing SSIS locally - how can I do it? There are many options,
the most common are (1) use SQL Agent, (2) create a custom Web service
application. To use Agent you need to create a job on the machine where you want
to run the package, configure the job to use the appropriate proxy account, create a
step that executes the package. Now you can either schedule the job, or start it
manually from SQL Server Management Studio, or start it programmatically by
executing sp_start_job stored procedure.

connecting to remote SSIS server

Step1)http://msdn.microsoft.com/en-us/library/aa337083.aspx

Step2)http://mohansmindstorms.spaces.live.com/Blog/cns!69AE1BEA50F1D0E7!
213.entry?action=post&wa=wsignin1.0

Step3)http://www.etiennek.com/2008/01/16/connect-to-ssis-service-on-machine-
sqlserver01-failed/
• SQL Server Agent is not found in SQLEXPRESS

• To connect to SQL server in win2003 use . or localhost as servername.

Execute SSISPackage thru Jobs (SQL Server Agent)

1) Right Click --> Add Job --> Step-->New Step-->SSIS Package --> Give Package details. -->
done.

2) use msdb

exec sp_start_job RunSSISPackage

go

Three ways to execute SSIS Package thru code in Webservice hosted in the same SQL
Server.

Suppose the SSIS package is at D:\Subhasis\ISProject2\ISProject2\Package.dtsx in the SQL


Server.

a) app.LoadPackage("D:\Subhasis\ISProject2\ISProject2\Package.dtsx", null);

b) app.LoadFromSqlServer("Package", "localhost", String.Empty, String.Empty, null);

c) app.LoadFromDtsServer("/File System/Package", "localhost", null);


calling a SSIS Package in a remote SQL Server thru WebServices not working (thru Client).

so use sp_start_job stored procedure. Thats the only way till now.

http://blogs.msdn.com/michen/archive/2007/03/22/running-ssis-package-programmatically.aspx

(contains all prons/cons of all ways to call ssis prgramatically)

http://www.codeproject.com/KB/aspnet/Deployment_SSIS_NET.aspx

(The webserver needs to have Integration Service installed (not the whole SQL Server) to use the
SSIS Object model and call SSIS Package programatically through its object model. Calling SSIS
package through its Object model has the advantage of passing parameters to it)

To use DTEXEC utilty

1) Go to SQL Server command prompt

2) C:\Program Files\Microsoft SQL Server\90\NotificationServices\9.0.242\Bin>dtexec

/f Package2.dtsx /set \package.variables[Business_Name].Value;abcxyz

Use of xp_cmshell

-- To allow advanced options to be changed.

EXEC sp_configure 'show advanced options', 1

GO
-- To update the currently configured value for advanced options.

RECONFIGURE

GO

-- To enable the feature.

EXEC sp_configure 'xp_cmdshell', 1

GO

-- To update the currently configured value for this feature.

RECONFIGURE

GO

EXEC xp_cmdshell 'dtexec /f "D:\Subhasis\ISProject3\ISProject3\ISProject3\Package2.dtsx"'

DateTime in SQL Server

1)
select h.SalesOrderNumber, h.ShipDate, h.CustomerID, d.OrderQty,
d.ProductID, d.LineTotal FROM
Sales.SalesOrderHeader h
JOIN
Sales.SalesOrderDetail d on d.SalesOrderID=h.SalesOrderID
where
h.ShipDate BETWEEN convert(VARCHAR(10),'01/01/2002',103) AND
convert(VARCHAR(10),'01/05/2002',103)
ORDER BY
h.ShipDate, h.SalesOrderNumber //There is a date in the query

2)
SELECT CONVERT(VARCHAR(10), GETDATE(), 103)

3)

SELECT CONVERT(VARCHAR(11), GETDATE(), 106)

For more information

http://www.sql-server-helper.com/tips/date-formats.aspx
To call SSIS package remotely from client and with parameters ...great ..what I was looking for

source:https://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=3400941&SiteID=17
(Very good)

alter procedure CallXPCmdShell

@Param1 nvarchar(50)

as

begin

declare @cmdStr nvarchar(1000)

set @cmdStr = 'DTEXEC /FILE "D:\Subhasis\ISProject3\ISProject3\ISProject3\Package2.dtsx"'

set @cmdStr = @cmdStr + ' ' + '/SET \package.variables[Business_Name].Value;'+@param1

exec xp_cmdshell @cmdStr

end

Then call this stored proc from your webpage.


public void RunSSISRemotely

SqlConnection jobConnection;

SqlCommand jobCommand;

SqlParameter jobReturnValue;

SqlParameter jobParameter;

int jobResult;

jobConnection = new SqlConnection("Server='nodd-7713';Initial


Catalog=AdventureWorks;Integrated Security=true");

jobCommand = new SqlCommand("CallXPCmdShell", jobConnection);

jobCommand.CommandType = CommandType.StoredProcedure;

jobParameter = new SqlParameter("@Param1", SqlDbType.VarChar);

jobParameter.Direction = ParameterDirection.Input;

jobCommand.Parameters.Add(jobParameter);

jobParameter.Value = TextBox1.Text;

jobConnection.Open();
jobCommand.ExecuteNonQuery();

jobConnection.Close();

C# ANONYMOUS METHODS AND PREDICATE DELEGATES


using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpFeatures
{
class Program
{
static void Main(string[] args)
{
List<Customer> list = new List<Customer>();
list = GetCustomers();

//gets all customers in Noida


//List<Customer> l = list.FindAll(delegate(Customer c)
// { return c.City == "Noida"; });

foreach (Customer c in GetCustomerByLocation(list,"Hapur"))


Console.WriteLine(c.Name);
Console.Read();
}

static List<Customer> GetCustomerByLocation(List<Customer>


fullList, string location)
{
return fullList.FindAll(delegate(Customer cust)
//"predicate delegate" which returns boolean
{ return cust.City == location; });
}

static List<Customer> GetCustomers()


{
List<Customer> custList = new List<Customer>();

Customer c = new Customer();


c.Name = "Subhasis";
c.City = "New Delhi";
c.CustId = 1;
custList.Add(c);
c = new Customer();
c.Name = "Avisek";
c.City = "Noida";
c.CustId = 2;
custList.Add(c);

c = new Customer();
c.Name = "Ajeet";
c.City = "Hapur";
c.CustId = 3;
custList.Add(c);

c = new Customer();
c.Name = "Mudit";
c.City = "Noida";
c.CustId = 4;
custList.Add(c);

return custList;

}
}
public class Customer
{
private string name;
private string city;
private int custId;

public string Name


{
get { return name; }
set { name = value; }
}
public string City
{
get { return city; }
set { city = value; }
}
public int CustId
{
get { return custId; }
set { custId = value; }
}
}

WINDOWS WORKFLOW FOUNDATION


(Book: Pro WF Windows Workflow in .NET 3.0)
Basics
namespace HelloWorkflow
{
class Program
{
static void Main(string[] args)
{
WorkflowRuntime workflowRuntime = new WorkflowRuntime();
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted
+= delegate(object sender, WorkflowCompletedEventArgs e)
{
waitHandle.Set();
};
workflowRuntime.WorkflowTerminated
+= delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};
WorkflowInstance instance
= workflowRuntime.CreateWorkflow(typeof(HelloWorkflow.Workflow1));
instance.Start();
waitHandle.WaitOne();
}
}
}

The code starts by


creating an instance of the WorkflowRuntime class. As the name implies, this is the
all-important class
that is actually in charge of running the workflow. The class also provides a number
of events and
methods that permit you to monitor and control the execution of any workflow.
The host application must create only a single instance of the WorkflowRuntime
for each
AppDomain. Most simple applications are implemented as a single AppDomain, so
this restriction really
means that a single WorkflowRuntime is created for an entire application.

Next, an instance of the AutoResetEvent class is created. This is a thread


synchronization class
that is used to release a single waiting thread. Thread synchronization you say?
Exactly what threads
do you need to synchronize? When a workflow executes, it does so in a separate
thread that is created
and managed by the workflow runtime. This makes sense since the workflow runtime
is capable of
handling multiple workflows at the same time. In this example, the two threads that
must be
synchronized are the workflow thread and the main thread of the host console
application.
In order for the host console application to know when the workflow has completed,
the code
subscribes to two events of the WorkflowRuntime class: WorkflowCompleted and
WorkflowTerminated.
It uses the .NET 2.0 anonymous delegate syntax for this, implementing the event
handler code inline
rather than referencing a separate method.
When a workflow completes normally, the WorkflowCompleted event is raised and
this code
is executed:
waitHandle.Set();
This signals the AutoResetEvent object, which releases the console application from
its wait.
If an error occurs, the WorkflowTerminated event is raised and this code is executed:
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
This displays the error message from the exception and then releases the waiting
thread. There
are other events that can be used to monitor the status of a workflow, but these are
the only two that
we need in this example.
Once the workflow runtime has been prepared, an instance of the workflow is created
and
started with this code:
WorkflowInstance instance
= workflowRuntime.CreateWorkflow(typeof(HelloWorkflow.Workflow1));
instance.Start();
The CreateWorkflow method has several overloaded versions, but this one simply
requires the
Type of the workflow that you want to create as its only parameter. When a workflow
is created, it
doesn’t begin executing immediately. Instead, a WorkflowInstance object is returned
from this method
and used to start the execution of the workflow.
Finally, the console application suspends execution of the current thread and waits
until the
AutoResetEvent object is signaled with this code:
waitHandle.WaitOne();

Passing Parameters
Workflows would have limited usefulness without the ability to receive parameter input. Passing
parameters to a workflow is one of the fundamental mechanisms that permit you to affect the
outcome of the workflow.
The preceding example writes a simple string constant to the Console. Let’s now modify that
example so that it uses input parameters to format the string that is written. The parameters will be
passed directly from the host console application.

Declaring the Properties


Input parameters can be passed to a workflow as normal .NET CLR (Common Language Runtime)
properties. Therefore, the first step in supporting input parameters is to declare the local variables
and properties in the workflow class. You can start with the Workflow1.cs file from the previous
example and add the following code shown in bold to the Workflow1 class:

public sealed partial class Workflow1 : SequentialWorkflowActivity


{
private String _person = String.Empty;
private String _message = String.Empty;
/// <summary>
/// The target of the greeting
/// </summary>
public String Person
{
get { return _person; }
set { _person = value; }
}
/// <summary>
/// The greeting message
/// </summary>
public String Message
{
get { return _message; }
set { _message = value; }
}
public Workflow1()
{
InitializeComponent();
}
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("Hello Workflow!");
}
}
Two local variables and their associated properties define all of the input parameters that are
needed for this example.
Next, you can modify the Console.WriteLine statement in the codeActivity1_ExecuteCode
method shown previously to use the new variables like this:
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
//display the variable greeting
Console.WriteLine("Hello {0}, {1}", _person, _message);
}

Passing Values at Runtime


The Program.cs file requires a few changes in order to pass the new parameters to the workflow.
Listing 1-3 shows the revised code for Program.cs in its entirety. The additions and changes from the
previous example are highlighted in bold.

Listing 1-3. Program.cs Code to Pass Runtime Parameters


#region Using directives
using System;
using System.Collections.Generic;
using System.Threading;
using System.Workflow.Runtime;
#endregion
namespace HelloWorkflow
{
class Program
{
static void Main(string[] args)
{
WorkflowRuntime workflowRuntime = new WorkflowRuntime();
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted
+= delegate(object sender, WorkflowCompletedEventArgs e)
{
waitHandle.Set();
};
workflowRuntime.WorkflowTerminated
+= delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};
//create a dictionary with input arguments
Dictionary<String, Object> wfArguments
= new Dictionary<string, object>();
wfArguments.Add("Person", "Bruce");
wfArguments.Add("Message", "did the workflow succeed?");
WorkflowInstance instance = workflowRuntime.CreateWorkflow(
typeof(HelloWorkflow.Workflow1),
wfArguments);
instance.Start();
waitHandle.WaitOne();
Console.WriteLine("Press any key to exit");
Console.ReadLine();
}
}
}
Input parameters are passed to a workflow as a generic Dictionary object. The Dictionary must
be keyed by a String and use an Object as the value for each parameter entry. Once the Dictionary
object is created, you can use the Add method to specify the value for each parameter that the
workflow
expects.

Notice that the key to each parameter in the Dictionary is an exact match to one of the workflow
public properties. This is not an accident. In order for the parameters to make their way into the
workflow, the names must match exactly, including their case. Likewise, the Type of the parameter
value must match the expected Type of the property. In this example, both properties are of type
String, therefore a string value must be passed in the Dictionary.

■ Note If you do manage to misspell a parameter name, you’ll receive an


ArgumentException during execution.
For example, if you attempt to pass a parameter named person (all lowercase) instead of
Person, you’ll
receive an ArgumentException with the message “Workflow Services semantic error: The
workflow ‘Workflow1’
has no public writable property named ‘person’.”
If the parameter name is correct but the value is of the incorrect type, the message will be
“Invalid workflow
parameter value.”

The only other required change is to actually pass the Dictionary object to the workflow. This is
accomplished with an overloaded version of the CreateWorkflow method as shown here:
WorkflowInstance instance
= workflowRuntime.CreateWorkflow(typeof(HelloWorkflow.Workflow1),
wfArguments);

When this example application is executed, the results indicate that the parameters are
successfully passed to the workflow:
Hello Bruce, did the workflow succeed?
Press any key to exit

Calculator Example in WF

C:\Documents and
Settings\Fun Zone\My Documents\Visual Studio 2005\Projects\WorkflowCalc.zip
Points to note:

- Make use of Workflow library project.


- _workflowRuntime.WorkflowCompleted
+= delegate(object sender, WorkflowCompletedEventArgs e)
{
_result = (Double)e.OutputParameters["Result"]; //Use of WF output param
_waitHandle.Set();
};
- Set the library Proj as startup proj  Go to its proj propertiesDebug TabStart
Action= Start External Program (CalculatorClient.exe)

Dependency Properties in WF:


-This dialog allows you to select a dependency property of the workflow or another
activity to bind to this property. Binding means that at runtime, the value of this activity
property is set to the value obtained from another activity or the workflow. The use of
dependency properties is what makes this kind of binding possible. (Pg 134).

To add a Dependency prop. Use Code Snipper. Go to Code BehindRight ClickInsert


SnippetWorkflowDependency property.

Example :
public static DependencyProperty SalesItemIdProperty
= System.Workflow.ComponentModel.DependencyProperty.Register(
"SalesItemId", typeof(Int32), typeof(Workflow1));
/////Workflow1 is the name of the CLASS having this
dependency property
/// <summary>
/// Identifies the item to sell
/// </summary>

[Description("Identifies the item to sell")]


[Category("CodeActivity Example")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

public Int32 SalesItemId


{
get
{
return ((Int32)(base.GetValue(Workflow1.SalesItemIdProperty)));
}
set
{
base.SetValue(Workflow1.SalesItemIdProperty, value);
}
}

- Custom activity (simple ones) should be derived from base Activity class rather than
base SequenceActivity class (this one is by default when you add a activity) as the latter
is a composite activity and enables you to host other child activity. No harm in using it
but can confuse the user of the custom activity.

- While Using Custom Activity, start using dependency properties (using snippets) from
the beginning. Override the execute method by simply writing “override” and using
intellisense.

-Notice that the private instance variables used in the CodeActivity example have been
omitted from this workflow(Custom Activity example). Those variables are needed in
that example since they are used to pass state between each execution of a CodeActivity
(by CodeActivity setting the values of private variables and If-else using them) . In this
example, the same data is passed directly between activities using their bound
dependency properties. This eliminates the need for the private instance
variables.

-After making the custom activites, you have to build the workflow – to make Custom
Activites show up in the Toolbox.

After adding event handlers, the workflow runtime engine is started by calling the
StartRuntime method. Calling this method isn’t strictly required in this example since
the runtime will automatically start when you create your first workflow. This example
doesn’t add any core workflow services, but if it did, they would be registered with the
workflow runtime prior to calling the StartRuntime method.

Custom Acti. validate, toolboxitem , make notesPg 158,184

CONNECTION POOLING IN .NET

Connection Pooling Basics


Opening a database connection is a resource intensive and time consuming operation.
Connection pooling increases the performance of Web applications by reusing active
database connections instead of creating a new connection with every request.
Connection pool manager maintains a pool of open database connections. When a new
connection requests come in, the pool manager checks if the pool contains any unused
connections and returns one if available. If all connections currently in the pool are busy
and the maximum pool size has not been reached, the new connection is created and
added to the pool. When the pool reaches its maximum size all new connection requests
are being queued up until a connection in the pool becomes available or the connection
attempt times out.
Connection pooling behavior is controlled by the connection string parameters. The
following are four parameters that control most of the connection pooling behavior:
Connect Timeout - controls the wait period in seconds when a new connection is
requested, if this timeout expires, an exception will be thrown. Default is 15
seconds.
Max Pool Size - specifies the maximum size of your connection pool. Default is 100.
Most Web sites do not use more than 40 connections under the heaviest load
but it depends on how long your database operations take to complete.
Min Pool Size - initial number of connections that will be added to the pool upon its
creation. Default is zero; however, you may chose to set this to a small number
such as 5 if your application needs consistent response times even after it was idle
for hours. In this case the first user requests won't have to wait for those database
connections to establish.
Pooling - controls if your connection pooling on or off. Default as you may've
guessed is true. Read on to see when you may use Pooling=false setting.

Common Problems and Resolutions

Connection pooling problems are almost always caused by a "connection leak" - a


condition where your application does not close its database connections correctly and
consistently. When you "leak" connections, they remain open until the garbage collector
(GC) closes them for you by calling their Dispose method. Unlike old ADO, ADO.NET
requires you to manually close your database connections as soon as you're done with
them. If you think of relying on connection objects to go out of scope, think again. It may
take hours until GC collects them. In the mean time your app may be dead in the water,
greeting your users or support personnel with something like this:
Exception: System.InvalidOperationException Message: Timeout expired. The timeout
period elapsed prior to obtaining a connection from the pool. This may have occurred
because all pooled connections were in use and max pool size was reached. Source:
System.Data at
System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectio
nString options, Boolean& isInTransaction) at
System.Data.SqlClient.SqlConnection.Open() ...
Exception: System.InvalidOperationException
Message: Timeout expired. The timeout period elapsed prior to obtaining a connection
from the pool. This may have occurred because all pooled connections were in use and
max pool size was reached.
Source: System.Data
At
System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectio
nString options, Boolean& isInTransaction)
at System.Data.SqlClient.SqlConnection.Open()
Closing your connections
When you intend to close your database connection, you want to make sure that you are
really closing it. The following code looks fine yet causes a connection leak:
SqlConnection conn = new SqlConnection(myConnectionString);
conn.Open();
doSomething();
conn.Close();

If doSomething() throws an exception - conn will never get explicitly closed. Here is
how this can be corrected:
SqlConnection conn = new SqlConnection(myConnectionString);
try
{
conn.Open();
doSomething(conn);
}
finally
{
conn.Close();
}
or
using (SqlConnection conn = new SqlConnection(myConnectionString))
{
conn.Open();
doSomething(conn);
}
Did you notice that in the first example we called conn.Close() explicitly while in the
second one we make the compiler generate an (implicit) call to conn.Dispose()
immediately following the using block? The C# using block guarantees that the Dispose
method is called on the subject of the using clause immediately after the block ends.
Close and Dispose methods of Connection object are equivalent. Neither one gives you
any specific advantages over the other.

How does a Connection Pool work? (from a different Website)


Connection pools are actually containers that contain open and reusable connections.
Multiple pools can exist in the same application domain at the same point in time,
but Connection Pools cannot be shared across application domains. Note that one
pool is created per unique connection string. A Connection Pool is created the first time a
request for a connection to the database comes in with a unique connection string. Note
that if another request comes in with a different connection string for the database,
another Connection Pool would be created. Hence, we have one Connection Pool per
connection string and not per database. The following code listings below illustrate
this.

Listing 1

// A new pool is created.


SqlConnection sqlConnection = new SqlConnection();
sqlConnection.ConnectionString =
"Server=localhost;Database=test;User ID=joydip;Password=joydip;Trusted_Connection=False";
sqlConnection.Open();

Listing 2

// A new pool is created as the connection strings differ.


SqlConnection conn = new SqlConnection();
sqlConnection.ConnectionString =
"Server=localhost;Database=test;User ID=test;Password=test;Trusted_Connection=False";
sqlConnection.Open();

Listing 3
// The connection string is the same as in Listing 1 so no new pool is created.
SqlConnection conn = new SqlConnection();
sqlConnection.ConnectionString =
"Server=localhost;Database=test;User ID=joydip;Password=joydip;Trusted_Connection=False";
sqlConnection.Open();

Page Life Cycle and ViewState

Browser Request  HTTP Handler Factory  ASP.NET Page Life Cycle Begins

Q- )What does __ViewState Hidden Field contains


A-)
1) Any programmatic change of state of the ASP.NET page and its controls. Like
Dymanically setting the ‘text’ property of a label or dynamically binding to DDL.
Note: Statically binding a DDL to a datasource does not come into this category.

2) Any data stored by the developer using the Viewstate property [Key-Value]

Page LifeCycle

1. PreInit - This is the only event where programmatic access to master pages and
themes is allowed. Dynamic Controls should be created here. Controls created
during Design time(except controls in MasterPage) are initialized here.
2. Init
3. InitComplete
4. LoadViewState
5. LoadPostbackdata – This is responsible for loading postback data. Like something
written on the Textbox, Checkbox checked etc. Note: ViewState is not
responsible for this. Try this with ViewState off and it will work.
6. PreLoad
7. Load
8. RaisePostbackEvent
9. LoadComplete
10. PreRender
11. PreRenderComplete
12. SaveViewState
13. SaveControlState
14. Render
15. UnLoad

VIEWSTATE/PAGE LIFECYCLE EXAMPLE 1 (IMP)

• It contains a single Label control (lbl) with its “Text” property set to
“statictext”
• It contains a Button control (btnA) with code in its event handler that sets
the “Text” property of “lbl” to “dynamictext”
• It contains a Button control (btnB) whose purpose is to cause a page
postback

Now, let us examine what will happen during the page life cycle.

1. The page is first loaded


1. The compiled class of the page is generated and “statictext” is
assigned to “lbl.Text”
2. Tracking for Viewstate is enabled in the “InitComplete” event
3. “LoadViewState” is not fired because there is no postback
4. “SaveViewstate” is fired, but nothing happens because no change of
state is recorded
5. The page is rendered with the value “statictext” inside “lbl”
2. btnA is clicked
1. The previously generated compiled class is handed the request;
“lbl.Text” is set to “statictext”
2. Tracking for Viewstate is enabled
3. “LoadViewState” is fired, but nothing happens because no change of
state was recorded in the previous page visit
4. “RaisePostbackEvent” event is executed and “btnA” click event
handler is fired; “lbl.Text” is set to “dynamictext”; since tracking is
enabled at this stage, this item is tracked (marked as “Dirty”).
5. “SaveViewState” is fired; “dynamictext” is serialized and stored in
the __VIEWSTATE field
6. The page is rendered with the value “dynamictext” inside “lbl”
3. btnB is clicked
1. The previously generated compiled class is handed the request;
“lbl.Text” is set to “statictext”
2. Tracking for Viewstate is enabled
3. “LoadViewState” is fired; since a change of state was recorded from
the previous page visit, __VIEWSTATE is loaded and the value
“dynamictext” is extracted; this value is then assigned to “lbl”
4. “RaisePostbackEvent” event is executed; nothing happens here
because “btnB” has no event handler for its “Click” event
5. “SaveViewState” is fired, but nothing happens because no change of
state is recorded
6. The page is rendered with the value “dynamictext” inside “lbl”

TRY PRESSING BUTTON btnB with EnableViewState=false on the Label. It


will show “StaticText”.

ViewstateDemo.zip

VIEWSTATE/PAGE LIFECYCLE EXAMPLE 2 (V.IMP)

Disabling Viewstate would obviously reduce Viewstate size; but, it surely kills the
functionality along the way. So, a little more planning is required…

Consider the case where you have a page with a drop down list that should display
the countries of the world. On the “Page_Load” event handler, you bind the drop
down list to a data source that contains the countries of the world; the code that
does the binding is wrapped inside a “!IsPostback” condition. Finally, on the page,
you have a button that when clicked should read the selected country from the drop
down list. With the setup described above, you will end up with a large
__VIEWSTATE field. This is due to the fact that data bound controls (like the drop
down list) store their state inside the Viewstate. You want to reduce Viewstate; what
options do you have?

1. Option 1: Simply disable the Viewstate on the drop down list


2. Option 2: Disable the Viewstate on the drop down list, and remove the “!
IsPostback” condition
3. Option 3: Disable the Viewstate on the drop down list, and move the binding
code without the “!IsPostback” condition to the “OnInit” or “OnPreInit”
event handlers

If you implement Option 1, you will reduce the Viewstate alright, but with it, you will
also lose the list of countries on the first postback of the page. When the page
first loads, the code in the “Page_Load” event handler is executed and the list of
countries is bound to the list. However, because Viewstate is disabled on the list, this
change of state is not saved during the “SaveViewState” event. When the button
on the page is clicked causing a postback, since the binding code is wrapped inside a
“!IsPostback” condition, the “LoadViewState” event has nothing saved from the
previous page visit and the drop down list is empty. If you implement Option 2, you
will reduce the Viewstate size and you will not lose the list of countries on postback.
However, another problem arises: because the binding code is now executed
at each “Page_Load”, the postback data is lost upon postback, and every
time, the first item of the list will be selected. This is true because in the page
life cycle, the “LoadPostbackdata” event occurs before the “Load” event. Option
3 is the correct option. In this option, you have done the following:

• Disabled Viewstate on the drop down list


• Removed the “!IsPostback” condition from the binding code
• Moved the binding code to the “OnInit” event handler (or the “OnPreInit”
event handler)

Since the “Init” event occurs before the “LoadPostbackdata” in the page
life cycle, the postback data is preserved upon postbacks, and the selected
item from the list is correctly preserved.

Now, remember that in Option 3, you have successfully reduced the Viewstate size
and kept the functionality working; but, this actually comes at the cost of rebinding
the drop down list at each postback. The performance hit of revisiting the data
source at each postback is nothing when compared with the performance boost
gained from saving a huge amount of bytes being rendered at the client’s
__VIEWSTATE field. This is especially true with the fact that most clients are
connected to the Internet via low speed dial up connections

MAILING THRU CLIENT OUTLOOK

First Way
// Creates a new Outlook Application Instance
Microsoft.Office.Interop.Outlook.Application objOutlook = new
Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.Inspector objInspector;
// Creating a new Outlook Message from the Outlook Application Instance
Microsoft.Office.Interop.Outlook.MailItem mi =
(Microsoft.Office.Interop.Outlook.MailItem)
(objOutlook.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailIte
m));
objInspector = mi.GetInspector;
mi.To = txtProdOwner.Text;
mi.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
mi.Subject = hdnItemCode.Value + " - " +
hdnItemversion.Value + " : " + hdnItemDescription.Value;
mi.HTMLBody ="<span style='font-size:10.0pt;font-
family:\"Arial\",\"sans-serif\"'>"+

"Hi " + txtProdOwner.Text + "," + "<br/><br/>" +


"Kind regards," + "<br/>" +
Session["fullName"].ToString() + "</span><br/><br/>";

//fire outlook
mi.Display(true);

The above approach requires Outlook installed in Server as well

Second way
The other way is to use mailto HTML attribute but you can only send simple
unformatted mails and not HTML mails using mailto.

USING LOG4NET

1) Add a ref to log4net.dll


2) Add a xml file (say log4net.xml) with the following content
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="C:\\Subhasis\\Testing\\Testing\\log.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger -
%message%newline" />
</layout>
</appender>
<appender name="RollingFileAppender"
type="log4net.Appender.RollingFileAppender">
<file value="C:\\Subhasis\\Testing\\Testing\\Rollinglog.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger -
%message%newline" />
</layout>
</appender>
<appender name="EventLogAppender"
type="log4net.Appender.EventLogAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger -
%message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="FileAppender" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="EventLogAppender" />
</root>
</log4net>

In this example, I have configured three types of logger. In practical apps one is
enough. (refer documentation)

3) Initialize the logger with the following line:

private static readonly log4net.ILog log =


log4net.LogManager.GetLogger(typeof(Testing.Log4NetDemo));

This should be done at class level. In a practical app., you can do it a base page from
where all page would extend.

4)Configure the logger with the following line (linked to point2)

log4net.Config.XmlConfigurator.Configure(new
System.IO.FileInfo("C:\\Subhasis\\Testing\\Testing\\log4net.xml"));

In a Practical app., this can be done at Global.asax Application_Start

5)catch with log.Info(ex.Message,ex);

EXPRESSO AND EDITPLUS

Use Expresso to make Regular Expressions and use it with Editplus to ‘find n replace’
any pattern.

SQL SERVER 2005

GO is not a Transact-SQL statement; it is often used in T-SQL code. Go causes all


statements from the beginning of the script or the last GO statement (whichever is closer)
to be compiled into one execution plan and sent to the server independent of any other
batches. SQL Server utilities interpret GO as a signal that they should send the current
batch of Transact-SQL statements to an instance of SQL Server. The current batch of
statements is composed of all statements entered since the last GO, or since the start of
the ad hoc session or script if this is the first GO.
GO Statement must be written in new line as it is not T-SQL command. T-SQL statement
can not occupy the same line as GO. GO statement can contain comments.
Following is example for SQL SERVER 2005 for database Adventureworks.

USE AdventureWorks;
GO
DECLARE @MyMsg VARCHAR(50)
SELECT @MyMsg = 'Hello, World.'
GO ---- @MyMsg is not valid after this GO ends the batch.

---- Yields an error because @MyMsg not declared in this batch.


PRINT @MyMsg
GO

identity column creates a numeric sequence for you. Default is 1,1 (seed,increment)

If you cannot remember the syntaxes of SQL, Stored proc….Use the Template Explorer.
Click on ViewTemplate Explorer. Drag n Drop a template. It even shows how to
execute the stored proc.

DESIGN PATTERNS

1)Mediater pattern: Objects communicate through a Mediater object. Implemented by


passing the mediater object in the constructor of Participant object.

2)Proxy Pattern: Object1 representing Object2. (the actual work is done by the Object2).
This is used to Implement Lazy Loading

3)Singleton Pattern: Class ensures that at a time only one instance is present.
Implemented by having a private/protected constructor (so that a new instance is not
initialized using new()) and an static private variable of its type. Practically used in Load
balancing servers.
Microsoft Enterprise Library

1) Caching: Create a CacheManager from Cachefactory (factory pattern). Then use


Cache.Add(id,data). There are other overloads to include the time to expire as well. In
that case the data is stored in an isolated storage.

2)DataAccess: DatabaseFactory.CreateDatabase(“instancename”);
Db.ExecuteScaler , Db.ExecuteDataset, Db.ExecuteReader(“StoredProcname-Params”)
..encrypting connection string

DELEGATES IN C# (EXPLAINED)

Delegates stores the reference to a function. (just like in reference types


variables , the reference to the actual data is stored, delegates stores the address of
a function). But with a difference i.e it is Typesafe ( the signature of the function
should match the signature of delegate)

http://www.codersource.net/csharp_delegates_events.html

a standard line of .NET


btn1.Click += new EventHandler(btn1_Click);

Here “Eventhandler” is a delegate and “btn1_Click” is a function. Go the


definition of “Eventhandler” in Visual Studio, you will see.
public delegate void EventHandler(object sender, EventArgs e);

That’s why the definition of btn1_click is same as that of above.

If a delegate stores the reference of more than one function, it is called a multicast
delegate. Multicast delegate return type is always void.

Some code from the above webpage


----------------------------------------------
class Figure
{
public Figure(float a, float b, float c)
{
m_xPos = a;
m_yPos = b;
m_zPos = c;
}

public void InvertX()


{
m_xPos = - m_xPos;
}

public void InvertY()


{
m_yPos = - m_yPos;
}

public void InvertZ()


{
m_zPos = - m_zPos;
}

private float m_xPos = 0;


private float m_yPos = 0;
private float m_zPos = 0;

Above is a simple class with some functions

In main class we declare delegate as follows:

public delegate void FigureDelegate();

And now in the main function we should use it like this:

Figure figure = new Figure(10,20,30);


FigureDelegate fx = new FigureDelegate(figure.InvertX);
FigureDelegate fy = new FigureDelegate(figure.InvertY);
FigureDelegate fz = new FigureDelegate(figure.InvertZ);
MulticastDelegate f_del = fx+fy+fz;

The line above means “fx” stores a reference to function “InvertX’ and so-on.
CACHING IN ASP.NET (V.IMP)

Caching is done by adding a directive on the top of the page <%@OutputCache. The
duration for which it is to be cached is specified in the durarion attribute and it is
mandatory (there is no default value). The best way to test is display the current
date/time.
Eg:
<%@ OutputCache Duration=20 VaryByParam="none" %>

<div>
<%=DateTime.Now.ToString() %>
</div>

ASP.NET implements this through Output Cache Engine. First the page is checked here
before dynamically generated.
“VaryByParam” attribute is used to cache based on parameters (either GET or POST).
Example /ProductInfo.aspx?PartNo=4 will check for cached page for that particular
details of a PartNo, if VaryByParam=”PartNo” is set, otherwise it will show the output of
previously opened page for any PartNo. This attribute is also mandatory.

There are 3 types of Caching a)FullPage b)PartialPage c)DataCaching.


The one that we just discussed above is FullPage Caching. Partial Page Caching is done
when a particular section of the Page is to be Cached. It is implemented through the use
of UserControl.
DataCaching is storing data in the Cache object in key-value pairs. The duration(data
expiry) is till the application process is running.

DIFFERENCE BETWEEN ICOMPARABLE AND ICOMPARER

As the name suggests Icomparable makes an object of a class (say Person) comparable to
another Person object based on some logic. The Person class has to implement
Icomparable interface
Where as IComparer is used to make custom comparer and is passed to the sort method
of Lists etc. (listPersons.sort(new FirstNameComparer());

Array of ints are sorted using Array.sort(arr1, new MyComparer());


TYPES OF ASP.NET COMPILATION/DEPLOYING

• In-place compilation This option performs the same compilation that occurs during dynamic

compilation. Use this option to compile a Web site that has already been deployed to a production
server. (copying the aspx and aspx.cs directly to the server without precompiling)

• Non-updateable full precompilation Use this to compile an application and then copy the

compiled output to the production server. All application code, markup, and UI code is compiled
into assemblies. Placeholder files such as .aspx pages still exist so that you can perform file-
specific tasks such as configure permissions, but the files contain no updateable code. In order to
update any page or any code you must precompile the Web site again and deploy it again.

• Updateable precompilation This is similar to non-updateable full precompilation, except that

UI elements such as .aspx pages and .ascx controls retain all their markup, UI code, and inline
code, if any. You can update code in the file after it has been deployed; ASP.NET will detect
changes to the file and recompile it. Note that code in a code-behind file (.vb or .cs file) built into
assemblies during precompilation, and you therefore cannot change it without going through the
precompilation and deployment steps again.

In all the three cases compilation is done by aspnet_compiler.exe

csc.exe does c# -> IL.


JIT compiler(part of CLR) does IL -> Native code

http://www.odetocode.com/Articles/417.aspx (precompilation explained)

JQuery

To use jQuery you have download the jquery.js file and and jQuery-vsdoc.js (for Visual
Studio) both, otherwise it wont work. And to use intellisense you have to install a hotfix
in VS for jQuery

Always reference the js file through


<script type="text/javascript" src="jquery-1.3.2.js"></script>
Do not try with self closing tags. They do not work.

Just realized jQuery-vsdoc.js does not work properly so use jQuery-vsdoc2.js. it works
perfect
$(document).ready(function() {
$("table tr:nth-child(even)").addClass("even");
});

is better than

window.onload = function() {
$("table tr:nth-child(even)").addClass("even");
};

As the former waits until the DOM tree is made while the latter waits until the full page is
loaded with all images etc (making it longer to wait before the script is executed)

To make things simpler, filter selectors are easily identified because they all
begin with a colon character (:) or a square bracket character ([). Any other selector
can’t be used inside the :not() filter

Microsoft official JSON Serializer is:


System.Runtime.Serialization.Json.DataContractJsonSerializer. To use this you also
have to add a reference to System.ServiceModel.Web and System.Runtime.Serialization

If you are using jQuery to handle click of a button you have to write “return false;”
otherwise it will bubble up the DOM tree and the output will not be visible.
Use of $.each() function to parse array,obj,array of objects (4 examples shown)
$.each(arr1, function(n, value) {
$("#someElement").append(value + "<br/>");
});

$.each(obj1, function(name, value) {


$("#someElement").append(name + " - " + value +
});

$.each(arrayOfObjects, function(n, value) {


$.each(value, function(propName, propValue) {
$("#someElement").append(propName + " - " +
propValue + "<br/>");
});
$("#someElement").append("<br/>-------<br/>");
});

$.each(arrayOfObjects, function(n, value) {


$("#someElement").append(value.Property1 + " - " +
value.Property2);
});

Using jQuery for AJAX is very simple. Use it with any method of anypage.aspx. The
conditions are
1) That method should be “static”
2) That method should have [Webmethod] Attribute
3) That method should be accesible (public) from the calling page. 

That anypage can even return a custom object say “objPerson”. Every detail of JSON
serialization is taken care by jQuery.
Note: Use Fiddler for any error/debugging. It helped me a long way. If you are getting
any error in Visual Studio, Its probably due to improper jQuery syntax.

Below is a “hello world”. It gets a “custom object”. Some points to note are
a) we are using POST to make it more secure as GET requests are vulnerable to XSS
attacks
b) No params requests (GET requests) are passed as “{}”
c)The response is always a object with property “d”. This feature was there in .NET 3.5
and was introduced to make it more secure.

$(function() {
$.ajax({
type: "POST",
url: "AjaxPageMethods.aspx/GetObject",
data: "{}",
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function(msg) {
$("#Result").text(msg.d.CategoryId +
msg.d.CategoryName);

},
error: function() {
alert("Sorry, The requested property could not be
found.");
}
}
);

Some Links

http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-
services
http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-
with-aspnet-ajax
http://encosia.com/2009/02/10/a-breaking-change-between-versions-of-
aspnet-ajax/#comment-34045
http://encosia.com/2008/04/16/why-do-aspnet-ajax-page-methods-have-to-
be-static
http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-
ajax-page-methods
http://mosesofegypt.net/post/2008/04/GridView-Grouping-Master-Detail-
Drill-Down-Using-jQuery-AJAX.aspx

SOAP SERVICE – Creating SoapRequest/Parsing SoapResponse/Catching


SoapException manually

protected void Page_Load(object sender, EventArgs e)


{
//Take care of the whitespace in the second and third line
as the element is not fully complete.
//otherwise it ll throw a error.
StringBuilder strSoapMessage = new StringBuilder("<?xml
version='1.0' encoding='utf-8'?>");
strSoapMessage.Append("<soap:Envelope
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' ");//whitespace
strSoapMessage.Append("xmlns:xsi='http://www.w3.org/2001/XM
LSchema-instance' "); //whitespace
strSoapMessage.Append("xmlns:xsd='http://www.w3.org/2001/XM
LSchema'>");
strSoapMessage.Append("<soap:Body>");
strSoapMessage.Append("<GetSoapException
xmlns='http://subhasisrout.org/'>");
strSoapMessage.Append("</GetSoapException>");
strSoapMessage.Append("</soap:Body>");
strSoapMessage.Append("</soap:Envelope>");

HttpWebRequest req =
(HttpWebRequest)WebRequest.CreateDefault(new
Uri(@"http://localhost/WebService123/WebService1.asmx"));
req.ContentType = "text/xml; charset=utf-8";
req.Method = "POST";
req.Accept = "text/xml";
req.Headers.Add("SOAPAction",
@"http://subhasisrout.org/GetSoapException");
StreamWriter stream = new
StreamWriter(req.GetRequestStream(), UTF32Encoding.UTF8);
stream.Write(strSoapMessage.ToString());
stream.Flush();
stream.Close(); //releases (sets free) the request object

//Below is another method to send the request and is much


better actually
//as it gives the errors in the xml input if any, whereas
the above method will send the bad
//xml input to the server and the response will be "Bad
Input". No Idea Why.

//XmlDocument doc = new XmlDocument();


//doc.LoadXml(strSoapMessage.ToString());
//doc.Save(stream);
//stream.Close();

try
{
WebResponse response = req.GetResponse();
Stream str = response.GetResponseStream();
StreamReader rdr = new StreamReader(str);
Response.Write(rdr.ReadToEnd()); Response.End();
}
catch (WebException webEx)
{
Stream str = webEx.Response.GetResponseStream();
StreamReader rdr = new StreamReader(str);
Response.Write(rdr.ReadToEnd());
Response.End();
}

DEPLOYING WCF SERVICE TO IIS

1) Do everything normally as Webservice. Modify “web.config” as


following (underlined part):
<service name="WcfService123.Service1"
behaviorConfiguration="WcfService123.Service1Behavior">
<host>
<baseAddresses>
<add
baseAddress="http://localhost/WcfService123/Service1.svc"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding"
contract="WcfService123.IService1">
<!--
Upon deployment, the following identity element should be
removed or replaced to reflect the
identity under which the deployed service runs. If
removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>

2) And run the following command


"%windir%\Microsoft.NET\Framework\v3.0\Windows
Communication Foundation\ServiceModelReg.exe" -r –y
3) In case of Win7/IIS7. Grant Full Control to “IIS_IUSRS” to the directory
“C:\Windows\Temp” (Tricky )

DEBUGGING TIPS
1) Break on all Exceptions (even if it is handled) Go to Debug > Exception
(Ctrl Alt E). This will be useful when you are given an unknown
application that collects all the errors and shows it at once on the top of
the screen. You do not know the source the error (or the exception). Just
enable this option and find out directly.
2) A faster way of debugging an error is to do it backwards i.e. go the known
bottommost function and start doing a step out (Shift – F11) to climb up and
see where it fails. This is better than debugging from start (top) and doing next
-> next. The “starting from bottommost” technique will give all the call
flows at once in the CallStack window.
3) If you want to change value of any variable while debugging (during runtime),
use immediate window and just write VAR1=”abc” in the window.
Or hover over the variable , write the value there itself and press Enter.
4) Conditional BreakPoint in Loops: You can attach a breakpoint in a FOR ot
FOREACH loop and when it hits it, right-click on the breakpoint and you can
put a CONDITION say when p.FirstName=="Paul". So you dont have to
iterate through the whole collection one by one. There are other options as
well when you right click.
GENERAL VISUAL STUDIO TIPS/.NET TIPS
1) To make traditional properties (.NET 2.0) faster, just declare the private variable,
select it, right click and click Refactor and click Encapsulate.
2) Tools > options > keyboard > TestDriven.NET > Assign keyboard shortcut to VS
plugin….( or any plugins for that matter)
3) When you are returning a collection say IList. Make sure its readonly so that its
underlying elements are not changed by the actor. To do that use
listPerson.ToList<Person>().AsReadOnly.

Configuring VirtualPC for internet and sharing with Host


Refer the link http://support.microsoft.com/kb/833134
1) Open Virtual PC. Go to Setting menu -> Networking. Add only one
network adapter and that should be Shared Networking (NAT). You will be able
to access internet.
2) Go to Setting menu -> Shared Folders. You can share a folder of Host and
can use it for 2-way communication.
3) To install some windows component like IIS (from CD/DVD). Go to CD
-> Capture ISO image. Give the path. After the work is done, Eject the CD by
clicking on CD->Release ISO.
4) After installing IIS 6.0, you will see the default “Under Construction”
Page.

Setting a Continuous Integration Server (CruiseControl.NET for Vault Source


Control)

1) Install CCNet in a separate server (VM machine). Make sure that machine has
SDK for .NET framework (MSBuild is required). To be on the safer side I installed
full VS2008 (as the installation has SDK)

2) Prepare the ccnet.config file.

ccnet.config

In here
a) use sourcecontrol type as “vault” if you are using the vault command line
utility (works for me). If you are using a downloadable vault plugin use
type=”vaultplugin” (did not work for me . There were issue with
NetReflector.dll as well)
<sourcecontrol type="vault" autoGetSource="true" applyLabel="true"
cleanCopy="true">

b) Make sure to add the logger tag


<logger>C:\Program
Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MSBuild.dll</logg
er>
3) The vault command line utility has to downloaded from vault site (under the
section “Vault ClientAPI”.

Configure CruiseControl.NET to show MbUnit report


a) Minor changes in config file + Add a Build project file for the Unit Test Project
b) attached 3 config files + 1 file(UnitTestBuild.proj)

ccnet.exe.config ccservice.exe.config dashboard.config UnitTestBuild.proj

c) iisreset (cause pages are cached)

WINDSOR CASTLE
Windsor castle is one of the part of Castle Project Framework. It is used as IoC
container (Dependency Injection). It creates objects by picking up the required
dependencies. Other frameworks are StructureMap and Spring.NET (.NET
counterpart for Spring of Java world). More Info @
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInj
ectionWithCastleWindsorContainerPart1.aspx

ASP.NET Issue#1: Controls in aspx not accessible/found in code behind file.


This usually happens when people copy paste the aspx/aspx.cs files from somewhere.
The reason why it happens, .designer.cs file is missing. To generate that right click on
the aspx page and click on “Convert to Web Application”

MESSAGE INSPECTOR IN WCF


Message Inspector can attached at service level and client level. To attach at Service level
make the inspector implement IdispatchMessageInspector and for Client level make the
inspector implement IclientMessageInspector. In addition to the inspector file, we need to
add two other files Behavior and BehaviorExtensionElement. After that Web.config has to
be modified in the following way.
<endpoint address="" binding="basicHttpBinding" contract="WcfService123.IService1"
behaviorConfiguration="subhasisBehavior">

<extensions>
<behaviorExtensions>
<add name="ConsoleOutputBehavior"
type="WcfService123.ConsoleOutputBehaviorExtensionElement, WcfService123,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<endpointBehaviors>
<behavior name="subhasisBehavior">
<ConsoleOutputBehavior />
</behavior>
</endpointBehaviors>

To check the working of the message inspector, attach a breakpoint in the starting of
AfterReceiveReply (or whatever) and check reply.ToString().

For Server side Message Inspector attached are the files.

ConsoleOutputMessa ConsoleOutputBehav ConsoleOutputBehav web.config


geInspector.cs ior.cs iorExtensionElement.cs

Client side message inspector would be same except in “ConsoleOutputBehavior”,


“ApplyClientBehavior” has to be defined instead of “ApplyDispatchBehavior”

CONDITIONAL DEBUGGING THROUGH CODE

for (int i = 1; i <= 100; i++)


{
if (System.Diagnostics.Debugger.IsAttached && i == 97)
{
System.Diagnostics.Debugger.Break();
}
Response.Write(i.ToString() + " ");
}
WORKING WITH GIT AND GITHUB

Here are the basic steps to create a project and check-in files. For more info refer
http://gitref.org/

1) Create a repo. in www.github.com


2) Open Git Bash shell
3) Navigate to the directory where you have the source code.
4) Type "git init"
5) Type "git add *" to add all the files/dir./sub dir. to staging area.
6) Type " git commit -m 'DrilldownGrid first checkin' "

7) Next step is to add an alias for the repository created in Step 1. That alias would be
used
in the Git Client for referring the repo. in the next steps.
8) Type "git remote add ddgrid git@github.com:subhasisrout/DrilldownGrid.git"
9) Here ddgrid is the alias
10) Type"git push ddgrid master" (here master is the branch. you will be asked the
passphrase.)

Vous aimerez peut-être aussi