Wednesday, December 9, 2009

Silverlight 3 : Enable and Disable Validation For Control.

Please check previous post about validation with silverlight.

Enable and Disable Validation or you can say manually adding and remove binding for control.

In previous post i bound myName TextBox to Name property of Customer, But some case you do not want to validate that control and to do so you need to clear binding. ( Simplest way as per my thinking).

1. Remove Binding in Silverlight or Disable Validation

// Clear all errors from validation summary. ( Review previous post XAML)

valida.Errors.Clear();

// Set Text to clear ( As per your need )
myName.Text = String.Empty;

//This call will cleae binding for TextProperty( Take any dependency property)
myName.SetValue(TextBox.TextProperty, DependencyProperty.UnsetValue);
            myName.ClearValue(TextBox.TextProperty);

2. Adding Binding in Silverlight or Enable Validation.

Binding binding = new Binding("Name");
           binding.ValidatesOnExceptions = true;
           binding.NotifyOnValidationError = true;
           binding.Mode = BindingMode.TwoWay;
           myName.SetBinding(TextBox.TextProperty, binding);


Let me know your comment on this.

Silverlight 3 : Validation

To do validation in silverlight 3 , need to use dataannotation. In my previous post i discussed about binding and resource file.

1. Sample XAML File.

<UserControl xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"  xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"  x:Class="SilverlightApplication2.MainPage"    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SilverlightApplication2.Resourses" xmlns:localCustom="clr-namespace:SilverlightApplication2"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
    <UserControl.Resources>
        <local:Strings x:Key="LocStrings"></local:Strings>
        <localCustom:DisplayLabelConvertor x:Key="display"></localCustom:DisplayLabelConvertor>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="#FF333333">     
        <StackPanel Orientation="Vertical" x:Name="MyDataForm" BindingValidationError="MyDataForm_BindingValidationError" >
            <dataInput:ValidationSummary x:Name="valida" Height="100"></dataInput:ValidationSummary>     

            <TextBox x:Name="myName" Text="{Binding Name,Mode=TwoWay,ValidatesOnExceptions=True,NotifyOnValidationError=True}" >
            </TextBox>         
                <Button Content="save" Click="Button_Click"></Button>
        </StackPanel>
    </Grid>
</UserControl>

2. CS File.

public partial class MainPage : UserControl
    {
        Customer c = new Customer();
        private int _errorCount = 0;
        public MainPage()
        {
            InitializeComponent();       
            MyDataForm.DataContext = c;
        }

        private void MyDataForm_BindingValidationError(object sender, ValidationErrorEventArgs e)
        {
            if (e.Action == ValidationErrorEventAction.Added)
                _errorCount++;
            else if (e.Action == ValidationErrorEventAction.Removed)
                _errorCount--;
        }     

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _errorCount = 0;

            // Need to do for validating control.
            // If you do not do this then untill you make any change in control no validation will work.
            // Like form first time open and you prees submit then it will not validate . To do so this is required.
            BindingExpression exp = myName.GetBindingExpression(TextBox.TextProperty);
            if (exp != null)
            exp.UpdateSource();

            if (_errorCount ==0)
            {
                //Success
            }
            else
            {
                //Error
            }
        }

    }

3. Enjoy Validation………… :)

Let me know your comment.

Sunday, December 6, 2009

Silverlight 3 and Resource File

In silverlight you can access resource file to customize label and other data that need to be localize.

1. Create class that use DataAnnotation attributes.

public class Customer
   {
       private string _name = string.Empty;
       [Display(ResourceType=typeof(SilverlightApplication2.Resourses.Strings),Name="CustomerLabel")]
       [Required(ErrorMessageResourceType = typeof(SilverlightApplication2.Resourses.Strings), ErrorMessageResourceName = "CustomerNameError")]
       public string Name
       {
           get
           {
               return _name;
           }
           set
           {
               Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "Name" });               
               _name = value;
           }
       }
   }

In above class you can see that for Display and Required attribute , ResourceType and ErrorMessageResourceType set. This will point to resource file. Also in setter of property you have to validate the value.

2. Add resource file as per your need. For example here i added Strings.Resx file.

Step 3 is very very important in order to access resource in .xap file.

3. Specially for Silverlight open Strings.Resx.cs file. Change access modifier from internal to public. Also set public for each resource string. ( See below images.)

image

image

Generate another resource file for different culture. For example fr-CA culture you need to generate Strings.fr-CA.resx.

4. Now in silverlight application if you use DataForm then just need to do following.This will automatic use label from display resource.

dfCustomer.CurrentItem = new Customer();

5. To access resource in XAML.

<UserControl xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"  xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"  x:Class="SilverlightApplication2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SilverlightApplication2.Resourses" xmlns:localCustom="clr-namespace:SilverlightApplication2"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
    <UserControl.Resources>
        <local:Strings x:Key="LocStrings"></local:Strings>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="#FF333333">     
        <StackPanel Orientation="Vertical" x:Name="MyDataForm" >
            <dataInput:ValidationSummary Height="100"></dataInput:ValidationSummary>          
            <TextBox Text="{Binding Name,Mode=TwoWay,ValidatesOnExceptions=True,NotifyOnValidationError=True}" >
            </TextBox>
            <Button Content="save" Click="Button_Click"></Button>
        </StackPanel>
    </Grid>
</UserControl>

In cs file.

public MainPage()
       {

           InitializeComponent();        
           Customer c = new Customer();
           c.Name = "TEST";
           MyDataForm.DataContext = c;
       }

 

6. Last step but very important. You have to edit .csproject file in notepad. Add supportedcultures.

