To validatethe user input in any application we write code or use some validation controlsand we repeat this task on each and every page of application. So why not writea generic solution for that which can handle the job and also which can bereusable for any application.

I am sorryto say I am not going to paste any code here but I will write down the buildingblocks and some important things you should coverJ

What Validation Types it shouldcover?

RequiredFieldValidator

User should enter a value of a field

RangeValidator

User should enter a value between a range of values

CompareValidator

User should enter a value which should be equal to the valueof another field for example confirm password should be equal to the choosenpassword.

ReqularExpressionValidator

User should enter a value which should be matching with thegiven Reqular Expression for example email validation

GroupValidator

If user enters a value to a certain field then some otherfield should also be entered

CustomValidator

Consider a situation when your validation function exists tosome ABC method of an external Assembely’s, this should also be covered.

What UI Control Types it should cover?

TextBox

DropdownList

CheckBoxList

RadioButtonList

CheckBox

RadioButton

ListBox

GridView (Allcontainer Controls)

UserControl

CustomWebControl

What else?

  • Able to handle to controls which are disable or hidden thatshould it validate them or not?
  • Developer can also add an custom error which should be a partof generated error summary
  • Set a background color of error controls with tooltips
  • While clicking on a error in error summary user should beable to navigate to that control
  • Validations must be depended on their container controls
  • Generic enough to handle the validations by their priority orsequence for example email is required and also it should be a valid email. Soif first validation fails then it should skip remaing ones and so on.
  • Should be able to treat warnings and errors separtely

Database Structure

ApplicationValidation

ValidationID int
ValidationChildID int
ValidationParentID int
ControlID varchar(150)
Type tinyint
FullClassName varchar(150)
ControlClientID varchar(150)
ParentControlID varchar(150)
ContainerControlID varchar(150)
ValidateOnDisabled bit
ValidatorType tinyint
Expression varchar(500)
MinValue decimal(10, 5)
MaxValue decimal(10, 5)
CompareControlID varchar(150)
ErrorMsg varchar(300)
Sequence int
OnClickSetFocus bit
Status bit
GroupOf int
HasError bit
IsOptionalField bit
ErrorType bit
[Assembly] varchar(1024)
FunctionName varchar(1024)
SortOrder decimal(5, 2)

ApplicationValidationParameter

ValidationID int
ParamName varchar(64)
Type tinyint
Sequence tinyint

you can view the this working live here


LINQ to SQL enables you to access and modify data from a Microsoft SQL Server database without writing any SQL. LINQ to SQL enables you to perform all of your database queries from directly within the C# or VB.NET programming languages.

