Friday, April 23, 2010

URL with port number in Firefox

Firefox will block url containing port number for security reasons.
we can configure firefox to access url with port numbers.
we can override the blocked ports as follow:
Solution:
first type "about:config" into the address bar and press Enter.
then right click anywhere on the page and choose choose New -> String.
then type "network.security.ports.banned.override" in the textbox and click OK.
and in the value textbox we can enter port numbers seperated by comma., like 86,87,88
and then click OK.

How to decouple your application from IoC container implementation

As we all know, DI(Dependency Injection) is a form of IoC(Inversion of Control). when I use IoC Containers like Unity or Autofac to implement dependency injection, my application will be dependent on that framework, so if i decide to go for another IoC Container, I need to change a lot of things.what I want to achieve is how to make this change easier and how to decouple my application from any specific container. what i did is creating an interface to work with.


I need to add a reference to Microsoft.Practices.ServiceLocation.dll
and I make use of IServiseLocator interface in that assembly.
//IoCContainer.cs
//-----------------------------------------------------
using Microsoft.Practices.ServiceLocation;

public abstract class IocContainer
{
   public static IServiceLocator Locator;

   protected IocContainer()
   {
      Locator = CreateServiceLocator();
   }

  protected abstract IServiceLocator CreateServiceLocator();
}

public class IocContainerInitialization
{
  private static IocContainer _iocContainer;


  public static void Initialize(IocContainer iocContainer)
  {
    _iocContainer = iocContainer;
  }

  public static IocContainer IocContainer
  {
    get { return _iocContainer; }
  }
}
//-------------------------------------------------------------

//then for every IoC Container I want to use, I need to create a container //inheriting from that base IoCContainer class.

//for example, for using Autofac


//AutofacIocContainer.cs
//----------------------------------------------------------
using Autofac.Integration.Web;
using Autofac.Integration.Web.Mvc;
using AutofacContrib.CommonServiceLocator;
using Microsoft.Practices.ServiceLocation;

public class AutofacIocContainer : IocContainer
{
  protected override IServiceLocator CreateServiceLocator()
  {
    var containerBuilder = new ContainerBuilder();

    //For MVC-------------
  containerBuilder.RegisterControllers(System.Reflection.Assembly.GetExecutingAssembly());
    //------------------------------------------------
    RegisterTypes(containerBuilder);

    ContainerProvider containerProvider = new ContainerProvider(containerBuilder.Build());

    //For MVC-------------------------------
    System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(new  AutofacControllerFactory(containerProvider));
    //---------------------------------------------------

    return new AutofacServiceLocator(containerProvider.ApplicationContainer);
}

  private static void RegisterTypes(ContainerBuilder container)
  {
    //Cache per request
    container.Register(c => new DbHelper("MyConnectionString")).As().InstancePerLifetimeScope();

    container.Register(c => new DbMapper(c.Resolve())).As();
    container.Register(c => new TagRepository()).As();
    container.Register(c => new UserRepository()).As();
  }
}
//--------------------------------------------------------------

//Then, in your Global.asax file we need to initialize our Container.


void Application_Start(object sender, EventArgs e)
{
  IocContainerInitialization.Initialize(new AutofacIocContainer());
  RegisterRoutes(RouteTable.Routes);
}

Now, if you want to switch to another IoC Container, you only need to change one line and initialize another container.

cheers!

Thursday, April 22, 2010

ASP.NET ReportViewer problems on IIS 7

today we were trying to move our asp.net application to IIS 7, and there were some pages using ReportViewer in local mode. we had some problems to make it working.
The first thing to consider is that IIS7 need a new web.config structure. you have to register your httpModules and httpHandlers under system.webServer element instead of system.web

1- register the handler in the web.config file under system.webServer element

<system.webServer>
<add name="ReportViewerWebControl" path="Reserved.ReportViewerWebControl.axd" verb="*" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</system.webServer>

2- make sure on the aspx page using ReportViewer control you have registered the correct version. it must be like this:

<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>


Cheers!

Friday, April 16, 2010