<SupportedCultures>fr-CA
</SupportedCultures>

Let me know update or any other idea about resource file.

ASP.net MVC 2 : Client-side Validation and Resource file

In my previous post i gave example of client side validation. Also you need to localize error message. To do this you need to add resource file.Add resource file following way.

image

During creation of Student model you need to specify the resource.

public class Student
   {
       [Required(ErrorMessageResourceType = typeof(StudentResourse), ErrorMessageResourceName = "FirstNameError")]
       [DisplayName("User name")]
       public string FirstName { get; set; }

       [Required(ErrorMessageResourceType = typeof(StudentResourse), ErrorMessageResourceName = "EmailError")]
       [DisplayName("Email address")]
       public string Email { get; set; }

       [Required(ErrorMessageResourceType = typeof(StudentResourse), ErrorMessageResourceName = "PriceError")]       
       [DisplayName("Fees")]
       public double Fees { get; set; }
   }

Here you can see that ErrorMessageResourceType and ErrorMessageResourceName. This is used to identify resource file and resource name.

image

you need to create resource file for each culture you need. For example fr-FR.

image

As per the CurrentUICulture message is displayed.

ASP.net MVC 2 : Client-side Validation

In ASP.net MVC 2 Beta, DataAnnontation supports for validation . While creating model you can give attribute that use to support validation.

public class Student
   {
       [Required(ErrorMessage="Firstname is required field.")]
       [DisplayName("User name")]
       public string FirstName { get; set; }

      [Required(ErrorMessage = "Email is required field.")]
       [DisplayName("Email address")]

       public string Email { get; set; }

      [Required(ErrorMessage = "Fees is required field.")]      
       [DisplayName("Fees")]
       public double Fees { get; set; }
   }

Now use this model class to create view.

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication12.Models.Student>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    ViewPage2
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>

<h2>ViewPage2</h2>
<% Html.EnableClientValidation(); %>

    <% using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Fields</legend>
            <p>
                <%= Html.LabelFor(model => model.FirstName) %>
                <%= Html.TextBoxFor(model => model.FirstName) %>
                <%= Html.ValidationMessageFor(model => model.FirstName) %>
            </p>
            <p>
                <%= Html.LabelFor(model => model.Email) %>
                <%= Html.TextBoxFor(model => model.Email) %>
                <%= Html.ValidationMessageFor(model => model.Email) %>
            </p>
            <p>
                <%= Html.LabelFor(model => model.Fees) %>
                <%= Html.TextBoxFor(model => model.Fees) %>
                <%= Html.ValidationMessageFor(model => model.Fees) %>
            </p>
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%=Html.ActionLink("Back to List", "Index") %>
    </div>

</asp:Content>

To enable client side validation need to add javascript and  <% Html.EnableClientValidation(); %>.

Let me know your comment on this.

Tuesday, November 17, 2009

Translation WebPart using Bing Service

This is my first project that i added to codeplex. That contain source code as well as binary with PDF document.

Translation WebPart

As mention in codeplex you can use webpart with WSS/MOSS . But even you can use this with Simple ASP.net WebSite.

Let me know your comment on this.

Sunday, September 20, 2009

Cross-thread operation not valid.

In window application , when you need to use Threading and access control inside that thread, then you get this error “Cross-thread operation not valid.” The reason behind this control is working under main thread and you create another thread in which you are trying to access control.

There are two ways to solve this error.

1. Set property in Form constructor.
You need to set static property CheckForIllegalCrossThreadCalls  of control class to false value. This will disable cross thread checking.
       
       public Form1()
       {
         InitializeComponent();
           Control.CheckForIllegalCrossThreadCalls = false;
       }

Sample Code (C#):

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Test));
            th.Start(1000);           
        }

        public void Test(object o)
        {
            for (int i = 0; i < 10; i++)
            {
                label1.Text = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + " --- " + i.ToString();
                System.Threading.Thread.Sleep(int.Parse(o.ToString()));
            }
        }
    }



2. Use delegate and event.

Sample Code (C#) :

public partial class Form1 : Form
    {
        delegate void SetLabelText(string str);
        SetLabelText setLabel1Text = null;
        public Form1()
        {
            InitializeComponent();
            setLabel1Text = new SetLabelText(Label1Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Test));
            th.Start(1000);           
        }

        public void Test(object o)
        {
            for (int i = 0; i < 10; i++)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(setLabel1Text, System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + " --- " + i.ToString());
                }
                System.Threading.Thread.Sleep(int.Parse(o.ToString()));
            }
        }

        public void Label1Text(string str)
        {
            label1.Text = str;
        }
    }

Please give your comment on this.

Sunday, June 14, 2009

Remove Focus Rectangle From Button

Article is about to remove focus rectangle or say cues from Button in window form application.

First let discuss what default focus rectangle. Please look at following image , in that image OK button has default focus so it display cues rectangle.

image 
(FlatStyle == System)

When we want to set background image of button to make button attractive in that case this default rectangle create problem with look and feel.

image
(FlatStyle = Standard)
 
 image
(FlatStyle = Flat)

In above two image need to set FlatApperance.BorderStyle =0. You can visualize that in all above case default focus rectangle make button look ugly with background image.

To remove this cues ( Default focus rectangle ) you need to set ShowFocusCues property of Button to false but this property does not directly available to Button. This property available in ButtonBase class with protected access specifier. In order to set this property to false we need to create class that inherits from Button or ButtonBase and set this property explicitly false.

class CustomButton : System.Windows.Forms.Button
    {
        protected override bool ShowFocusCues
        {
            get
            {
                return false;
            }
        }
}

image
Now see that default focus rectangle is removed.