LINQ to SQL provides a number of benefits:

  • Productivity — A huge amount of developer time is wasted writing components that bridge the gap between the relational (database) and object (C# or VB.NET) worlds. LINQ to SQL eliminates all of this work.
  • Intellisense — Since LINQ to SQL is integrated into both the C# and VB.NET languages, you get full Intellisense within Visual Studio when writing LINQ to SQL queries.
  • Maintainability — LINQ to SQL enables you to maintain all of your code in one place: your application. You no longer need to write stored procedures when taking advantage of LINQ to SQL.

just leave out the definitions and advantages lets write some code..

create a new project and add Linq to Sql Classes item .. it will bring you a designer  as given below now add a connection and drag n drop your database tables. This will generate all DTO’s, Collections and Data Context items for you.

configure data context

here are some simple operations to start with….

LINQDataContext db = new LINQDataContext();
//Get list of Products
db.Products.ToList();
  //Get Filtered list of Products where price > 100
            db.Products.Where(p=>p.ListPrice > 100).ToList();
            //Another way to do it
            var query = from p in db.Products
                        where p.ListPrice > 100
                        select p;
            query.ToList();
            //using orderby
            db.Products.OrderBy(p=>p.Name).ToList();
            db.Products.OrderByDescending (p=>p.ListPrice).ToList();
           //Load product by Id
           Product product = db.Products.Where(p=>p.ProductID == 5).SingleOrDefault();
           //get sub category name of product.. check out hirarichal support
           product.ProductSubcategory.Name;
           //Add New
            Product _product =new Product();
            product.Name ="<New>";
            db.Products.InsertOnSubmit(product);
            db.SubmitChanges();
            //Delete
            db.Products.DeleteOnSubmit(db.Products.Where(p => p.ProductID == 5).SingleOrDefault());
            db.SubmitChanges();


In almost every web form few fields are required to save the information and to indicate that we use a seperate label to show a sign with that field like * is the most common one. For example * User Name here user name field is required so we put an * here to indicate user. We used to add two labels for that one for * and one for that field; i have embedded that logic in one label here it is…… very trickyyyy:)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace rationals.WebControls
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:PrettyLabel runat=server></{0}:PrettyLabel>")]
    public class PrettyLabel : Label
    {
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public override  string Text
        {
            get
            {
                String s = (String)ViewState["Text"];
                return ((s == null) ? String.Empty : s);
            }

            set
            {
                ViewState["Text"] = value;
            }
        }
       
        [Category("Required")]
        public bool ShowRequiredSign
        {
            get
            {
                object obj = ViewState["ShowRequiredSign"];
                if (obj != null)
                    return Convert.ToBoolean(obj);
                return false;
            }
            set
            {
                ViewState["ShowRequiredSign"] = value;
            }
        }
        /// <summary>
        /// Which sign should be shown if required, by default it will show *
        /// </summary>
        [Category("Required")]
        public string RequiredSign
        {
            get
            {
                object obj = ViewState["RequiredSign"];
                if (obj != null)
                    return obj.ToString();
                return “*”;
            }
            set
            {
                ViewState["RequiredSign"] = value;
            }
        }
        [Category("Required")]
        public string RequiredSignCssClass
        {
            get
            {
                object obj = ViewState["RequiredSignCssClass"];
                if (obj != null)
                    return obj.ToString();
                return string.Empty;
            }
            set
            {
                ViewState["RequiredSignCssClass"] = value;
            }
        }
        [Category("Required")]
        public Alignment RequiredSignAlignment
        {
            get
            {
                object obj = ViewState["RequiredSignAlignment"];
                if (obj != null)
                    return (Alignment)obj;
                return Alignment.Left ;
            }
            set
            {
                ViewState["RequiredSignAlignment"] = value;
            }
        }
        protected override void RenderContents(HtmlTextWriter output)
        {
            if (ShowRequiredSign)
            {
                string temp = string.Empty;
                if ( RequiredSignCssClass == string.Empty)
                    temp = “<span style=’color:Red;font-size:12px;font-weight:bold;font-family:Arial;’>” + RequiredSign + “</span>”;
                else
                    temp= string.Format(“<span class=’{0}’>”,RequiredSignCssClass) + RequiredSign + “</span>”;
                if (RequiredSignAlignment == Alignment.Right)
                    Text = Text + temp;
                else
                    Text = temp + Text;
               
            }
            output.Write(Text);
        }
    }
    public enum Alignment
    {
        Left,
        Right,
    }
}


Google Co-op is a platform that enables you to customize the web search experience for users of both Google and your own website.

so go to http://www.google.com/coop/ and create your own search engine for your site and use google services for search.

see i have created a sample for my blog

 http://www.google.com/coop/cse?cx=004912805684274411112%3Ajaw58cdgos8

after creating the search engine follow the instructions from google and copy/paste the code to your web site.


Almost every website like to communicate with its users by automatic emails for example “Registration Details”, “Forget Password” or even “Newsletters“. So you need to have some kind of mechnisim to design a template for each email type visually and will able to parse them before sending.

I have worked on this on some project and i thought it may be helpful for others.

Database Design

DB

Data Access Layer

These are the methods we need to implement in our Data Access Layer.

/// <summary>

/// To Load Email Template by Code

/// </summary>

/// <param name=”code”></param>

/// <returns></returns>

public Model.EmailTemplate EmailTemplateLoadByCode(string code) {}/// <summary>

/// To Load Email Template by ID

/// </summary>

/// <param name=”templateID”></param>

/// <returns></returns>

public Model.EmailTemplate EmailTemplateLoad(int templateID){}/// <summary>

/// To Update Email Tempalte

/// </summary>

/// <param name=”template”></param>

/// <returns></returns>

