Archive for the 'C#.Net' Category

ELMAH With WCF Web Services

After a long time, I again started  Asp. Net job. On this job, I faced first challenge which is to log and monitor all WCF web services un-handled exceptions. For logging, I used ELMAH (Error Logging Modules and HTTP handlers) for Logging all the applicaion exception. This is open source (https://code.google.com/p/elmah/) and can be easily integrated with any Asp.Net web applications. Lets started with simple steps that I used to integrate it with WCF. These are

  1. Download it from https://code.google.com/p/elmah/wiki/Downloads?tm=2 according to your architecture.
  2. Add ELMAH.dll to your project by clicking Add Reference (use .net 1.1 dll, you will find it inside bin folder).
  3. Add the following configuration inside your web.config or app.config, these are

 

<sectionGroup name=”elmah”>

<section name=”errorLog” requirePermission=”false” type=”Elmah.ErrorLogSectionHandler,Elmah”/>
<section name=”security” requirePermission=”false” type=”Elmah.SecuritySectionHandler, Elmah”/>

</sectionGroup>

 

Add above configuration inside <configSections>, if does not exists, create it inside configuration tag.

 

<elmah>
<errorLog type=”Elmah.SqlErrorLog, Elmah” connectionString=”your connection sring” />

</elmah>

 

Add above lines below <configSections>, I used SQL server for logging, you can use XML , SQLlite etc. You can change this setting according to your data source.

 

<httpModules>

<add name=”ErrorLog” type=”Elmah.ErrorLogModule, Elmah”/>
<add name=”ErrorFilter” type=”Elmah.ErrorFilterModule, Elmah”/>

</httpModules>

 

Add the above lines, inside <system.web> tag.

 

<serviceHostingEnvironment multipleSiteBindingsEnabled=”true” aspNetCompatibilityEnabled=”true” />

 

Add above line inside <system.serviceModel>

 

<location path=”elmah.axd”>

<system.web>

<httpHandlers>

<add verb=”POST,GET,HEAD” path=”elmah.axd” type=”Elmah.ErrorLogPageFactory, Elmah” />

</httpHandlers>

</system.web>

</location>

 

Add above lines below <system.webServer> tag. These lines will help us to view our log in the browser. elmah.axd will serve the log inside a grid when we open it in browser.

 

4. Create ErrorHandler class and paste this code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel.Dispatcher;

namespace YourNameSpace
{
public class ErrorHandler : IErrorHandler
{
#region IErrorHandler Members
public bool HandleError(Exception error)
{
return false;
}
public void ProvideFault(Exception error,
System.ServiceModel.Channels.MessageVersion version,
ref System.ServiceModel.Channels.Message fault)
{
if (error == null)
return;
if (HttpContext.Current == null) //In case we run outside of IIS
return;
Elmah.ErrorSignal.FromCurrentContext().Raise(error);
}
#endregion
}
}

 

This class will caught all exceptions and manually triger the Elmah error signal module so that it can be logged.

 

5. Add ServiceErrorBehaviorAttribute class and paste the below code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace YourNameSpace
{
public class ServiceErrorBehaviorAttribute : Attribute, IServiceBehavior
{
Type errorHandlerType;
public ServiceErrorBehaviorAttribute(Type errorHandlerType)
{
this.errorHandlerType = errorHandlerType;
}

#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription
serviceDescription,
System.ServiceModel.ServiceHostBase serviceHostBase,
System.Collections.ObjectModel.Collection<ServiceEndpoint>
endpoints,
System.ServiceModel.Channels.BindingParameterCollection
bindingParameters)
{ }

public void ApplyDispatchBehavior(ServiceDescription
serviceDescription, System.ServiceModel.ServiceHostBase
serviceHostBase)
{
IErrorHandler errorHandler;
errorHandler =
(IErrorHandler)Activator.CreateInstance(errorHandlerType);
foreach (ChannelDispatcherBase cdb in
serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher cd = cdb as ChannelDispatcher;
cd.ErrorHandlers.Add(errorHandler);
}
}
public void Validate(ServiceDescription serviceDescription,
System.ServiceModel.ServiceHostBase serviceHostBase)
{ }
#endregion
}
}

 

6. Add the below lines above your service classes