More generic class for Button.

class CustomButton : System.Windows.Forms.Button
   {
       private bool _DisplayFocusCues = true;
       protected override bool ShowFocusCues
       {
           get
           {
               return _DisplayFocusCues;
           }
       }

       public bool DisplayFocusCues
       {
           get
           {
               return _DisplayFocusCues;
           }
           set
           {
               _DisplayFocusCues = value;
           }
       }
   }

Using this class you can set DisplayFocusCues at design time so CustomButton work with any case. ( Want to display focus rectangle or not).

image 

Hope this solution is help you to create button without cues.

Your suggestion is always invited.

Programmatically Install Window Service

This article is about to install / uninstall window service programmatically from C#. This is useful when you need to install / uninstall window service from some other application.

For this purpose you need to use ServiceProcessInstaller and ServiceInstaller class from another application. These two installer classes are responsible for Installation of service.

C# Example for Programmatically Install Window Service.

ServiceProcessInstaller ProcesServiceInstaller = new ServiceProcessInstaller();
ProcesServiceInstaller.Account =  ServiceAccount.User;
ProcesServiceInstaller.Username = "<<username>>";
ProcesServiceInstaller.Password = "<<password>>";

ServiceInstaller ServiceInstallerObj = new ServiceInstaller();
InstallContext Context = new System.Configuration.Install.InstallContext();
String path = String.Format("/assemblypath={0}", @"<<path of executable of window service>>");
String[] cmdline = { path };

Context = new System.Configuration.Install.InstallContext("", cmdline);              
ServiceInstallerObj.Context = Context;
ServiceInstallerObj.DisplayName = "MyService";
ServiceInstallerObj.Description = "MyService installer test";
ServiceInstallerObj.ServiceName = "MyService";
ServiceInstallerObj.StartType =  ServiceStartMode.Automatic;
ServiceInstallerObj.Parent = ProcesServiceInstaller;          

System.Collections.Specialized.ListDictionary state = new System.Collections.Specialized.ListDictionary();
ServiceInstallerObj.Install(state);

C# Example to Programmatically Uninstall Window Service.

ServiceInstaller ServiceInstallerObj = new ServiceInstaller();
InstallContext Context = new InstallContext("<<log file path>>", null);
ServiceInstallerObj.Context = Context;
ServiceInstallerObj.ServiceName = "MyService";
ServiceInstallerObj.Uninstall(null);

other article related to window service.

http://dotnetstep.blogspot.com/2009/06/passing-parameter-to-installutil.html

http://dotnetstep.blogspot.com/2009/06/install-window-service-without-using.html

http://dotnetstep.blogspot.com/2009/06/install-windowservice-using-installutil.html

http://dotnetstep.blogspot.com/2009/06/get-windowservice-executable-path-in.html

Please give your idea about this article.

Saturday, June 13, 2009

Passing Parameter to InstallUtil

When installing window service or any installer ( class inherits from install class) required custom parameter at run time , Need to pass as parameter of installutil.