public bool EmailTemplateUpdate(Model.EmailTemplate template){}/// <summary>

/// To Load All Variables of a Tempalte

/// </summary>

/// <param name=”templateId”></param>

/// <returns></returns>

public DataTable EmailVariableLoadByTemplate(int templateId){}/// <summary>

/// To Get a Variable Value based on Primary key value

/// </summary>

/// <param name=”tablename”></param>

/// <param name=”field”></param>

/// <param name=”pkey”></param>

/// <param name=”pkeyValue”></param>

/// <param name=”fieldValue”></param>

public void GetTemplateVariableValue(string tablename, string field, string pkey, string pkeyValue, ref string fieldValue){}

Only the last method is tricky so i am adding its proceedure as well.

Create proc [dbo].[EmailTemplate_GetTemplateVariableValue]( @tablename varchar(100), @field varchar(100)
, @pkey varchar(100), @pkeyValue varchar(100))
as

exec(’select ‘ + @field + ‘ from ‘ + @tablename +’ Where ‘ + @pkey + ‘=’ + @pkeyValue )

Business Logic Layer

Just need to wrap the DAL methods or its up to you how you handle them.

Email Parser

using System;

using System.Collections.Generic;

using System.Text;

using System.Collections.Specialized;

using System.Text.RegularExpressions ;

namespace EmailTemplates{

public class Parser

{

public static string Parse(int templateid, System.Collections.Specialized.NameValueCollection valuesCollection){

Model.EmailTemplate template = BLL.EmailTemplateLoad(templateid);

if (template != null)return ReplaceVariables(template.EmailTemplateID, template.BodyText, valuesCollection);

return string.Empty;}

private static string ReplaceVariables(int templateId,string bodyText, System.Collections.Specialized.NameValueCollection valuesCollection){

const string HEADER = “{{HEADER}}”;const string FOOTER = “{{FOOTER}}”;char[] ch = new char[1];ch[0] =

‘,’;string[] pkeyValue = null;

string fieldValue = string.Empty;string pattern = string.Empty;

string temp = string.Empty;try

{

StringBuilder mailbody = new StringBuilder();if (bodyText.Trim().Length > 0){

System.Data.DataTable dtVariable = BLL.EmailVariableLoadByTemplate(templateId );mailbody.Append(bodyText );

for (int j = 0; j < dtVariable.Rows.Count; j++){

pattern = “{{“ + dtVariable.Rows[j]["VariableName"].ToString() + “}}”;

Regex reExp = new Regex(pattern, RegexOptions.IgnoreCase);MatchCollection matches = reExp.Matches(bodyText ); for (int i = 0; i < matches.Count; i++){

if (matches[i].Value.ToUpper() == HEADER){

mailbody.Replace(matches[i].Value, ReplaceHeaderFooter(Enum.GetName(typeof(EnumModel.EmailTempate), EnumModel.EmailTempate.HEADER)));}

else if (matches[i].Value.ToUpper() == FOOTER){

mailbody.Replace(matches[i].Value, ReplaceHeaderFooter(Enum.GetName(typeof(EnumModel.EmailTempate), EnumModel.EmailTempate.FOOTER)));}

else

{

fieldValue = string.Empty;temp = valuesCollection.Get(dtVariable.Rows[j]["ClassMemberName"].ToString());pkeyValue = temp.Split(ch);

if (pkeyValue.Length == 1){

GetTemplateVariableValue(dtVariable.Rows[j]["TableName"].ToString(), dtVariable.Rows[j]["FieldName"].ToString(), dtVariable.Rows[j]["PriKey"].ToString(), pkeyValue[0], ref fieldValue);

if (dtVariable.Rows[j]["VariableType"] != DBNull.Value){

if (Convert.ToByte(dtVariable.Rows[j]["VariableType"]) == Convert.ToByte(Enum.Parse(typeof(EnumModel.VariableType), EnumModel.VariableType.Password.ToString()))){

string password = Common.Utility.DecryptString(fieldValue);mailbody.Replace(matches[i].Value, password);

}

else if (Convert.ToByte(dtVariable.Rows[j]["VariableType"]) == Convert.ToByte(Enum.Parse(typeof(EnumModel.VariableType), EnumModel.VariableType.Date.ToString()))){

mailbody.Replace(matches[i].Value, Convert.ToDateTime(fieldValue).ToLongDateString());}

else if (Convert.ToByte(dtVariable.Rows[j]["VariableType"]) == Convert.ToByte(Enum.Parse(typeof(EnumModel.VariableType), EnumModel.VariableType.Time.ToString()))){

mailbody.Replace(matches[i].Value, Convert.ToDateTime(fieldValue).ToLongTimeString());}

else if (Convert.ToByte(dtVariable.Rows[j]["VariableType"]) == Convert.ToByte(Enum.Parse(typeof(EnumModel.VariableType), EnumModel.VariableType.DateTime.ToString()))){

mailbody.Replace(matches[i].Value, fieldValue);

}

else if (Convert.ToByte(dtVariable.Rows[j]["VariableType"]) == Convert.ToByte(Enum.Parse(typeof(EnumModel.VariableType), EnumModel.VariableType.Encrypted.ToString()))){

mailbody.Replace(matches[i].Value, Common.Utility.EncryptString(fieldValue));

}

}

else

{

mailbody.Replace(matches[i].Value, fieldValue);

}

}

}

}

}

return mailbody.ToString();}

}

catch (Exception ex) { }return string.Empty;}

public static string ReplaceHeaderFooter(string code){

Model.EmailTemplate template = BLL.EmailLoadByCode(code);

if (template != null)return template.BodyText;

return string.Empty;}

private static void GetTemplateVariableValue(string tablename, string field, string pkey, string pkeyValue, ref string fieldValue){

if (tablename.Trim().Length > 0 && field.Trim().Length > 0)BLL.GetTemplateVariableValue(tablename, field, pkey, pkeyValue, ref fieldValue);else

fieldValue = String.Empty;}

}

public class EnumModel
{
// Here you need to specify the TemplateKey column value from EmailTemplate Table
public enum EmailTempate
{
Header,
Footer,
NewsLetter,
UserRegisteration,
ForgotPassword,
MassEmal,
ProfileApproved,
}

//Possible Variable Types are handled in parser but if needed can be supported more.
public enum VariableType
{
Password = 1,
Date = 2,
Time = 3,
DateTime = 4,
Encrypted = 5,
}
//This is a ClassMemberName from EmailVariable Table
public enum VariableClassMemberName
{
SubscriberID,
UserId,
PackageId,
StatusID,
CompanyID,
}
}
}