[ServiceErrorBehavior(typeof(ErrorHandler))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

7. Use sql script to create tables and stored procedure (it will be found inside db folder)

8. Now you can run and enjoy. You can test it by throwing some random exceptions. You can access the log viewer by using http://yourwebserviceaddress/elmah.axd

Thanks

 

References

[1] http://dotnetslackers.com/articles/aspnet/Getting-ELMAH-to-work-with-WCF-services.aspx

 

Disabling browser’s back functionality on logout from Asp.Net

Hi,

Today I come with a pretty cool problem or say requirement that our client demand from us. He want, when a user sign out from our site then he will redirect to home page and if he try the back button then the back page should not opened. Because that page is secure page and we have to disable the back button.

I search it and found a good solution.

When we request any page from server, browser maintains its cache in local system. When user press back button the cached page opened in front of user.

Its mean we have to disable the cache functionality for our session pages. So for this you have to insert this code into “Page_Load” event of the session page or to master page that is used for secure pages.

Response.Buffer= true;
Response.ExpiresAbsolute=DateTime.Now.AddDays(-1d);
Response.Expires =-1500;
Response.CacheControl = “no-cache”;
if(Session[“SessionId”] == null)
{
Response.Redirect (“Home.aspx”);
}
}

This code just disable the cache for current page and save this page in buffer.

And buffer is maintained in memory so when user logout the buffer will
destroy and no backup copy of that page available to view.

So its mean we successfully disable the back button.

Regards

Rana Faisal Munir


Dynamically adding / removing textboxes in ASP.NET Repeater

Hi,

Sorry for delay. This delay because of that I again start the education after 1 year of web development.  But now I again start the development and want to share something new that I did for my BOSS.

Requirements:

We have to make HR (Human Resource) components for some organization. Our client demanded that his client can entered multiple degrees. In start we only have text boxes for only one degree but when user press add another we must add other fields dynamically and maintain the contents of old degrees and change the buttons to remove for them and for new add and empty fields appeared.

Solution:

We have two solutions to solve this problem.

One is to use JavaScript [ But I hate it 🙂 ]

So I use repeater and DataSet to gain the same functionality that our client wanted.

We have a page on which we add repeater

Page Name: Default.aspx

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;

<html xmlns=”http://www.w3.org/1999/xhtml&#8221; >
<head runat=”server”>
<title>Untitled Page</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<asp:Repeater ID=”Repeater1″ runat=”server” OnItemCommand=”Repeater1_ItemCommand” OnItemDataBound=”Repeater1_ItemDataBound”>
<HeaderTemplate>
<table>
<tr>
<th>Book Title</th>
<th>Book ISBN</th>
</tr>

</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:TextBox ID=”txtBookTitle” runat=”server” Text='<%# DataBinder.Eval(Container.DataItem, “Title”) %>’></asp:TextBox>
</td>
<td>
<asp:TextBox ID=”txtISBN” runat=”server” Text='<%# DataBinder.Eval(Container.DataItem, “Isbn”) %>’></asp:TextBox>
</td>
<td>
<asp:Button ID=”btnAddAnother” runat=”server” Text='<%# DataBinder.Eval(Container.DataItem, “Button”) %>’ CommandName='<%# DataBinder.Eval(Container.DataItem, “Button”) %>’ />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</form>
</body>
</html>

In ITEMTEMPLATE of repeater we add the text boxes and a button, we also set the text for text boxes to maintain their  values. For button set the command and text because I want to change this in “Remove” when new one is added.

Now on the backend coding page we have to write this code

Page Name: Default.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
DataSet dsDummy =  null; //dummy dataset use for repeater
DataTable tbDummy = null; //dummy table for dataset
protected void Page_Load(object sender, EventArgs e)
{
// Intitalization
dsDummy = new DataSet();
tbDummy = new DataTable();
//Only first time of page load
if (!Page.IsPostBack)
{

AddColumns();

//Add dummy row to table
tbDummy.Rows.Add(“”,””,”Add”);

BindWithRepeater();
}
}

On Page load we add our required columns and set the row to empty as u see and then bind this to repeater. So in initially we add only one row so only one row of text boxes is appeared.

protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
int Total = Repeater1.Items.Count; //get total items in repeater
if (e.CommandName == “Add”)
{
Total = Total + 1; //increase 1 because of add

AddColumns();

foreach (RepeaterItem item in Repeater1.Items)
{
//getting the values of user entered fields
string title = ((TextBox)item.FindControl(“txtBookTitle”)).Text;
string isbn = ((TextBox)item.FindControl(“txtISBN”)).Text;
Button btnAdd = ((Button)item.FindControl(“btnAddAnother”));

//now change button text to remove, and save user entered values in table
tbDummy.Rows.Add(title, isbn, “Remove”);

}

//Add dummy row, because we need to increase
tbDummy.Rows.Add(“”, “”, “Add”);

BindWithRepeater();
}
else if (e.CommandName == “Remove”)
{
Total = Total – 1;
tbDummy.Columns.Add(“Title”);
tbDummy.Columns.Add(“Isbn”);
tbDummy.Columns.Add(“Button”);

foreach (RepeaterItem item in Repeater1.Items)
{
Button btnAdd = ((Button)item.FindControl(“btnAddAnother”));
if (btnAdd != e.CommandSource) //the current row on which user click will removed
{
string title = ((TextBox)item.FindControl(“txtBookTitle”)).Text;
string isbn = ((TextBox)item.FindControl(“txtISBN”)).Text;

if (btnAdd.Text == “Remove”)
{
tbDummy.Rows.Add(title, isbn, “Remove”);
}
else
{
tbDummy.Rows.Add(title, isbn, “Add”);
}
}

}

BindWithRepeater();
}
}


In ItemCommand, we have to tackle both Add and Remove functionality. So we did this by checking command. And you see when We add the row to table we add the previous entry by getting it from repeater and adding only one for new.


Similarly when we remove we have to check that the button that is clicked. So we check this by a condition compare with sender if not equal then we add it in table and just not adding that one on which user click remove. So by doing this we automatically remove the one row.

private void AddColumns()
{
//Add 3 dummy coloumn, this can be increase on our need basis
tbDummy.Columns.Add(“Title”);
tbDummy.Columns.Add(“Isbn”);
tbDummy.Columns.Add(“Button”);
}

private void BindWithRepeater()
{
//add this table to dataset
dsDummy.Tables.Add(tbDummy);

//bind this dataset to repeater
Repeater1.DataSource = dsDummy;
Repeater1.DataBind();
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{

}
}

That’s it. This is not much good programming practice But I think good to do thing quickly under work load and tight deadline.

Now one request, Just Pray for ME 🙂

Regards

Rana Faisal Munir

Create Thumbnail in C#

Hi,

This is very simple class that I used to generate thumbnail of images. You just pass it file name. It generate the thumbnail from file and store it in thumbnail folder. You can change width and height. And path of original image and thumbnail image. Better way is to store path in web.config file and access here.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;

/// <summary>
/// Summary description for Thumbnail
/// </summary>

public class Thumbnail
{
private int Width = 100;
private int Height = 100;
string ThumbFolderPath = “~/Contents/Thumb/”;
string OriginalFolderPath = “~/Contents/Images/”;

public Thumbnail()
{
//
// TODO: Add constructor logic here
//
}

public bool GenerateThumbnail(string fileName)
{
try
{
//Get The Image From File
System.Drawing.Image OriginalImage = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(OriginalFolderPath + fileName));
//Create ITs Thumbnail
System.Drawing.Image ThumbImage = OriginalImage.GetThumbnailImage(Width, Height, null, new System.IntPtr());
//Store It in Thumbnail Folder
ThumbImage.Save(HttpContext.Current.Server.MapPath(ThumbFolderPath + fileName));

return true;
}
catch
{
return false;
}
}
}

Thanks

Rana Faisal Munir

Asp.Net Developer

Relax Solutions

Free Textbox With UpdatePanel

Hi,
As we often use Free Textbox control with our web projects. But it show some limitation when we use it with updatepanel. No this limitation removed using this work around of this problem

Step1
//Add this on page load
if(!Page.IsPostBack)
{
Page.ClientScript.RegisterClien

tScriptInclude(“FTB-FreeTextBox“, VirtualPathUtility.MakeRelative(Request.Path, “~/scripts/FTB-FreeTextBox.js”));
Page.ClientScript.RegisterClien
tScriptInclude(“FTB-Utility”, VirtualPathUtility.MakeRelative(Request.Path, “~/scripts/FTB-Utility.js”));
Page.ClientScript.RegisterClien
tScriptInclude(“FTB-Toolbars”, VirtualPathUtility.MakeRelative(Request.Path, “~/scripts/FTB-ToolbarItems.js“));
Page.ClientScript.RegisterClien
tScriptInclude(“FTB-ImageGallery”, VirtualPathUtility.MakeRelative(Request.Path, “~/scripts/FTB-ImageGallery.js“));
Page.ClientScript.RegisterClien
tScriptInclude(“FTB-Pro”, VirtualPathUtility.MakeRelative(Request.Path, “~/scripts/FTB-Pro.js”));
}