Crating window service using article (http://dotnetstep.blogspot.com/2009/06/install-windowservice-using-installutil.html).  This article suggest you add installer ( ProjectInstaller). Now we use installer class events to configure ServiceProcessInstaller and ServiceInstaller as per parameter pass to installutil.

[RunInstaller(true)]
public partial class ProjectInstaller : Installer
    {
        public ProjectInstaller()
        {
            InitializeComponent();
           this.BeforeInstall += new InstallEventHandler(ProjectInstaller_BeforeInstall);
            this.BeforeUninstall += new InstallEventHandler(ProjectInstaller_BeforeUninstall);
        }       

        void ProjectInstaller_BeforeInstall(object sender, InstallEventArgs e)
        {
            // Configure Account for Service Process.
            switch(this.Context.Parameters["Account"])
            {
                case "LocalService":
                    this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService;
                    break;
                case "LocalSystem":
                    this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
                    break;
                case "NetworkService":
                    this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.NetworkService;
                    break;
                case "User":
                    this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.User;
                    this.serviceProcessInstaller1.Username = this.Context.Parameters["UserName"];
                    this.serviceProcessInstaller1.Password = this.Context.Parameters["Password"];
                    break;
            }      
            // Configure ServiceName
            if(!String.IsNullOrEmpty(this.Context.Parameters["ServiceName"]))
            {               
                this.serviceInstaller1.ServiceName = this.Context.Parameters["ServiceName"];
            }
        }

        void ProjectInstaller_BeforeUninstall(object sender, InstallEventArgs e)
        {
            if (!String.IsNullOrEmpty(this.Context.Parameters["ServiceName"]))
            {
                this.serviceInstaller1.ServiceName = this.Context.Parameters["ServiceName"];
            }
        }
    }

Above ProjectInstaller class handle two events : BeforeInstall and BeforeUninstall. BeforeInstall is called just before install method of installer (ProjectInstaller) called via InstallUtil and same way BeforeUninstall called just before Uninstall method of projectinstaller class. After adding that two event handler use following to configure service using installutil.

1. Install
installutil /Account=User /UserName=admin /Password=admin /ServiceName=WinService1 /i WindowService1.exe

2. Uninstall
installutil /ServiceName=WinService1 /u WindowService1.exe

This will also help you configure WindowService1.exe with two different name and different account.
installutil /Account=User /UserName=admin /Password=admin        /ServiceName=WinService1 /i WindowService1.exe

installutil /Account=LocalSystem /ServiceName=WinService2 /i WindowService1.exe

Install window service without using installutil

Article is about to install window service without using InstallUtil utility.
Windows XP or Later has command line utility called sc . (This utility talks with service controller and with services from command line).
SC is a window base utility. AS explain in article http://dotnetstep.blogspot.com/2009/06/install-windowservice-using-installutil.html sc does not required ProjectInstaller.

1. Start service using sc
          sc start ServiceName

2. Stop serivce
         sc stop ServiceName

3. Delete window service
        sc delete servicename
        Note : During delete call if service is in running state then service is delete when nexttime service is stop or PC restart.

4. Create window service
       sc create ServiceName binpath= “c:\windowservice1\windowservice1.exe”

       Apart from above many option available . For that just go to command prompt and type sc create /?

  For example configure service running account.

sc create servicename binpath= “c:\windowservice1\windowservice1.exe” obj= administrator password= pass

Hope this article will help you .

Please give your comment or idea about this.

In above all case Service ServiceName ( Mark as blue) , don’t use display name.

 image

Install WindowService using installutil.

This article is about to install to window service using installutil.exe. InstallUtil.exe or simply say installutil utility comes up with .NET Framework 2.0.

Steps.
1. Create new Window Service Project.
image 
2. After that open services1.cs in design mode . It looks like this.
image 
3. Now right click on design window. It open popup menu with installer option.
image
4. When you click on Add Installer. It will will add new class called projectinstaller.cs. It contain serviceprocessinstaller1 and serviceinstaller component. ServiceProcess installer is used to configure service account and serviceinstaller contain information about service.
image
5. Apart from above ProjectInstaller.cs contain following code which is used to call from installutil.
image
In above code RunInstaller attribute marked as true. So InstallUtil take this thing into consideration and use this information to call installer.

To install using installutil open VS 2005/VS 2008 command prompt or go to  %windir%\Microsoft.NET\Framework\v2.0.50727.

installutil.exe /i  WindowService1.exe ( To Install ).

installutil.exe /u WindowSerivce1.exe ( To uninstall).

Installutil use Installer class (Projectinstaller) to install service.

If you mark RunInstlaller as false then this installutil not work.

If you don’t want to use installutil to install wndow service then go to http://dotnetstep.blogspot.com/2009/06/install-window-service-without-using.html.

Tuesday, June 9, 2009

Get WindowService Executable Path In .NET

WindowService has a property called “Path to Executable” . This property contains path of window service that is going to execute. When you need this path in .NET Application there is no direct way to do it . You can not get it either via ServiceControler or any other way.

image 
To get that you need to read Registry. All information about all window service installed on machine storead at following location.
HKLM\SYSTEM\CurrentControlSet\Services.

C# Code to read Service Registry.

RegistryKey services = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services");
if (services != null)
{
object pathtoexecutable = services.OpenSubKey(<<ServiceName>>).GetValue("ImagePath");
}

In Above code replace <<ServiceName>> with your service name.

Also this is a registry operation so you need proper permission to read registry and apply any other registry operation at your own risk.

Give your comment or any new idea about this task.

Sunday, June 7, 2009

Redirect console application output to another application in .NET

In .NET sometime it is required to execute system command and capture its result or data in application that execute that command.
For example you want to execute ipconfig command from .NET application and display its result in window application or need to read output of .NET console application.

For this purpose you need to use Process class that belongs to System.Diagnostics namespace.

//Create process class object
System.Diagnostics.Process p = new System.Diagnostics.Process();

// Set StartInfo property.
// Set redirection true for Error and output stream.
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;

// When you set redirection you must set UseShellExecute to false .
p.StartInfo.UseShellExecute = false;

// Set window style
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

// Set Command paramter.
p.StartInfo.FileName = "ipconfig";
p.StartInfo.Arguments = " /all";

// Set CreateNoWindow to true as window is not required here.
p.StartInfo.CreateNoWindow = true;

// Following two events are new in .NET framework 2.0 which allow us to capture data asynchronously.

p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_OutputDataReceived);
p.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_ErrorDataReceived);

// Start the process.
p.Start();

// Must call following two methods in order to capture data asynchronously.
p.BeginErrorReadLine();
p.BeginOutputReadLine();

// Wait for Process to Exit ( This is not must done ).
p.WaitForExit();

// Event Handler for ErrorStream.
void p_ErrorDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
            System.Diagnostics.Debug.WriteLine(e.Data);   
}

// Event Handler for OutputStream.
void p_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
           System.Diagnostics.Debug.WriteLine(e.Data);
}

Even you can use this functionality to make utility like process command background and produce result in window application.

p.StartInfo.FileName = @"%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe";
p.StartInfo.Arguments = @" -v / -f -p C:\Blog\WebSite1 c:\WebSite1Compile";
// Note : Replace %windir% with your window directory. or use p.StartInfo.EnvironmentVariables["windir"]

Above is the one example to compile website application from window application.

Apart from this there is event called Exited associated with Process class object. In order to receive this event you need to set EnableRasingEvents property to true value.

Give your comment and idea on this article.

Saturday, June 6, 2009

DateTime operation in .NET Application

DateTime is a very important datatype and data in terms of realtime application. Some of the application that run timely manner and some of the application that generate data (log file) with time.
To generate such report you need to required store information about date and time.

In .NET there is datatype called DateTime. This contain all information about datetime but sometime problem with this too.

For example:

DateTime dt = DateTime.Now;  // 6/6/2009 09:35:00 PM.
This is used to get current current time of system. If you store this time in file or in a database and later you retrieve then you get that time. So at last “6/6/2009 09:35:00 PM” this is going to  store in a file.

Problem occur when you retrieve this later to display information and by some reason you make changes to current time zone of system or sometime timezone of application. So then also you get “6/6/2009 09:35:00 PM.” as data , which is not right.

