Creating custom project template with wizard for Visual Studio

Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg This

Introduction
If you are a experienced .Net developer, you might have already created or used custom project template in Visual Studio. In new versions of Visual Studio, Microsoft has included common files like jQuery, CSS, standard Master page etc. in the default web site template which was not there in old Visual Studio versions.

I always require jQuery file, standard CSS file of client, some common logo images to be added in my new projects. Also, whenever I creat a new project, I require to modify the connection string by going to web.config file. There are also some other common setting which I repetatively do in web.config.

Visual Studio provides some easy way of creating a cusomt project template so that, such a common items and code can be included in the new project template.

In this short article, I will explain about

Creating project template
Creating DLL for new project wizard dialogue
Incorporating new wizard in project template to accept additional input from user
Using project template to create new website
Article Body
Note that, I am using web site project as a example in complete article. However, this is applicable for web application or any other project (including console application, WinForm application etc.)

Lets first start by creating simple project template which will contain common files that we require in most of our projects. You might be aware that, Visual Studio provide a option of exporting existing open project as temaplate. You can simply open a web site project and then go to File -> Export Temaplate and then follow the wizard stepas this will make current project as a template which can be used as a base while opening new project next time.

However, to have more control over templated items and to use separate wizard dialouge etc. we can follow steps given below (Which is the focus of the article)

Creating simple project template first

Suppose, I want that jQuery file be added by default when I creat new project (This is already there in Visual Studio 2010 but not in VS 2005) also, there is a standard CSS file and a image file which should be included. Also, there is public function class file which I want to use across all my projects.

Lets first creat new web site project and add all these files into this project.

Now, add new XML file in the root directory of project and name it as ProjectTemplate.vstemplate. This is the file which will contains information required to create new project in VS. The content of .vsTemplate file are diaplayed below (note that you could name the file as per your choice)

?123456789101112131415161718192021222324252627282930 Blue Lemon Default Project TemplateA web site project template by Kedarlemon.icoWebCSharpWebSitepubClass.csjquery-1.4.1.jsjquery-1.4.1.min.jsMyJS.jsStandardTheme.csslemon.icoDefault.aspx

Default.aspx.

csweb.config
The purpose of various tags inside in above XML format is evident from their name. You can change these values as per your choice (like ProjectType could be either CSharp/VisualBasic/JSharp/Web so that project template can be categorized into appropriate type).

Insidetag, I have includedtag and specified name of .ico file. The Icon tag information is used to display picture of project template while creating new project. I strongly advice to read this to know more about template data.

Intag, we need to mention details of all files which we wish to include in the template. Creat structre of all necessary file by usingto mention folder name (like App_Code) and usetag to give file details. As name suggest by setting OpenInEditor=”true” in ProjectItem tag, the respective file can be set to be opened by default when you start a new project by selecting this template. There is another attribute of ProjectItem as ReplaceParameters. This can be set to true so that dyamic paramters can be added into the file and used by template when creating new project.

To see its use, open pubClass.cs file from App_Code and change its namespace value as $safeprojectname$. The content of class file looks as

?1234567891011121314151617181920 using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace $safeprojectname$ { ///
/// Summary description for Class1 ///

public class PubClass { public void ExecuteQuery() { } } }
The parameter $safeprojectname$ in above code has certain meaning in Visual Studio project template. VS provides name entered by user in New project dialogue in this parameter. By setting ReplaceParameter to True for pubClass.cs file in XML file above, we have intimated VS to replace $safeprojectname$ in pubClass.cs with new project name enterd by user.

In above XML format, there is a tag as. Although, Web site project does not have any solution or project file, it is required for interanl purpose. Hence, go to folder location where you have defined this project and create new blank file and name it as WebApplication.webproj.

After refreshing project in Visual Studio, below is list of files available.

If you want just to create simple projetc template without any additional dialogue and just default set of files. Then you can jump to third section (However, I would suggest to read on next section)

Creating DLL for new Project wizard dialogue

Until this it is fine. But what if I want that when I create a new project using custom template it should ask me for connectionstring setting I want to add in my web.config file? so that I dont have open web.config file and add connection string value again after project is started.

Project template wizard could come handy in such situations. However, it is not straightforward as creating project template. To add wizard form in project template, we have to create a separate class library project and follow below steps.