Here Header and Footer are EmailTemplates but can be treated as a Variable to be included in other emails for consistent layout of all templates like if you want to have a flash banner and some links on the top and copyrights statement on bottom of every template then instead of doing this in all templates just create a Header and Footer template and just add a variable in each template and it will automatically placed there. In this way you create as many sections of your each template as you would like to.

UI

I have designed the UI for editing the template just like following but its up to you how you design the UI.

UI

Thanks to Telerik for their wonderful RichTextBox control :)

Calling Code

System.Collections.Specialized.NameValueCollection values = new System.Collections.Specialized.NameValueCollection();
               values.Add(EnumModel.VariableClassMemberName.UserId.ToString(), user.UserID.ToString());

Note that in above code we are adding the value of UserId whose password needs to be sent.

Now call the Parser.Parse method to get the bodytext for email.

like this

string mailBody=Parser.Parse(forgotPasswordEmailId, values);

finally write some your own code to send email with this mail body :)


When working on web projects there is a common requirement is to show flash files as a banner. Html Object tag allows you to show flash files but its a core html tag, what if you want to add have this functionality on server side? Here is the simple solution

using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Web;
using System;

namespace BitLogix.Web.Controls
{
   public class Image :System.Web.UI.WebControls.Image 
    {

       protected override void Render(System.Web.UI.HtmlTextWriter writer)
       {
           if (ImageUrl.Length > 0)
           {
              
               StringBuilder html = new StringBuilder();
              
               if (ImageUrl.ToLower().EndsWith( “.swf”) )
                   Type = FileType.Flash;
               else if (ImageUrl.ToLower().EndsWith(“.html”) || ImageUrl.ToLower().EndsWith(“.htm”) )
                   Type = FileType.Html;
               else if(ImageUrl.ToLower().EndsWith(“</object>”))
                   Type = FileType.Embeded;
               else
                   Type = FileType.Image;
              

               if (Type == FileType.Flash)
               {
                         
                long RandomNumber = DateTime.Now.Ticks ;
                html.Append(“<object classid=’clsid:D27CDB6E-AE6D-11cf-96B8-444553540000′”);
                html.Append(string.Format( “codebase=’http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0′ width=’{0}’”,Width.ToString()));

                if(Height.IsEmpty ==false)
                    html.Append(” height= ” + Height.ToString() );
                html.Append( string.Format(“> <param name=’movie’ value=’{0}?dummyVar={1}’>”,ImageUrl ,RandomNumber));

                html.Append(” <param name=’quality’ value=’high’>”);

                html.Append( string.Format(“<embed src=’{0}?dummyVar={1}’ quality=’high’”,ImageUrl ,RandomNumber));

                html.Append(“  pluginspage=’http://www.macromedia.com/go/getflashplayer’ type=’application/x-shockwave-flash’></embed></object>”);

                writer.Write(html.ToString());
               }
               else if (Type == FileType.Html)
               {
                   html.Append(“<IFRAME src=’” + ImageUrl + “‘ align=’top’ border =’0px’ frameborder =’0′ scrolling = ‘no’ width =’100%’ marginheight=’0px’ marginwidth =’0px’ noresize = ‘noresize’>”);

                   html.Append(“</IFRAME>”);
                   writer.Write(html);
               }
               else if (Type == FileType.Embeded)
               {
                   writer.Write(ImageUrl);
               }
               else
               {

                   if (NavigateUrl.Trim().Length > 0)
                       writer.Write(“<A href=’” + NavigateUrl + “‘ target =’” + Target + “‘  >”);

                   base.Render(writer);

                   if (NavigateUrl.Trim().Length > 0)
                       writer.Write(“</A>”);
               }
           
           }

       }

       /// <summary>
       /// URL to redirect when clicked
       /// </summary>
       public string NavigateUrl
       {
           get
           {
               object obj = ViewState["NavigateUrl"];
               if (obj == null)
                   return string.Empty;
               return obj.ToString();
           }
           set { ViewState["NavigateUrl"] = value; }
       }
       /// <summary>
       /// URL Target
       /// </summary>
       public string Target
       {
           get
           {
               object obj = ViewState["Target"];
               if (obj == null)
                   return “_blank”;
               return obj.ToString();
           }
           set { ViewState["Target"] = value; }
       }
       /// <summary>
       ///File Type
       /// </summary>
       private  FileType  Type
       {
           get
           {
               object obj = ViewState["Type"];
               if (obj == null)
                   return  FileType.Image ;
               return (FileType) obj;
           }
           set { ViewState["Type"] = value; }
       }

    }