So best way to store date is UTC format.

DateTime dt = DateTime.UtcNow and after retrieval convert it to LocalTime but for that also you have to confirm that stored DateTime is in Utc format.

DateTime structure contains  methods called ToBinary() and FromBinary().

long binaryDate  = DateTime.Now.ToBinary() ;

Now store ‘binaryDate’ value in database or text file. So later when you get this value.

DateTime dt =  DateTime.FromBinary(binaryDate).  This will generate correct Date and Time even after timezone changed. This is because of binaryDate( Long ) value contain information about TimeZone too. So it automatically adjust as per system timezone.

Apart from this DateTime structure contain one field called ‘Kind’. which contain current DateTime format kind and that is Utc , Local or Unspecified. Many of case when you store simple way DateTime and later you retrieve kind is unspecified. But when you store binary date and later you retrieve you get either Utc or Local.

Please give your comment or any new idea about storing datetime.

Usage of aspnet_compiler.exe and aspnet_merge.exe

Whenever asp.net website or webapplication publish,aspnet_compiler.exe is used for compilation. 

Example :

WebSite : c:\myProject\TestSite

1 . Go to Visual Studio Tool from program menu and start Visual studio command prompt.
                                     or
     If you do not have visual studio installed on your machine and just .NET Framework 2.0 installed on your machine then also you can use aspnet_compiler tool. 
- Start > run  and type cmd.
- set path=%windir%\Microsoft.NET\Framework\v2.0.50727
- aspnet_compiler –v / –p c:\myproject\testsite c:\testcompile
  
   It will compile c:\myproject\testsite and put published site in c:\testcompile. 
- When you compile site using above command site is not updatable after publish. 
-  If you want to site updatable after publish add –u option to it.
- It is good to add –f option in order to override existing published site.
- Fore more help just type aspnet_compiler /?

Now let discuss about aspnet_merge.exe tool. This tool is introduce later and it is used to merge all assemblies that is located in bin directory of published site. When you published website project many assemblies are in bin directories depending upon your option.

- In aspnet_compiler if you add –fixednames option then it will generate single assembles for each page otherwise it is generated per directory (this is default for asp.net website project).

- Main disadvantage of different assembles either way is problem with reflection. You are not able to get control and page information located in another assemblies without assemblies loading programmatically.

- aspnet_merge.exe tool merge all aspnet generated assemblies to single assemblies.

Example :

1. set path=%programfiles%\Microsoft SDKs\Windows\v6.0A\bin
2. aspnet_merge c:\testcompile
   This will create single DLL ( assembly ) in bin directory.
3. To set generated assembly name use this.
    aspnet_merge –o Single.dll c:\testcompile.

Hope this will help you.

Please give your comment and advice on this.

Thursday, May 28, 2009

BuildManager To Get Detail About Dynamic Compiled Assembly

Here i am going to explain how one can use BuildManager to get detail about dynamic generated Assembly.
In ASP.net 2.0 or ASP.net 3.5 , there are two type of projects. One is ASP.net Web Application and Another one is ASP.net WebSite Project. Significant difference between these two is how they compiled or published.

1. When “ASP.net WebApplication“ project published it create only Single DLL file in Bin for whole application and DLL name is also predetermined. Also when any new item added to the Project ( Either Web Form or Web User Control ) it comes under one namespace.

2. When “ASP.net WebSite“ project published then it create many DLL file in bin directory. No of DLL depend on condition you choose when publish “ASP.net WebSite” project.

image
- When only first checkbox is checked then it create assembly per directory. In following image you can see one sample solution. So it create one assembly for Top Level directory and their page and control and one assembly for TestControls directory.

       image

- When second checkbox is selected then it creates separate assembly for each page and each controls.

Now main thing “BuildManager” comes into picture. 

1. If you have “ASP.net WebApplication” project then you can access of another type in project via namespace. For Example you have two page "Default.aspx” and “Default2.aspx” and you want to just create instance of “Default.aspx” via its type in “Default2.aspx”.

namespace WebApplication3
{
    public partial class _Default : System.Web.UI.Page
    {
        public string GetMessage()
        {
              return “Hello”;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
        }
    }
}

namespace WebApplication3
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        { 
            WebApplication3._Default dForm = new _Default();
            Response.Write(dForm.GetMessage());
         }
    }
}
so it is very easy for “ASP.net WebApplication” project.

2.  For “ASP.net Web site“ type of project this is not a case. This type of project does not allow you to access another simple way as above. For that you have to use BuildManager Class.