URL Routing in ASP.NET 3.5 Webform

URL Routing decouples the URL from a physical file on the disk, we can define routing rules to specify what URL maps to what physical files. ASP.NET Routing is not only for MVC and is independent library so ASP.NET Routing can be used in a traditional ASP.NET web forms.

First, add a reference to System.Web.Routing and make sure that web.config has UrlRoutingModule HTTP Module registered in httpModules section.

then, we create this class,

CustomRouteHandler.cs
//------------------------------------------------------
public class CustomRouteHandler : IRouteHandler
{
public CustomRouteHandler(string virtualPath)
{
this.VirtualPath = virtualPath;
}

public string VirtualPath { get; private set; }

public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
foreach (var paramUrl in requestContext.RouteData.Values)
{
requestContext.HttpContext.Items[paramUrl.Key] = paramUrl.Value;
}
var page = BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(Page)) as IHttpHandler;
return page;
}
}
//--------------------------------------------------
Then in Global.asax file and in Application_Start event, I will define my routing rules.

Global.asax
//----------------------------------------------
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}


private void RegisterRoutes(System.Web.Routing.RouteCollection routes)
{
routes.Clear();

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.ashx/{*pathInfo}");

routes.Add("IndexPage", new Route("index/{page-num}", new CustomRouteHandler("~/Home/index.aspx")));
routes.Add("Index", new Route("index", new CustomRouteHandler("~/Home/index.aspx")));
routes.Add("ContactUs", new Route("contactus", new CustomRouteHandler("~/Home/contactus.aspx")));

}

The Route Data will be stored in HttpContext.Item (cache per request)
You can get the Route Data from HttpContext.Current.Items["name"] on the page.

Cheers!

Wednesday, April 14, 2010

Some Useful Design Principles

I am a big fan of design patterns and like these principles much, they can really help us decide better when facing design issues, even they can help in normal life when you don't program.