Create new class library project and add a windows form in it with required wizard design

Right click on project in solution explorer and select windows form. name it as wizardForm.cs and create form design (in this case, I want to let use to enter connection string and some other custom message)

In the wizardForm.cs c# code, create public properties to return value of form fields. The complete code is

?1using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace CustomOptions { public partial class wizardForm : Form { public string strCustomMessage; public string strConnectionstring; public wizardForm() { InitializeComponent(); } public string get_CustomMessage() { return strCustomMessage; } public string get_ConnectionString() { return strConnectionstring; } private void btnAdd_Click(object sender, EventArgs e) { strCustomMessage = txtParameter.Text; strConnectionstring = txtConnectionstring.Text; this.Dispose(); } } }
Update class file to create wizard template assembly

Now is the time to update class file of to create project template assembly. Before that, it is required that we add reference to following assemblies in the project

Right click on project -> select Add reference. In .Net tab select Microsoft.VisualStudio.TemplateWizardInterface, System.Windows.Forms and EnvDTE. In the class.cs file (or you might have different name to this file) add using statement to these namespace (in case of vb.net, it is import).

We required to create a class which inherits form IWizard interface. IWizard has many other functions out of which we are going to provide implementation for RunStarted and RunFinished.

?using System; using System.Collections.Generic; using Microsoft.VisualStudio.TemplateWizard; using System.Windows.Forms; using EnvDTE; namespace CustomOptions { public class WizardClass : IWizard { private wizardForm wizardFrm; private string customMessage; private string strConnectionstring; public void BeforeOpeningFile(ProjectItem projectItem) { } public void ProjectFinishedGenerating(Project project) { } public void ProjectItemFinishedGenerating(ProjectItem projectItem) { } public void RunFinished() { MessageBox.Show(“The custom options has been added. Creating new project with selected template and parameters”); } public void RunStarted(object automationObject, DictionaryreplacementsDictionary, WizardRunKind runKind, object[] customParams) { try { //Call win form created in the project to accept user input wizardFrm = new wizardForm(); wizardFrm.ShowDialog(); //call property from wizardForm to read user input values customMessage = wizardFrm.get_CustomMessage(); strConnectionstring = wizardFrm.get_ConnectionString(); // Add custom parameters. replacementsDictionary.Add(“$custommessage$”, customMessage); replacementsDictionary.Add(“$connectionstring$”, strConnectionstring); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } public bool ShouldAddProjectItem(string filePath) { return true; } } }
Note carefully that, all we are doing in RunStarted method is displaying wizard dialogue, reading values entered by user in wizard form and add it in dictionary variable. We are also adding a string enclosed in $. This works as a key which we would use later in project template to read user inputted value and replace in template pages.

Sign assembly and add in GAC

We have now completed creating wizard form. To use it in project template, the assembly needs to signed with strong name and be added in GAC. To sign assembly, right click project go to Properties in project properties page go to Signing tab -> check “sign the assembly” checkbox. In “Choose string name key file”, select New. Then in new dialogue, enter Key file and password/s the key file (.pfx) would be generated in root of project.

This assembly now needs to be added in GAC (global assembly cache) you might already know how to do it or read this.

Incorporating new wizard in project template to accept additional input from user

We now have a custom project template and a template wizard assembly. Now go back to our original project template (step 1 above). In the .vsTemplate XML file, we have to add reference to the assembly we just created. To do that, add following tags after closingtag

?123456 wizardTemplate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0abc167b5bd11206 CustomOptions.WizardClass
Note that, we need assembly information for this. To get assembly information of just added assembly, go to Visual studio command prompt and type

> gacutil -l

this will give us the assembly information string which we can copy and paste intotag above. Also note that, FullClassName tag should indicate namespace.classname of wizard project.

If you see complete XML format of .vsTemplate file, we had set ReplaceParameter to true for web.config as well as default.aspx. That is because, the we are going to replace values in these files with string entered by user in wizard form.

Go to web.config file of project template add replace connectionstring tag as

?12345
The $connectionstring$ indicate that value of $connectionstring$ parameter should be replace here. One final thing we are left with is to package the template project. To do this, go to folder location where template project is saved. in the root directory, select all files -> right click -> send to -> Compressed (zipped) Folder.

We now need to add this zip file into default template location of visual studio. Mostly (unless you have changed) VS template stored at

\My Documents\Visual Studio 2010\Templates\ProjectTemplates\\

or

\My Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual Web Developer

Read this to know how can you find default location of project template on your machine. Once the default location is identified, copy and paste the zip file here and that’s it!

Using project template to create new website

To test the project template with wizard, open new Visual studio instance and go to File -> New web site. The new project name can be seen here

Select this new project template and click OK. A dialgue will appear as this. Add values in the textboxes

Then click on Add button. The project will start with all default files selected by us as part of template. Go to web.config file now. whoo! instead of $connectionstring$ you can now see value entered by us in project wizard dialogue.

Conclusion
Diffrent functionality of Visual Studio can be extended very easily. By creating custom wizard in project template we can do lot of many other things to speed up development process. With NuGet, it is more easier to use any existing project templates.

If you know of any NuGet package which takes care of creating project template wizard then please update us.

Thanks for visiting my site. Your comments are welcome :)

website designing delhi,website designing india,website designing,website design,websitedesignin.org,seo,search engine optimization,seo articels,website design delhi,website design india

Programming the Sending of Emails yourself

Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg This

A minimalist Email

First we have to figure out how the SMTP (Simple Mail Transport Protocol) Protocol works as it is the foundation for the sending of emails. The beauty of it is that all the commands and replies to them from the SMTP server are clear text (which on the other hand might be considered to be a security issue…).

The following ‘script’ shows the basic sequence of SMTP commands necessary for sending an email:

HELO local computername
MAIL FROM: sender's address
RCPT TO: recipient's address
DATA
mail header and body text
.

To actually send an email, you have to telnet onto port 25 (the SMTP port, telnet servername 25) on the Email server and type in the example email:

HELO SHAGPAD
MAIL FROM: christophw@alphasierrapapa.com
RCPT TO: christophw@dev.alfasierrapapa.com
DATA
Subject: Hi Chris

This is a part of the body text
.

The parameters HELO, MAIL FROM and RCPT TO are unspectacular and were ‘previsible’. The DATA parameter, however, is interesting: the header (Subject) and body text are separated by a blank line. This example sports only one header (Subject), further examples will insert the missing headers.

The dot (which has to be on a separate line) finally terminates the email and the server reports the status of the operation. Apropos status reports: each of the commands shown returns a status message from the server – these can come in very handy!

Implementing the minimalist Email in C#

We will now transport this process 1:1 into C# using the System.Net classes of the .NET Framework as helpers. Basically, it all now is a mattter of an instance of the TcpClient class and its Stream for connecting to the SMTP Server and for exchanging commands and status messages.

The file email-simple.aspx is part of the download for today’s article.

<% @Page Language="C#" %>
<% @Import Namespace="System.IO" %>
<% @Import Namespace="System.Net" %>
<% @Import Namespace="System.Net.Sockets" %>
<% @Import Namespace="System.Text" %>
<script language="C#" runat="server">
bool WriteToStream(ref NetworkStream nwstream, string strLine)
{
  string strString2Send = strLine + "\r\n";
  Byte[] arr2Send = Encoding.ASCII.GetBytes(strString2Send.ToCharArray());
  try
  {
    nwstream.Write(arr2Send, 0, arr2Send.Length);
  }
  catch
  {
    return false;
  }
  return true;
}

bool ReadFromStream(ref NetworkStream nwstream, out string strMessage)
{
  byte[] readBuffer = new byte[255];
  int nLength = nwstream.Read(readBuffer, 0, readBuffer.Length);
  strMessage = Encoding.ASCII.GetString(readBuffer, 0, nLength);
  return (3 <= readBuffer[0]); // 2 success, 3 informational
}
</script>
<%
Response.Buffer = false;

string strEmailServer = "fx2.dev.alfasierrapapa.com";
string strSendTo = "christophw@fx2.dev.alfasierrapapa.com";
string strMailFrom = "christophw@alphasierrapapa.com";
string strSubject = "My Email Test";

TcpClient tcpc = new TcpClient();
try
{
  tcpc.Connect(strEmailServer, 25);
}
catch (SocketException socketEx)
{
  Response.Write("Connection Error: " + socketEx.ToString());
  Response.End();
}

NetworkStream nwstream = tcpc.GetStream();
string strResponse;

WriteToStream(ref nwstream, "HELO myhost");
ReadFromStream(ref nwstream, out strResponse);
Response.Write(strResponse + "<br>");

WriteToStream(ref nwstream, "MAIL FROM: " + strMailFrom);
ReadFromStream(ref nwstream, out strResponse);
Response.Write(strResponse + "<br>");

WriteToStream(ref nwstream, "RCPT TO: " + strSendTo);
ReadFromStream(ref nwstream, out strResponse);
Response.Write(strResponse + "<br>");

WriteToStream(ref nwstream, "DATA");
ReadFromStream(ref nwstream, out strResponse);
Response.Write(strResponse + "<br>");

WriteToStream(ref nwstream, "Subject: " + strSubject);
ReadFromStream(ref nwstream, out strResponse);
Response.Write(strResponse + "<br>");

WriteToStream(ref nwstream, ".");
ReadFromStream(ref nwstream, out strResponse);
Response.Write(strResponse + "<br>");
%>

Concentrating on the lower part of the listing (the blocks of code three-liners), we see that this really looks no different from creating an Email using Telnet. The funcionality for sending the commands and for querying the status messages is hidden in the methods WriteToStream and ReadFromStream, respectively.

The WriteToStream method is responsible for sending the commands. This happens by appending a CR/LF pair to the string, converting that into a byte array and the subsequent sending to the SMTP Server via the Write method of the NetworkStream object. The return value is true/false, dependent on whether the command could successfully be sent:

bool WriteToStream(ref NetworkStream nwstream, string strLine)
{
  string strString2Send = strLine + "\r\n";
  Byte[] arr2Send = Encoding.ASCII.GetBytes(strString2Send.ToCharArray());
  try
  {
    nwstream.Write(arr2Send, 0, arr2Send.Length);
  }
  catch
  {
    return false;
  }
  return true;
}

The ReadFromStream method basically works much the same way, differing only in reading a byte array and returning that as a String to the caller in consequence. As every status message of the SMTP Server is initiated by a three digit status code, I use that to compute true/false: 2xx are success messages, 3xx are successes with additional information:

bool ReadFromStream(ref NetworkStream nwstream, out string strMessage)
{
  byte[] readBuffer = new byte[255];
  int nLength = nwstream.Read(readBuffer, 0, readBuffer.Length);
  strMessage = Encoding.ASCII.GetString(readBuffer, 0, nLength);
  return (3 <= readBuffer[0]); // 2 success, 3 informational
}

Even with both methods returning boolean results, I ignore them for simplicity’s sake in today’s example. Instead, I will output the status messages of the SMTP Server – something one wouldn’t do in a production environment:

According to the status code, sending the Email was a success – Outlook Express shares that opinion:

However, the result looks less than appealing, as Outlook expects special headers for sender and recipient – Eudora isn’t as nitpicking as far as this goes, but less popular. Thus we must program a little additional something into it to make the Outlookians think favourable of us.

Eye candy for Outlook

This little something are the headers To and From. These simply are included in the Header section (email-better.aspx):

WriteToStream(ref nwstream, "DATA");
ReadFromStream(ref nwstream, out strResponse);
Response.Write(strResponse + "<br>");

WriteToStream(ref nwstream, "From: " + strMailFrom);
WriteToStream(ref nwstream, "Subject: " + strSubject);
WriteToStream(ref nwstream, "To: " + strSendTo);
WriteToStream(ref nwstream, "");

WriteToStream(ref nwstream, "Hello Christoph!");

WriteToStream(ref nwstream, "\r\n.");
ReadFromStream(ref nwstream, out strResponse);
Response.Write(strResponse + "<br>");

This time around, Outlook Express also is ‘friendly’ with us and displays all desired information:

Conclusion

Today, we have just sent a simple email message, but in the course of this, we got acquainted with all the important SMTP commands. What we will add in the next articles will be recipients of copies, blind copies, content type, additional headers, HTML Email and attachments. Stay tuned!

Downloading the Code

Click here to start the Download.

website designing delhi,website designing india,website designing,website design,websitedesignin.org,seo,search engine optimization,seo articels,website design delhi,website design india
website designing delhi,website designing india,website designing,website design,websitedesignin.org,seo,search engine optimization,seo articels,website design delhi,website design india