public partial class _Default : System.Web.UI.Page
{   
protected void Page_Load(object sender, EventArgs e)
{   
// You can not access Default2 class directly.    
// Get Type using BuildManager.
// Here i specified virtual path.

Type compiled_o =  System.Web.Compilation.BuildManager.GetCompiledType("~/Default2.aspx");                
//Detail about assembly. Fully qualified name which contain dynamic assembly name too.
Response.Write(compiled_o.FullName);
// Create instance of Type.
object obj =  Activator.CreateInstance(compiled_o);
// GetData is a Method to call.
System.Reflection.MethodInfo info = compiled_o.GetMethod("GetMessage"); 
// Now Call method . Here Method GetData is a instance method so we need to call
// Invoke method with obj. null as no argument required.
object data = info.Invoke(obj, null);
// Check that data contain value.
if (data != null)
{
  Response.Write(data.ToString());

}
}
public partial class Default2 : System.Web.UI.Page
{
    public string GetMessage()
    {
              return “Hello”;
    }
    protected void Page_Load(object sender, EventArgs e)
    {
    }
}

BuildManager class has static method GetCompiledType, which required virtual path as a input so you can even give virtual path of user control too.

Please give your comment on this.

Saturday, May 16, 2009

SMTP Setting to send outbound email

Here i am going to explain about steps required to configure SMTP (Local SMTP) to send outbound email.

Steps.
1. Go to run and Type inetmgr. After inetmgr ( Internet information services manager ) open. Right click on Default SMTP virtual server ( As shown in figure 1) . If this is not displayed in your inetmgr then you need to first install SMTP services using Add/ Remove component.
 1

2. After right click on Default SMTP virtual server go for property 
menu item. It will display as show in following image.
image
3. Now go in Access Tab and click on relay. Please select as shown in following image and click ok.
 2
4. After that go for delivery tab. ( Display as follows)
 image

5. Click on outbound security . In that tab select basic authentication. Here i am using by gmail account to send outbound email. AS gmail required TLS (security to transfer credential) , you have to select TLS encryption checkbox too.Then click on ok.
5
7. Now go for outbound connection button. It will display as follows. Please specify TCP port as 587 for gmail otherwise 25 as default.
3

8. Click on Advanced . Configure as follows . In case of other SMTP , you have to specify that smtp server.

4

Click ok and then finally click on apply. Now restart smtp server using inetmgr.
Note : Here i took Gmail smtp setting . For that you need to configure Gmail account from Gmail setting and click on IMAP enable.

Thursday, May 14, 2009

DataTable / DataSet and Linq

1. Querying DataTable using Linq 
    Here i am going to explain how you can use linq to get data from DataTable.
    You need to use AsEnumerable() method of DataTable object to query datatable using linq.
Example :  
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Name");
DataRow dr = dt.NewRow();
dr["ID"] = "1";
dr["Name"] = "Test1";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["ID"] = "2";
dr["Name"] = "Test2";
dt.Rows.Add(dr);

var result = from user in dt.AsEnumerable()
                     where user.Field<string>("ID") == "1"
                     select user;


2. Join Two DataTable using Linq.
     Example : Here i take two datatable.

        DataTable dt = new DataTable();
        dt.Columns.Add("ID");
        dt.Columns.Add("Name");
        DataRow dr = dt.NewRow();
        dr["ID"] = "1";
        dr["Name"] = "Test1";
        dt.Rows.Add(dr);
        dr = dt.NewRow();
        dr["ID"] = "2";
        dr["Name"] = "Test2";
        dt.Rows.Add(dr);

        DataTable dt1 = new DataTable();
        dt1.Columns.Add("ID");
        dt1.Columns.Add("Product");
        dr = dt1.NewRow();
        dr["ID"] = "1";
        dr["Product"] = "Test-Product";
        dt1.Rows.Add(dr);

Linq Query:

var c = from p in dt.AsEnumerable()
join d in dt1.AsEnumerable() on p.Field<string>("ID") equals d.Field<string>("ID")
select new { ID = p.Field<string>("ID"), Name = p.Field<string>("Name"), Product = d.Field<string>("Product") };

3. Except and Intersect operation between two DataTable using Linq .

        DataTable dt = new DataTable();
        dt.Columns.Add("ID");
        dt.Columns.Add("Name");
        DataRow dr = dt.NewRow();
        dr["ID"] = "1";
        dr["Name"] = "Test1";
        dt.Rows.Add(dr);
        dr = dt.NewRow();
        dr["ID"] = "2";
        dr["Name"] = "Test2";
        dt.Rows.Add(dr);

        DataTable dt1 = new DataTable();
        dt1.Columns.Add("ID");
        dt1.Columns.Add("Name");
        dr = dt1.NewRow();
        dr["ID"] = "1";
        dr["Name"] = "Test1";
        dt1.Rows.Add(dr);

        var  exceptresult = dt.AsEnumerable().Except(dt1.AsEnumerable(), System.Data.DataRowComparer.Default);