DRY : (Don't Repeat Yourself)
SOC : (Separation of Concerns)
KISS: (Keep it Simple and Stupid)
YAGNI : (You ain't gonna need it)
CQS : (Command-Query Separation)

SOLID Principles:
SRP:(single responsibility principle)
OCP:(Open Close Principle)
LSP: (Liskov substitution principle - Design By Contract)
ISP:(Interface-segregation principle)
DIP:(Dependency inversion principle)

Inheritance --> A is a kind of B
Composition --> A is a part of B
Aggregation --> A has a B

Cheers!

Friday, April 9, 2010

How to Format Decimal numbers in C# and remove extra zero digits

Sometimes you want to show the decimal numbers and you do not want to show the extra zero digits after decimal point.
for below code, if there are one or two digits to the right of the decimal point, that shows up, but, if there are digits of zero to the right of the decimal point, the number is formatted as a whole number

decimal d = 2.340M;
string result = string.Format("{0:0.##}",d); // result will be 2.34

Cheers!

How to Detect Refresh in ASP.Net web forms

I use this code to detect refresh in asp.net web forms. This methods uses Session.

I create a static class
public static class RefreshDetectionTools
{
#region Constants
private const string KEY_REF_DEC_HID = "RefDecHid";
private const string KEY_REF_DEC_STAMP = "RefDecStamp";
#endregion

#region Methods
public static bool IsPageRefresh()
{
Page page = HttpContext.Current.CurrentHandler as Page;

string val = HttpContext.Current.Request[KEY_REF_DEC_HID];

if ((val == null) || (val.Length == 0)) return false;

string stamp = HttpContext.Current.Session[KEY_REF_DEC_STAMP] as string;
if (stamp == null)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Write("Session Expired.");
HttpContext.Current.Response.End();
}
if (stamp != val)
return true;
else
return false;
}
///
/// You need to call this method in Page_PreRender to make the
/// refresh detection working
///

public static void StampRefreshDetection()
{
Page page = HttpContext.Current.CurrentHandler as Page;

string stamp = HttpContext.Current.Server.UrlEncode(DateTime.Now.ToString());

HttpContext.Current.Session[KEY_REF_DEC_STAMP] = stamp;

page.ClientScript.RegisterHiddenField(KEY_REF_DEC_HID, stamp);
}
#endregion
}

Then in any asp.net web form that needs to detect refresh, in Page_PreRender handler we need to call RefreshDetectionTools.StampRefreshDetection() and then any where you want to detect the refresh, we check StampRefreshDetection.IsPageRefresh()

Hope you enjoy, Cheers

Using ASP.Net User Controls to Create Code Generator

I m a big fan of code generators. It can help us minimize the errors and reduces the development time. Although we can use T4(text template transformation toolkit) in .Net to create code generators, But I sometimes feel like to create my own tools because I enjoy the full control over my home made tool, and I know what is going on in my code. Do not get me wrong, I don't want to reinvent the wheel, it is just for learning purpose.
I want to use the power of User Controls in ASP.Net.
What I want to achieve is generating Entity class for every table in our database.

First, I create a asp.net user control for my entity class template called EntityTemplate.ascx

and Create the required properties in the code behind:
EntityTemplate.ascx.cs
----------------------------------
public string MyClassName {get; set;}
public DataColumnCollection MyColumns {get; set;}
public string MyNamespace { get; set;}

EntityTemplate.ascx
------------------------------------
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="EntityTemplate.ascx.cs" Inherits="Templates_EntityTemplate" %>
using System;
using System.Collections.Generic;
using Common.Core;

namespace <%=MyNamespace %>.BOL.Entities
{
public class <%= MyClassName %>
{
#region Members
<% for (int i = 0; i < MyColumns.Count; i++)
{ %>
public <%= MyColumns[i].DataType.Name%> <%= MyColumns[i].ColumnName%> {get;set;}

<%} %>
#endregion Members
}
}

----------------------------------------------------------------
Second, we create a asp.net web from to grab the list of all tables from our Database and for every table we grab the table schema to get the list of columns for that table. then for each table, we dynamically load that template user control and we set the properties, then we Use RenderControl method to get the output of that rendering user control and save it on the hard disk.

DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SqlCilent");
DbConnection cn= factory.CreateConnection();

cn.ConnectionString = "Your Connection String";
DbDataAdapter da = factory.CreateDataAdapter();
DbCommand cmd = factory.CreateCommand();
cmd.Connection = cn;
da.SelectCommand = cmd;
cmd.CommandText = "SELECT name FROM sysobjects where type = 'U'";
cmd.CommandType = CommandType.Text;
DataTable dtTables = new DataTable();
cn.Open();
da.Fill(dtTables);

System.Text.StringBuilder output = new System.Text.StringBuilder();
System.IO.StringWriter sw = new System.IO.StringWriter(output);
HtmlTextWriter htw = new HtmlTextWriter(sw);

for(int i = 0; i< dtTables.Rows.Count; i++)
{
cmd.CommandText = "SELECT * FROM " + dtTables.Rows[i]["name"];
DataTable dt = new DataTable();
da.FillSchema(dt, SchemaType.Source);
Control ctrl = Page.LoadControl("Templates/EntityTemplate.ascx");
EntityTemplate EnCtrl = (EntityTemplate) ctrl;
EnCtrl.MyTableName = dtTables.Rows[i]["name"];
EnCtrl.MyClassName = dtTables.Rows[i]["name"];
EnCtrl.MyNamespace = "";
EnCtrl.MyColumns = dt.Columns;

c.RenderControl(htw);
System.IO.File.WriteAllText("BOL\\Entities\\" + dtTables.Rows[i]["name"] + ".cs", output.ToString());
output.Remove(0, output.Length);
}
cn.Close();
sw.Close();
htw.Close();



hope you enjoy, Cheers!

Hi Mate

This is my first post, I m a passionate .Net web developer currently living in Australia and i will blog about everything that catches my eyes and is interesting to me.
cheers mate!!!

گر تو سبزی، سبزم.. گر تو شادی ،شادم..من از شیرینی تو فرهادم وطنم..ایرانم..عید آن روزمبارک بادم که تو آبادی و من آزادم