   public enum FileType
   {
      
       Image,
       Flash,
       Embeded,
       Html

   }
}


 Sql server 2005 includes new Transact-SQL (T-SQL) functionality. The enhancements span the range from an alternative mechanism for transaction isolation to declarative support for hierarchical queries. And statement-level recompilation even improves existing T-SQL applications that were written before 2005.

Improvements to Transact-SQL

Microsoft has continually improved the Transact SQL language and the infrastructure of SQL Server itself. In brief, the improvements include the following:

SNAPSHOT isolation—Additional isolation level that does not use write locks

  • Statement-level recompile—More efficient recompilation of stored procedures
  • Event notifications—Integration of Data Definition Language (DDL) and DML operations with Service Broker
  • Large data types—New data types that deprecate TEXT and IMAGE
  • DDL triggers—Triggers that fire on DDL operations
  • Common Table Expressions—Declarative syntax that makes a reusable expression part of a query
  • Hierarchical queries—Declarative syntax for tree-based queries
  • PIVOT—Declarative syntax aggregations across columns and converting columns to rows
  • APPLY—New JOIN syntax made for use with user-defined functions and XML
  • TOP—Row count based on an expression
  • Transaction abort—TRY/CATCH syntax for handling errors

for more details visit

http://www.informit.com/articles/article.asp?p=327394&rl=1