         var intersectresult  = dt.AsEnumerable().Intersect(dt1.AsEnumerable(), System.Data.DataRowComparer.Default);

For both of above operation you need to specify DataRowComparer . System.Data.DataRowComparer is a static sealed class and its static property Default contain comparer reference.  You must have to specify comparer for this operation on Reference datatype.

Next blog i will give you CustomDataRow Comparer to make it more efficient.

Important Tool For .NET

1. Managed Stack Explorer 
    This tool is used to monitor all managed process and their threads.
    You can download that tool at following location DownLoad

2. Process Explorer
    This tool is same as Taskmanager but it will give you more detail than taskmanager. Even this tool show you process in parent child relation so it is easy to manager.
     You can find more detail and download location at following link Process Explorer.

3. CLRProfiler
    This tool is specially designed for CLR ( Common language runtime ) . This tool give you more detail about Heap graph of your application.
For .Net Framework 1.1
For .NET Framework 2.0

Tuesday, April 21, 2009

GMail SMTP Setting To Send Email From ASP.net Application

First of all , It is required to configured GMail.

1. Create Gmail account or use existing if you already have it.
2. Log in into Gmail.
3. Go Settings.
4. Go Forwarding and Enable IMAP/POP3
5. In that go to last section and enable IMAP.

Now in your Web Application / Web Site project , open web.config. Add following to web.config.

<system.net>
    <mailSettings>
      <smtp deliveryMethod="Network">
        <network host="smtp.gmail.com" port="587" userName="username@gmail.com" password="password" />
      </smtp>
    </mailSettings>
  </system.net>

GMail IMap Service runnig at port 587 so you must required to configured that. Also Gmail required SSL authentication so it is required to enable ssl for SMTPClient.

MailMessage message = new MailMessage();
message.From = new MailAddress(
from@gmail.com);
message.To.Add("to@gmail.com");

SmtpClient client = new SmtpClient();        
client.EnableSsl = true;            
client.Send(message);

Yuo can not enable SSL in web.config so you must required to configure it explicitly.

Friday, April 17, 2009

WebService Authenticate against proxy server.

When proxy server configured for PC or in a network , if it require authentication to make certain request then you have to use following code.

Error: (407) Proxy Authentication Required.

Here i am taking example of SharePoint List service. I added reference of SharePoint List Service.


ListSerivce lst = new ListSerivce();
//Get Default Proxy Setting
IWebProxy proxy = System.Net.WebRequest.DefaultWebProxy;
// Authenticate using network credential. In My case i need authentication using windows account.
proxy.Credential = new System.Net.NetworkCredential(“username”,”password”,”domain”);
lst.Proxy = proxy;
// Make Call to WebService Method.

You can even find System.Net.WebProxy.GetDefaultProxy() return default proxy setting but it is deprecated to better to use WebRequest.DefaultWebProxy.

You can even configure your own webproxy

Lists lst = new Lists();
System.Net.WebProxy proxy = new WebProxy();
proxy.Address = new Uri("
http://proxy:8090");
proxy.Credentials = new NetworkCredential ("username", "password", "domain");
lst.Proxy = proxy;

In both case credential pass as NetworkCredential but you can use CredentialCache to pass other type of credential.

Please give comment on this. Also if you have any better idea please free give your suggestion.

Thursday, April 9, 2009

CrystalReport redistribution package

This is just a small information about Crystal Report redistribution package. You can fine different packages related to Visual Studio at following location

“<system drive>:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages”

At this location you can different directories that contains .exe or .msi related to Visual Studio 2008 installation.

Friday, April 3, 2009

WSE 3.0 Setting Tool For Visual Studio 2008

WSE 3.0 Setting Tool not available in VS 2008. Here i am explaining steps required to enable it in Visual Studio 2008.

1 . Download Following Tool
     WSE 3.0 Tools
2.  Install that MSI File.
     “Basically that installation is for Visual Studio 2005.”
3.  After installation you find one file at following location.
     C:\Documents and Settings\All Users\Application Data\Microsoft\MSEnvShared\Addins
      Here i assumed that your OS is installed at C:\.
4. At that location you find this file “WSESettingsVS3.Addin”.
5. Open file in Notepad , you find following XML content.   

  <HostApplication>
    <Name>Microsoft Visual Studio Macros</Name>
    <Version>8.0</Version>
  </HostApplication>
  <HostApplication>
    <Name>Microsoft Visual Studio</Name>
    <Version>8.0</Version>
  </HostApplication>

change it to

  <HostApplication>
    <Name>Microsoft Visual Studio Macros</Name>
    <Version>9.0</Version>
  </HostApplication>
  <HostApplication>
    <Name>Microsoft Visual Studio</Name>
    <Version>9.0</Version>
  </HostApplication>

save that file.
6. Open Visual Studio , Tools – > Options –> Environments

image

Add Following
“C:\Documents and Settings\All Users\Application Data\Microsoft\MSEnvShared\Addins”

(Note : In Image it displayed D:\ as my os is on D Drive.)

7. Close all instance of Visual Studio.

8. Open it again , create web service application . Now you can se that WSE 3.0 Setting option enable.

Thursday, April 2, 2009

How to get assembly name for registration ?

When assembly added into global assembly cache and there is need for adding that assembly to web.config assemblies section.

<compilation debug="false">
          <assemblies>
            <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            </assemblies>
</compilation>

Now there is need to add System.Web.Extensions assembly , for that you need assembly detail with its public key token to register.

Easiest way to get that detail is 

1. Go to run and type assembly.

run

it will open following window.

window1

2. Now select assembly , for example system.web.extensions , then go to edit menu and select option Copy display name as shown in following image.

window2

3. Now paste data.

image

you get all detail to register assembly. Enjoy… !

Friday, March 6, 2009

Run MSI In Context Of User

Several times to install program you need administrative or other user privileges. For example you take input from user for username and password and run that program in that particular user context.

I faced problem during installing MSI in particular user context or start IIS in context of another user.

I found this solution using command line argument.

1. Inermgr ( Run following command in Command line)

C:\runas /user:administrator “mmc %sysroot%\system32\inetsrv\iis.msc”
Enter the password for administrator :

2. MSI install
C:\runas /user:administrator “msiexec /i <full path of msi file>”

c:\runas /user:administrator “msiexec /i c:\download\setup.msi”
Enter the password for administrator :

For more information just type runas /? on command line.

Thursday, March 5, 2009

Unauthorized (401.1) Exception calling Web Services in SharePoint (.Net Framework 3.5 )

After installing .NET Framework 3.5 sp1 following error may occur while making call to webservice. This thing mostly happen when you are trying to make webservice call using fully qualified domain name instead of IPAddress or Hostheader is used to map request on single port.

I found one strange thing in IIS Log that , for such request it is not sending authentication information to webservice request even though you pass it in NetworkCredential. One solution is to disable integrated authentication and use basic authentication. This will compromise with security but solve problem. Another solution that need to require registry changes. You can find it at following link with grate explanation.

http://www.crsw.com/mark/Lists/Posts/Post.aspx?ID=44
http://support.microsoft.com/default.aspx?scid=kb;EN-US;896861

SPAlert DynamicRecipient On Custom List

In SharePoint default. alert functionality available. You can subscribe Alert on List or ListItem using AlertMe action. But in certain situation you need to automize this alert. Like Alert automatically send to particular user even though he/she did not subscribe event.

There are two way to do . Create feature that receive ItemAdded or ItemUpdated Event , Find out user and email address , send email using SendEmail Functionality of SharePoint.

Another way is use DynamicRecipient property of SPAlert.

Sample List :

list

Here you can see that To Field is type of Person or Group. Send automatic email to user enter ‘To’ Field.

List Entry look Like (Edit View).

alert list entry

Note : UserName must have email id associated with him.SMTP also configured properly for site.

Now run following code against your site. (use console application).

SPSite site = new SPSite("http://yoursite");
SPWeb web = site.OpenWeb();
SPList lst = web.Lists["Alert Test"];
SPAlert alert = web.Alerts.Add();
alert.AlertFrequency = SPAlertFrequency.Immediate;
alert.AlertType = SPAlertType.List;
alert.EventType = SPEventType.All;
alert.DynamicRecipient = "To";
alert.List = lst;
alert.Status = SPAlertStatus.On;
alert.Title = “Auto Email Alert”;
alert.Filter = "<Query><IsNotNull><FieldRef Name='To'></FieldRef></IsNotNull></Query>";            
alert.Update();

You can even use FeatureReceiver to install/ Activate / deactivate this thing as a feature.

Thursday, February 12, 2009

Global Theme Setting for ASP.net 2.0 or Later.

In order to set theme globally for application. There are two ways to do that. one is longer and second one shorter way to do that.

1.
Create App_Themes directory for each application. This is special directory. You can copy Theme over here for each application.

2.
Put New theme under Themes directory of aspnet_clientfile directory.

C:\inetpub\wwwroot\aspnet_client\system_web\2_0_50727

If themes directory not found then create one. For example if theme name is Green then it should be like

C:\inetpub\wwwroot\aspnet_client\system_web\2_0_50727\Themes\Green

This will work for all website that already created. In IIS6 website can be created afterwards. so for that this clientfile does not map to new site, following location must contain themes directory and required theme folder.

C:\Windows\Microsoft.NET\Framework\v2.0.50727\ASP.NETClientFiles\Themes\Green

After that run following command from studio command prompt
> aspnet_regiis –c

Above setting works for only IIS6 or previous versino of IIS 5.

Wednesday, February 11, 2009

Kill Process On Remote Machine

It is not recommended that each and every time abort process this way but sometime it is necessary stop some process from executing on remote machine.

There are few useful command for that.

TaskList
Taskkill or tskill

Run following command on command prompt.
> TaskList     ( Current system running process list)

> TaskList /S <system name>
    e.g Remote system name remote1 then
   TaskList /S remote1
   Some of the case you require to pass credential for remote pc in that case use following command.
   TaskList /S remote1 /U <username> /P <Password>
TaskList command is used to get process id that we want to kill.

To Kill process there are two command TaskKill and tskill . I prefer TaskKill over tskill as it gives more command line options.

> TaskKill /PID <process id> ( use to kill perticular process that identified by process id on local machine)

> Taskkill /S <remote pc name or IP Address> /PID <process id> ( kill process that identified by process id on remote machine)

If remote pc require credential than use

> taskkill /S < remote pc name or IP Address> /PID <process id> /U <username> /P <password>

All above command are tested on Windows XP and Windows 2003.
You must require permission to run above command in order to use functionality.

In All Above you can use IP Address instead of remote PC name.

Sunday, February 1, 2009

Difference Between Explicit And Implicit Interface Implementation

Interface can be implemented two ways. Explicitly or Implicitly.
For Example :
public interface IEmployee
{
         string FullName
         {
               get;
               set;
         }
}

Implicit implementation of Interface
public class ImplicitClass : IEmployee
{
     public string FullName
     {
           get ;
           set ; 
     }
}

Explicit implementation of Interface.
public class ExplicitClass : IEmployee
{
    string IEmployee.FullName
    {     
           get ;
           set ;  
    }
}
Here you can see that FullName property does not have access modifier.As this is explicit implementation so it does not allow access modifier.

Now we see what happen when try to create object of both of above class.

ImplicitClass cls = new ImplicitClass();
cls.FullName = “test”;
// Above code works fine

ExplicitClass cls1 = new ExplicitClass();
cls1.FullName = “test”; // error occur

As interface implement explicitly FullName property not available directly to cl1 object b’coz it become private to the Interface type.
img1
By reflection

ImplicitClass cls = new ImplicitClass();
PropertyInfo pinfo = cls.GetType().GetProperty("FullName");
if (pinfo != null)
    {
     pinfo.SetValue(cls, "test",null);
    }       

ExplicitClass cls1 = new ExplicitClass();
PropertyInfo pinfo1 = cls1.GetType().GetProperty("FullName");
            if (pinfo1 != null) // pinfo1 is null in this case.
            {
                pinfo1.SetValue(cls1, "test",null);
            }      

By reflection way also not able to set property as can no available propertyinfo.

Solution for this is , If interface implemented explicit way then cast to Interface type then set property.

ExplicitClass cls1 = new ExplicitClass();
IEmployee emp = cls1 as IEmployee;
emp.FullName = “test”;

if want to access with use of Reflection
ExplicitClass cls1 = new ExplicitClass();                        PropertyInfo pinfo1 = cls1.GetType().GetInterface("IEmployee").GetProperty("FullName");
if (pinfo1 != null)
{
   pinfo1.SetValue(cls1, "test",null);
}      

Note: only choose explicit interface if needed. One such case is if your class previously has property/Event/Method that Interface has also , than to avoid conflict must need of explicit interface implementation.

Please give you further suggestion about this article.