and add these two funcions
Step2
[Obsolete]
public override void RegisterStartupScript(string key, string script)
{
string newScript = script.Replace(“FTB_AddEvent
(window,’load’,function () {“, “”).Replace(“});”, “”);
ScriptManager.RegisterStartupSc
ript(this, typeof(Page), key, newScript, false);
}
public new void RegisterOnSubmitStatement
(string key, string script)
{
ScriptManager.RegisterOnSubmitS
tatement(this, typeof(Page), key, script);
}

Cheers, Now textbox work very well in update panel.

ASP.NET – Block IP Addresses from Your Site

Hi,

Today I want to present a way how to Block an IP from your website. So that these blocked IP address can not open your site. I work on this on my recent project. The client demand that he can block user IP from admin panel. He can block any IP, so user will not access the site in future.

When I research on it I found two solutions

1- Using IIS

2- Using HTTP Module

1- Using IIS

This method is best for advance user. I did not work on this method. But if you are interested please read this article. http://www.west-wind.com/WebLog/posts/59731.aspx

2- Using HTTP Module

This method is very easy and I used this to accomplish the client requirements. In this method, we need two things.

i- A class in App_Code Folder

ii- Setting in Web.Config file

i- A class in App_Code Folder

Here is whole code

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/// <summary>
/// Summary description for BlockIP
/// </summary>
public class BlockIP : IHttpModule
{
public BlockIP()
{
//
// TODO: Add constructor logic here
//
}

#region IHttpModule Members

public void Dispose()
{
//clean
}

public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(Application_BeginRequest);
}

private void Application_BeginRequest(object source, EventArgs e)
{
HttpContext context = ((HttpApplication)source).Context;
string ipAddress = context.Request.UserHostAddress;
if (!IsValidIpAddress(ipAddress))
{
context.Response.StatusCode = 403; // (Forbidden)

}
}

private bool IsValidIpAddress(string ipAddress)
{
return UserIP.IsIpValid(ipAddress);
}

#endregion
}

In the Application_beginRequest we check that if ip is invalid then generate an error. So user can not see the page. We do this in beginning of request. so that user can not view the page and never get and content.

In this method IsValidIpAddress you can verify that it is valid IP address or blocked, I check this using User class. In it I check from database, where all blocked IP addresses saved. You can also write here your custom checking.

ii- Setting in Web.Config file

Now, we add this HTTP Module in web.config file so that we can use it. Under <System.Web> tag add this

<httpModules>
<add name=”YourClassName” type=”Your Class Name”/>
</httpModules>

This is complete. Now you can block any user programmatically.

Pray for Me!

Response.Redirect in Asp.net AJAX

Hi,

Today I tell you my experience about Asp.Net ajax. In previous projects, I used Ajax but feel very sad because in Ajax Response.Redirect and Server.Transfer cause problems. When I want to check that is session expired then redirect to login page. Then Ajax create problem and show popup error message. Message is

Sys.WebForms.PageRequestManagerParserErrorException:
The message received from the server could not be parsed.
Common causes for this error are when the response is modified by calls to Response.Write(),
response filters, HttpModules, or server trace is enabled.
Details: Error parsing near’
<!DOCTYPE html PUB’.”
When I search about this, I found 3 ways.
1- Using Http Module
2- Using Javascript
3- By modifying Web.Config (Very Easy)
1- Http Module
This method is useful for advance users. Because in this method we will required some expertise, in this we check the request before it goes to page. So here we will easily check that whteher session exist or not. But in my pervious article, I identify a bug. In http handler session id changed when we browse the website in mozila fire fox. Its mean we can not get our session variables.
2- Using Javascript
This is very easy method. In this method we add a javascript code on page load that we add on page load, if session is expired. This javascript code call on body load and using location.replace redirect to login page. But in this method suppose user disable the javascript then what happened. Simply our page opens in front of user and he can perform any operation.
//check session
if (!LoginController.CheckSession())
{
ScriptManager.RegisterStartupScript(UpdatePanel1, this.GetType(), “redirectMe”, “location.href=’login.aspx’;”, true);
}

3- By modifying Web.Config (Very Easy)
This is method that I really like. In this method we simply add a tag in web.config file and response.redirct and server.transfer start working. Now You can develop your website as you develop withour ajax and at the end using update panel, you can convert it in ajax enable web site.
Tag is
<httpModules>
<add name=”ScriptModule” type=”System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″/>
</httpModules>
Pray for Me
Thanks
Rana Faisal Munir