Sunday, February 22, 2009

Adding Text To Image Programmatically With C#

In this article I’ll continue talk about Adding Text To Image using an Extension Method in my previous article.

I’ll provide here a more useful and complete Class to Add Text To Image Programmatically with C#.

WaterMarkImage

This class is able to :

  • Add Text to Image
  • Render it through a Stream (like HttpContext.Current.Response.OutputStream)
  • Render it to Image File
public class WaterMarkImage
{
#region Private Properties

private Bitmap OriginalImage { get; set; }

#endregion

#region Public Properties

public Color TextColor { get; set; }
public Brush BrushStyle { get; set; }
public Font TextFont { get; set; }
public String Text { get; set; }
public PointF Position { get; set; }

#endregion

#region Constructors

public WaterMarkImage(String filename)
: this(new Bitmap(filename))
{
}
public WaterMarkImage(Bitmap bmp)
{
OriginalImage = bmp;
TextColor = Color.White;
BrushStyle = new SolidBrush(TextColor);
TextFont = new Font("Arial", 18, FontStyle.Bold);
}

#endregion

#region Public Methods

public Bitmap Process()
{
Bitmap tmp = new Bitmap(OriginalImage);
using (Graphics graphic = Graphics.FromImage(tmp))
{
if (Position == null)
{
Position = new PointF(10, 30);
}
graphic.DrawString(Text, TextFont, BrushStyle, Position);
}
return tmp;
}
public void WriteTo(Stream stream)
{
Bitmap bmp = Process();
if (bmp == null) return;
bmp.Save(stream, ImageFormat.Jpeg);
}
public void WriteTo(String filename)
{
Bitmap bmp = Process();
if (bmp == null) return;
bmp.Save(filename, ImageFormat.Jpeg);
}

#endregion
}

Simple Snippet MD5 and SHA1 Hash Implementation With C#

Here is a pretty simple snippet MD5 and SHA1 Hash Service Implementation.
MD5
public static String GetMD5Hash(String input)
{
Encoder enc = Encoding.Unicode.GetEncoder();
byte[] unicodeText = new byte[input.Length * 2];
enc.GetBytes(input.ToCharArray(), 0, input.Length, unicodeText, 0, true);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(unicodeText);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("X2"));
}
return sb.ToString();
}[TestMethod]
public void Hash_MD5()
{
String Text = "Hello World!";

String Hashed = HashServices.GetMD5Hash(Text);

Console.WriteLine(Hashed);
}

SHA1
public static String GetSHA1Hash(String input)
{
Encoder enc = Encoding.Unicode.GetEncoder();
byte[] unicodeText = new byte[input.Length * 2];
enc.GetBytes(input.ToCharArray(), 0, input.Length, unicodeText, 0, true);
SHA1 sha1 = new SHA1CryptoServiceProvider();
byte[] result = sha1.ComputeHash(unicodeText);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("X2"));
}
return sb.ToString();
}[TestMethod]
public void Hash_SHA1()
{
String Text = "Hello World!";

String Hashed = HashServices.GetSHA1Hash(Text);

Console.WriteLine(Hashed);
}

How-To Get Environment Variables And Resolve System Paths

Tonight a useful trick in order to get Environment Variables and Resolve System Paths like :

  • %windir%
  • %Programfiles%
  • ..
MSDN :

Environment Class

Provides information about, and means to manipulate, the current environment and platform. This class cannot be inherited.

Namespace: System
Assembly: mscorlib (in mscorlib.dll)

Display All Current Environment Variables

IDictionary dic = Environment.GetEnvironmentVariables();
foreach (String variable in dic.Values)
{
Console.WriteLine(variable);
}
String DirPath = "%ProgramFiles%";
String Expanded = Environment.ExpandEnvironmentVariables(DirPath);
Console.WriteLine(Expanded);

DirPath = "%windir%";
Expanded = Environment.ExpandEnvironmentVariables(DirPath);
Console.WriteLine(Expanded);

Source : http://blog.sb2.fr/post/2008/12/23/How-To-Get-Environment-Variables-And-Resolve-System-Paths.aspx

How-To Create Dynamic Image From Text

In this article I’ll provide a simple class in order to Create Dynamic Image From Text, which should be pretty useful for email obfuscation for example.

Default.aspx (2)

The TextImage Class


public class TextImage
{
#region Public Properties

public Color TextColor { get; set; }
public Color BackColor { get; set; }
public Font TextFont { get; set; }
public String Text { get; set; }

#endregion

#region Private Properties

private Brush TextBrushStyle { get; set; }
private Brush BackBrushStyle { get; set; }

#endregion

#region Constructors

public TextImage(String text)
{
Text = text;
TextColor = Color.Black;
BackColor = Color.White;
TextFont = new Font("Arial", 18, FontStyle.Bold);
}
public TextImage(String text, Color textColor, Color backColor, Font textFont)
{
Text = text;
TextColor = textColor;
TextFont = textFont;
BackColor = backColor;
}

#endregion


#region Public Methods

public Bitmap Process()
{
TextBrushStyle = new SolidBrush(TextColor);
BackBrushStyle = new SolidBrush(BackColor);

float f = TextFont.Size * 72 / 96;
Bitmap tmp = new Bitmap(Text.Length * (int)f, TextFont.Height);
using (Graphics graphic = Graphics.FromImage(tmp))
{
graphic.FillRectangle(BackBrushStyle, 0, 0, tmp.Width, tmp.Height);
graphic.DrawString(Text, TextFont, TextBrushStyle, new PointF(0, 0));
}
return tmp;
}
public void WriteTo(Stream stream)
{
Bitmap bmp = Process();
if (bmp == null) return;
bmp.Save(stream, ImageFormat.Jpeg);
}
public void WriteTo(String filename)
{
Bitmap bmp = Process();
if (bmp == null) return;
bmp.Save(filename, ImageFormat.Jpeg);
}
#endregion
}

protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "image/jpeg";
TextImage img = new TextImage("Hello How Are You ??");
img.BackColor = Color.White;
img.TextColor = Color.Red;
img.WriteTo(Response.OutputStream);
}

Source : http://blog.sb2.fr/post/2008/12/23/How-To-Create-Dynamic-Image-From-Text.aspx

Useful Image WaterMark Extension Method

Today i'll give you a useful Extension Method in order to Add some Text to Image that can be used in HttpHandler to display copyrighted images from Database for a Photo Store for example.

WaterMarkImageHandler.ashx

Here is the Extension Code

public static Bitmap WaterMarkImage(this Bitmap bmp, String Text)
{
Image img = new Bitmap(bmp, new Size(bmp.Width, bmp.Height));
Bitmap tmp = new Bitmap(img);
using (Graphics graphic = Graphics.FromImage(tmp))
{
SolidBrush brush = new SolidBrush(Color.FromArgb(120, 255, 255, 255));
Font font = new Font("Arial", 18, FontStyle.Bold);
graphic.DrawString(Text, font, brush, new PointF(10, 30));
}
return tmp;
}
Here is a Sample of Usage
public class WaterMarkImageHandler : 
IHttpHandler
{

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/jpeg";
Image img = Bitmap.FromFile(context.Server.MapPath("~/03SC008.JPG"));
Bitmap bmp = new Bitmap(img);
bmp = bmp.WaterMarkImage("SB2 DEVELOPPERS BLOG TEST");
bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg);
}

public bool IsReusable
{
get
{
return true;
}
}
}

Download Solution - WaterMarkImageHandler.zip

Source : http://blog.sb2.fr/post/2008/11/29/Useful-Image-WaterMark-Extension-Method.aspx

Cookies Extensions Methods

Tonight a simple way to manage Cookies on an ASP.NET Application with Strongly Typed Objects.

These Extensions might be improved but it's a beginning.

Here is the code

public static class CookieExtensions
{
public static void AddToCokie(this HttpCookie cok, String name, T val)
where T : struct
{
if (cok == null)
return;
if (!String.IsNullOrEmpty(cok.Values[name]))
cok.Values.Remove(name);
cok.Values.Add(name, val.ToString());
HttpContext.Current.Response.Cookies.Add(cok);
}
public static T GetCookieValue(this HttpCookie cok, String name)
where T : struct
{
if (cok == null)
return default(T);
if (String.IsNullOrEmpty(cok[name]))
return default(T);

return cok[name].ConvertTo();
}
public static T ConvertTo(this String input) where T : struct
{
T ret = default(T);

if (!string.IsNullOrEmpty(input))
{
ret = (T)Convert.ChangeType(input, typeof(T));
}

return ret;
}
}

And here is a sample of usage

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Int32 orderId = Request.Cookies["MyCookie"].GetCookieValue("OrderId");
Response.Write(orderId.ToString());
}
}

protected void Button1_Click(object sender, EventArgs e)
{
Request.Cookies["MyCookie"].AddToCokie("OrderId", Int32.Parse(this.TextBox1.Text));
}
}
Source : http://blog.sb2.fr/post/2008/11/29/ASPNET-Cookies-Extensions-Methods.aspx

ASP.NET Cookies Extensions Methods

Tonight a simple way to manage Cookies on an ASP.NET Application with Strongly Typed Objects.

These Extensions might be improved but it's a beginning.

Here is the code

public static class CookieExtensions
{
public static void AddToCokie(this HttpCookie cok, String name, T val)
where T : struct
{
if (cok == null)
return;
if (!String.IsNullOrEmpty(cok.Values[name]))
cok.Values.Remove(name);
cok.Values.Add(name, val.ToString());
HttpContext.Current.Response.Cookies.Add(cok);
}
public static T GetCookieValue(this HttpCookie cok, String name)
where T : struct
{
if (cok == null)
return default(T);
if (String.IsNullOrEmpty(cok[name]))
return default(T);

return cok[name].ConvertTo();
}
public static T ConvertTo(this String input) where T : struct
{
T ret = default(T);

if (!string.IsNullOrEmpty(input))
{
ret = (T)Convert.ChangeType(input, typeof(T));
}

return ret;
}
}

And here is a sample of usage

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Int32 orderId = Request.Cookies["MyCookie"].GetCookieValue("OrderId");
Response.Write(orderId.ToString());
}
}

protected void Button1_Click(object sender, EventArgs e)
{
Request.Cookies["MyCookie"].AddToCokie("OrderId", Int32.Parse(this.TextBox1.Text));
}
}
Source : http://blog.sb2.fr/post/2008/11/29/ASPNET-Cookies-Extensions-Methods.aspx

HowTo Get Current Online Users Count and Infos with ASP.NET

Today I'll talking about getting current online users count and informations about them using ASP.NET and HttpModule.

Here is our OnlineUserInfo class
public class OnlineUserInfo
{
public String UserAgent { get; set; }
public String SessionId { get; set; }
public String IPAddress { get; set; }
public String UrlReferrer { get; set; }
public DateTime SessionStarted { get; set; }
public IPrincipal CurrentUser { get; set; }

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("UserAgent = {0} | ", UserAgent);
sb.AppendFormat("SessionId = {0} | ", SessionId);
sb.AppendFormat("IPAddress = {0} | ", IPAddress);
sb.AppendFormat("UrlReferrer = {0} | ", UrlReferrer);
sb.AppendFormat("SessionStarted = {0}", SessionStarted);
return sb.ToString();
}
}


Here is our OnlineUserHttpModule

public class OnlineUsersModule : IHttpModule
{
private static Int32 _sessionTimeOut = 20; // Set Default to 20 Minutes
private static List _onlineUsers = null;

public static List OnlineUsers
{
get
{
CleanExpiredSessions();
return _onlineUsers;
}
}

private static void CleanExpiredSessions()
{
_onlineUsers.RemoveAll(delegate(OnlineUserInfo user)
{
return user.SessionStarted.AddMinutes(_sessionTimeOut) < _onlineusers =" new">();

// Get the Current Session State Module
SessionStateModule module = context.Modules["Session"] as SessionStateModule;

module.Start += new EventHandler(Session_Start);
}

private void Session_Start(object sender, EventArgs e)
{
HttpRequest Request = HttpContext.Current.Request;
HttpApplicationState Application = HttpContext.Current.Application;
HttpSessionState Session = HttpContext.Current.Session;

// Get Session TimeOut
_sessionTimeOut = HttpContext.Current.Session.Timeout;

Application.Lock();

OnlineUserInfo user = new OnlineUserInfo();

user.SessionId = Session.SessionID;
user.SessionStarted = DateTime.Now;
user.UserAgent = !String.IsNullOrEmpty(Request.UserAgent)
? Request.UserAgent : String.Empty;
user.IPAddress = !String.IsNullOrEmpty(Request.UserHostAddress)
? Request.UserHostAddress : String.Empty;
if (Request.UrlReferrer != null)
{
user.UrlReferrer = !String.IsNullOrEmpty(Request.UrlReferrer.OriginalString)
? Request.UrlReferrer.OriginalString : String.Empty;
}
else
{
user.UrlReferrer = String.Empty;
}
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
user.CurrentUser = HttpContext.Current.User;
}

// Add the New User to Collection
_onlineUsers.Add(user);
Application.UnLock();
}

public void Dispose()
{
}

#endregion
}


Here is a sample of Getting Informations using this HttpModule.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(OnlineUsersModule.OnlineUsers.Count);

foreach (OnlineUserInfo user in OnlineUsersModule.OnlineUsers)
{
Response.Write(user.ToString());
}
}
}


Download Solution - OnlineUserInfos.zip

More

Clearing Extra White Lines from Pages HttpModule

Here is a pretty useful HttpModule in order to clear Extra White lines from ASP.NET Pages using an Response Filter.

Here is the HttpModule code
public class ClearWhiteLinesModule : IHttpModule
{
#region IHttpModule Members

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

public void Dispose()
{
}

#endregion

private void BeginRequest(object sender, EventArgs e)
{
HttpApplication Application = sender as HttpApplication;
String OriginalString = Application.Request.Url.OriginalString;
if (OriginalString.ToUpperInvariant().Contains(".ASPX"))
{
Application.Response.Filter = new ClearWhiteLinesFilter(Application.Response.Filter);
}
}

private class ClearWhiteLinesFilter : Stream
{
#region Private Fields

private Stream _originalFilter;

#endregion

#region Constructors

public ClearWhiteLinesFilter(Stream originalFilter)
{
_originalFilter = originalFilter;
}

#endregion

#region Public Overrides Properites

public override bool CanRead { get { return true; } }
public override bool CanSeek { get { return true; } }
public override bool CanWrite { get { return true; } }
public override long Length { get { return 0; } }
public override long Position { get; set; }

#endregion

#region Public Overrides Methods

public override void Flush()
{
_originalFilter.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return _originalFilter.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return _originalFilter.Seek(offset, origin);
}
public override void SetLength(long value)
{
_originalFilter.SetLength(value);
}
public override void Close()
{
_originalFilter.Close();
}
public override void Write(byte[] buffer, int offset, int count)
{
Byte[] data = new Byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
String html = Encoding.Default.GetString(buffer);

// Remove Extra White Lines
html = html.Replace("\r\n\r\n", String.Empty);

Byte[] outdata = Encoding.Default.GetBytes(html);
_originalFilter.Write(outdata, 0, outdata.GetLength(0));
}

#endregion
}
}


ClearWhiteLinesModule.cs

More

Clearing Extra White Lines from Pages HttpModule

Here is a pretty useful HttpModule in order to clear Extra White lines from ASP.NET Pages using an Response Filter.

Here is the HttpModule code
public class ClearWhiteLinesModule : IHttpModule
{
#region IHttpModule Members

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

public void Dispose()
{
}

#endregion

private void BeginRequest(object sender, EventArgs e)
{
HttpApplication Application = sender as HttpApplication;
String OriginalString = Application.Request.Url.OriginalString;
if (OriginalString.ToUpperInvariant().Contains(".ASPX"))
{
Application.Response.Filter = new ClearWhiteLinesFilter(Application.Response.Filter);
}
}

private class ClearWhiteLinesFilter : Stream
{
#region Private Fields

private Stream _originalFilter;

#endregion

#region Constructors

public ClearWhiteLinesFilter(Stream originalFilter)
{
_originalFilter = originalFilter;
}

#endregion

#region Public Overrides Properites

public override bool CanRead { get { return true; } }
public override bool CanSeek { get { return true; } }
public override bool CanWrite { get { return true; } }
public override long Length { get { return 0; } }
public override long Position { get; set; }

#endregion

#region Public Overrides Methods

public override void Flush()
{
_originalFilter.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return _originalFilter.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return _originalFilter.Seek(offset, origin);
}
public override void SetLength(long value)
{
_originalFilter.SetLength(value);
}
public override void Close()
{
_originalFilter.Close();
}
public override void Write(byte[] buffer, int offset, int count)
{
Byte[] data = new Byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
String html = Encoding.Default.GetString(buffer);

// Remove Extra White Lines
html = html.Replace("\r\n\r\n", String.Empty);

Byte[] outdata = Encoding.Default.GetBytes(html);
_originalFilter.Write(outdata, 0, outdata.GetLength(0));
}

#endregion
}
}


ClearWhiteLinesModule.cs

More

HowTo Redirect WebResource.axd Requests To Another Server

Today an other trick in order to Redirect WebResource.axd Requests to Another Web Application Server. In collaboration with my friend Sebastien. V we made this HttpModule.

Here is the code
public class WebResourceRedirectorModule : IHttpModule
{
#region IHttpModule Members

public void Dispose()
{
}

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

#endregion

private void BeginRequest(object sender, EventArgs e)
{
HttpRequest Request = HttpContext.Current.Request;
HttpResponse Response = HttpContext.Current.Response;
String Url = Request.Url.OriginalString;
String RemoteServer = "http://localhost:2847";

if (Url.Contains("WebResource.axd"))
{
Uri uri = new Uri(Url);
String RemoteUrl = RemoteServer + uri.PathAndQuery;
HttpWebRequest req = WebRequest.Create(RemoteUrl) as HttpWebRequest;
using (StreamReader sr = new StreamReader(req.GetResponse().GetResponseStream()))
{
String data = sr.ReadToEnd();
Response.Write(data);
Response.End();
}
}
}
}


Download Solutionhttp://www.blogger.com/img/blank.gif - WebResourceRedirector.zip

more

FeedBurner Syndication Widget for BlogEngine.NET

Here is a simple FeedBurner Syndication Widget for BlogEngine.NET

Here is the "Very" Simple Code :)

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;
using System.Collections.Specialized;

public partial class widgets_Syndication_widget : WidgetBase
{

public override string Name
{
get { return "Syndication"; }
}

public override bool IsEditable
{
get { return true; }
}

public override void LoadWidget()
{
StringDictionary settings = GetSettings();
String contents = String.Empty;
if (settings.ContainsKey("Contents"))
{
contents = settings["Contents"];
}
this.ltContents.Text = contents;
}
}

To Install it download and extract the file at the end of this post and copy the Syndication directory to ~/widgets of your BlogEngine.NET web site.

The Add it to your SideBar and Copy/Paste your FeedBurner Button Link as the Following Sample :

To Install it download and extract the file at the end of this post and copy the Syndication directory to ~/widgets of your BlogEngine.NET web site.

The Add it to your SideBar and Copy/Paste your FeedBurner Button Link as the Following Sample :

<br/>
<p style="text-align: center">
<a href="http://feeds.feedburner.com/sb2/JSrW">
<img style="border-style: initial; border-color: initial; border-width: 0px"
src="http://feeds.feedburner.com/[YOURFEED]?bg=FF66300&fg=444444&anim=1" alt="" width="88" height="26" />
a>
p>
Syndication.rar

more

Blocking not Robots.txt Compliant Crawlers

Today an article talking about blocking Crawlers which are not Robots.txt Compliant. Number of web sites grows exponentially day by day and crawlers too on the Internet ! But there is a lot of Web Crawlers that don't follow Robots.txt Disallow Rules or totally ignore it ...

Download Solution - RobotModule.zip

more

GridView Paged Edition WebControl for ASP.NET

In this article i'll talk about GridView in order to display Data in an ASP.NET Page. While working with a lot of Data, Data Paging must be very useful.

So here is the Standard ASP.NET GridView but in it's Paged Edition.

Download Solution - PagedDataWithGridView.zip

more

Simple TagCloud WebControl For ASP.NET

Simple TagCloud WebControl For ASP.NET

Download Solution - TagCloudNET.zip

RequireSSL Attribute For ASP.NET

Here is a quick Custom Attribute in order to Define if a Page must be in HTTP SSL Mode and switch it to SSL if not.

[AttributeUsage(AttributeTargets.Class)]
public class RequireSSLAttribute : Attribute
{
public static void Validate(IHttpHandler handler)
{
Type type = handler.GetType();
Object[] objs = type.GetCustomAttributes(typeof(RequireSSLAttribute), true);
if (objs != null && objs.Count() > 0)
{
SwitchToSsl();
}
}
private static void SwitchToSsl()
{
#if DEBUG
return;
#endif
String baseUrl = HttpContext.Current.Request.Url.OriginalString;
Uri uri = new Uri(baseUrl);
String url = baseUrl.Replace(uri.Scheme, Uri.UriSchemeHttps);
HttpContext.Current.Response.Redirect(url, true);
}
}

A Sample Page Implementation

In order to make it working, you just need to call RequireSSLAttribute Validate Method. On Page Constructor might be fine :)

[RequireSSL]
public partial class _Default : Page
{
public _Default()
{
RequireSSLAttribute.Validate(this);
}

protected void Page_Load(object sender, EventArgs e)
{
}
}
Source : http://blog.sb2.fr/post/2008/12/20/RequireSSL-Attribute-For-ASPNET.aspx

RequireSSL Attribute For ASP.NET

Here is a quick Custom Attribute in order to Define if a Page must be in HTTP SSL Mode and switch it to SSL if not.

[AttributeUsage(AttributeTargets.Class)]
public class RequireSSLAttribute : Attribute
{
public static void Validate(IHttpHandler handler)
{
Type type = handler.GetType();
Object[] objs = type.GetCustomAttributes(typeof(RequireSSLAttribute), true);
if (objs != null && objs.Count() > 0)
{
SwitchToSsl();
}
}
private static void SwitchToSsl()
{
#if DEBUG
return;
#endif
String baseUrl = HttpContext.Current.Request.Url.OriginalString;
Uri uri = new Uri(baseUrl);
String url = baseUrl.Replace(uri.Scheme, Uri.UriSchemeHttps);
HttpContext.Current.Response.Redirect(url, true);
}
}

A Sample Page Implementation

In order to make it working, you just need to call RequireSSLAttribute Validate Method. On Page Constructor might be fine :)

[RequireSSL]
public partial class _Default : Page
{
public _Default()
{
RequireSSLAttribute.Validate(this);
}

protected void Page_Load(object sender, EventArgs e)
{
}
}
Source : http://blog.sb2.fr/post/2008/12/20/RequireSSL-Attribute-For-ASPNET.aspx

Tricky Simple File Download Proxy Handler

Today I wanna play a bit with Streams and specially with Response.OutputStream. So I decided to make a Simple File Download Proxy Handler in order to Download Files through an HttpHandler which download Files from Remote Site.

It’s Tricky, and may not be very useful :)

Here is the Code

public class FileProxyHandlerBase : HttpHandlerBase
{
#region Private Properties

private String RemoteUrl { get; set; }
private Uri RemoteUri { get; set; }
private String FileName { get; set; }

#endregion

protected override void Process()
{
if (!String.IsNullOrEmpty(Request.QueryString["url"]))
{
RemoteUrl = Request.QueryString["url"];
}

Uri uri;
if (!Uri.TryCreate(RemoteUrl, UriKind.Absolute, out uri))
{
Response.Write("Unable to Process File");
Response.End();
return;
}
RemoteUri = uri;

if (RemoteUri.Scheme == Uri.UriSchemeFtp)
{
Response.Write("Unable to Process File");
Response.End();
return;
}

int index = RemoteUrl.LastIndexOf("/") + 1;
FileName = RemoteUrl.Substring(index, RemoteUrl.Length - index);

HttpWebRequest _webRequest = WebRequest.Create(RemoteUri) as HttpWebRequest;
Stream ResponseStream = _webRequest.GetResponse().GetResponseStream();

Response.ClearContent();
Response.ContentType = "text/plain";
Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName);

using (BinaryWriter bw = new BinaryWriter(Response.OutputStream))
{
byte[] buffer = new byte[1];
while (ResponseStream.Read(buffer, 0, 1) > 0)
{
bw.Write(buffer);
}
}
Response.End();
}
}

You should use it like that : http://mysite.com/MyHandler.ashx?url=http://www.myRemoteSite.com/MyFile.zip


Source : http://blog.sb2.fr/post/2008/12/21/Tricky-Simple-File-Download-Proxy-Handler.aspx

Handle External Links With Custom Http Handler

In this article I’ll talk about External Links Handling.

We often need to manage more external links particularly in the mail or newsletter. These links must remain Standing, even when changing architecture of the website.

That is why it is important to adopt an external links policy of in a unique manner.

For that we'll use a Http Handler which will allow us to intercept the requested URL and so redirect the user to the proper destination.

more

BlogEngine.NET Backup Manager

BlogEngine.NET Backup Manager

Google Analytics WebControl for ASP.NET

Tonight I’ll provide a Quick Useful WebControl in order to add Google Analytics Feature to your ASP.NET WebSite.

This WebControl allow you to choose between the 2 different Analytics Mode :

  • Analytics GA
  • Analytics Urchin

Here is the Code :

[DefaultProperty("Text")]
[ToolboxData("<{0}:GoogleAnalytics runat=server>")]
public class GoogleAnalytics : Control
{
#region Inner Enum

public enum AnalyticMode
{
Urchin,
GA
}

#endregion

#region Public Properties

public String UACode
{
get { return ViewState["UACode"] as String; }
set { ViewState["UACode"] = value; }
}
public AnalyticMode GMode
{
get { return (AnalyticMode)ViewState["Mode"]; }
set { ViewState["Mode"] = value; }
}

#endregion

#region Protected Overrides Methods

protected override void Render(HtmlTextWriter output)
{
switch (GMode)
{
case AnalyticMode.GA:
output.Write(GetGAString());
break;
case AnalyticMode.Urchin:
output.Write(GetUrchinString());
break;
default:
output.Write(GetGAString());
break;
}
}

#endregion

#region Private Methods

private String GetUrchinString()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("");
sb.AppendLine("");
return sb.ToString();
}

private String GetGAString()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("");
sb.AppendLine("");
return sb.ToString();
}

#endregion
}

Sample Usage :


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Sb2.Web.Tests._Default" %>

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>title>
head>
<body>
<form id="form1" runat="server">
<div>
<Sb2:GoogleAnalytics ID="analytics" runat="server" GMode="GA" UACode="XXXXX" />
div>
form>
body>
html>


Source : http://blog.sb2.fr/post/2008/12/21/Google-Analytics-WebControl-for-ASPNET.aspx

Starting ASP.NET Development Web Server(Cassini) manually

For development, Visual Studio 2005 now comes with a built-in development-only Web server. This lightweight Web server can only respond to local requests and is therefore not a security threat. The server does, however support full debugging features and can be used as a development tool for new Web applications. When you are ready to test out scalability and performance or deploy for production, simply move the application to IIS.

If the asp.net application is not deployed in IIS and you try to run the asp.net application from Visual Studio 2005, the local development web server will be started automatically. If local web development server is automatically, it will pick up the port number randomly and run the development server in that port.

However, in some situations you might require to start this web server manually. For example, you might want to run this local web server in certain port or if you want to test the web page without opening VS 2005.

In those cases, you can use WebDev.WebServer.Exe located in

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215 (this path might vary depending upon the .net framework installation) to start this web server manually. This is the executable for local development web server; even VS 2005 internally uses this executable to start the local web server.

This command line executable accepts three parameters,

1. path : Physical path of the application which you want to run.

2. port : port in which you want to start this web server. Default is 80.

3. vpath: Specify application root using this option. Default is "/"

For example, to start a web application located at c:\temp\testing and in the port 8001.

WebDev.WebServer.EXE /path:D:\temp\Testing /port:8001 /vpath:/testing

After you run this utility, you can see ASP.NET development Web server in the system tray. You can access your web application from the browser using http://localhost:8001/testing/

Get Development Server VPath And Port From Project File

private static void GetDevelopmentServerVPathAndPortFromProjectFile(
string csprojFileName,
out string developmentServerVPath,
out int developmentServerPort)
{
XPathDocument doc = new XPathDocument(csprojFileName);
XPathNavigator navigator = doc.CreateNavigator();

XmlNamespaceManager manager = new XmlNamespaceManager(navigator.NameTable);
manager
.AddNamespace("msbuild",
"http://schemas.microsoft.com/developer/msbuild/2003");

const string xpath = "/msbuild:Project/msbuild:ProjectExtensions/"
+ "msbuild:VisualStudio/msbuild:FlavorProperties/"
+ "msbuild:WebProjectProperties";

XPathNavigator webProjectPropertiesNode =
navigator
.SelectSingleNode(xpath, manager);
XPathNavigator developmentServerPortNode =
webProjectPropertiesNode
.SelectSingleNode("msbuild:DevelopmentServerPort",
manager
);
XPathNavigator developmentServerVPathNode =
webProjectPropertiesNode
.SelectSingleNode("msbuild:DevelopmentServerVPath",
manager
);

developmentServerPort
= developmentServerPortNode.ValueAsInt;
developmentServerVPath
= developmentServerVPathNode.Value;
}

private static string GetCommonProgramFilesPath()
{
string commonProgramFiles =
Environment.GetEnvironmentVariable("CommonProgramFiles(x86)");
if (string.IsNullOrEmpty(commonProgramFiles))
{
commonProgramFiles
=
Environment.GetEnvironmentVariable("CommonProgramFiles");
}
if (string.IsNullOrEmpty(commonProgramFiles))
{
commonProgramFiles
=
Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles);
}
return commonProgramFiles;
}

private static Process PrepareCassiniProcess(int developmentServerPort,
string projectPhysicalPath,
string developmentServerVPath)
{
string commonProgramFiles = GetCommonProgramFilesPath();
string cassiniPath = Path.Combine(commonProgramFiles,
@
"Microsoft Shared\DevServer\9.0\WebDev.WebServer.exe");
string cassiniArgs = string.Format(
CultureInfo.InvariantCulture,
"/port:{0} /nodirlist /path:\"{1}\" /vpath:\"{2}\"",
developmentServerPort
, projectPhysicalPath, developmentServerVPath);

Process cassiniProcess = new Process();
cassiniProcess
.StartInfo.FileName = cassiniPath;
cassiniProcess
.StartInfo.Arguments = cassiniArgs;
return cassiniProcess;
}

//
To use it, you need to discover the path to the CSPROJ file of the web
// project under test. I'll leave that as an exercise for the reader

Source : http://stackoverflow.com/questions/328566/starting-asp-net-development-web-server-cassini-as-part-of-unit-test-setup

HowTo Use Microsoft .NET ASP.NET Development Server as Standalone Web Server

Hi,

A little post in order to explain howto use ASP.NET Development Server as Standalone Web Server.

First of all where is located the ASP.NET Development Server on your computer ?

On Windows XP :

C:\WINDOWS\Microsoft.NET\Framework\[VERSION]\WebDev.WebServer.exe

On Windows Vista :

C:\Program Files\Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.exe

You can now use it to start Standalone Web Application for local Presentation for example or for your ASP.NET Product Demo.

Here is the different's parameters in order to start your standalone Web Server

WebDev.WebServer /port: /path: /vpath:

Port Number : Between 1 and 65535 (Default is 80)
Physical Path : A valid directory on your hard disk where is located your Web Site
Virtual Path : A virtual path for your Web Application (Default is '/')

Here is a example of starting standalone Web Site by command-line :

WebDev.WebServer /port:8080 /path:"D:\WebSite" /vpath:"/MyApplication"

Cassini Wrapper (aka Web Dev WebServer)

Project Description
A '3-click away' ASP.Net webserver cassini (or 'Web Dev WebServer' for its new name)

1/ Right-Click on any folder in any standard screen (Explorer, DialogBox ...)
2/ Choose to start the web server from this folder
3/ Confirm the TCP/IP port to listen to.


Developed for the .NET Framework version 2.
Localized in English (Default) and French.

Integrated in Windows Shell (Right-click option on folders) via the installer.


link : http://www.codeplex.com/CassiniWrapper

code for the command line exe

here's the code for the command line exe:

using System;
using System.Windows.Forms;
using System.Diagnostics;

namespace OpenCassini
{
class Program
{
///
/// The main entry point for the application.
///

[STAThread]
static void Main(string[] args)
{
string path;

string command =
@"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.EXE";
string commandArgs = string.Empty;

Random r = new Random();

string port = r.Next(1024, 9000).ToString();

if(args.Length == 1){
//grab the original path
path = args[0];

commandArgs += " /path:\"" + path + "\"";
commandArgs += " /port:";
commandArgs += port;
commandArgs += " /vpath: \"/";
commandArgs += path.Substring(path.LastIndexOf('\\') + 1);
commandArgs += "\"";

System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();

info.Arguments = commandArgs;
info.CreateNoWindow = true;
info.FileName = command;
info.UseShellExecute = false;
info.WorkingDirectory = command.Substring(0, command.LastIndexOf('\\'));


Process.Start(info);

using(Control c = new Control()){
Help.ShowHelp(c, "http://localhost:" + port + "/");
}
}
}
}
}


Using Help.ShowHelp has the side effect of opening the default browser instead of just IE.

"ASP.NET 2.0 Web Server Here" Shell Extension

"ASP.NET 2.0 Web Server Here" Shell Extension

http://weblogs.asp.net/rmclaws/archive/2005/10/25/428422.aspx

I've been doing some web development work again lately, and I haven't wanted to screw with setting up IIS on my virtual machine. The .NET Framework 2.0 comes with a built-in webserver, based on the old Cassini web server. So I wanted to be able to easily set up any directory to have its contents served up on an as-needed basis. The result is an addition to the Windows Explorer right-click menu, as shown below:

This is enabled by a simple modification to the registry. You can take the text below and dump it into a file named "WebServer.reg", and then run it, to immediately get the item in the context menu.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\VS2005 WebServer]
@="ASP.NET 2.0 Web Server Here"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\VS2005 WebServer\command]
@="C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727\\Webdev.WebServer.exe /port:8080 /path:\"%1\""

There are a couple caveats to this tool, however:

  1. The web server does not randomly assign a port number, so it has to be hard-coded into the registry.
  2. The web server does not automatically assign a virtual directory, so it will always be "http://localhost:port"
  3. A command prompt window will be spawned, and cannot be closed without closing the web server process.

Moving foward, there are a couple of options to fix these issues:

  1. Someone who knows more about variables in the registry can help me fix issues #2 and #3
  2. I can build a wrapper executable that solves all three problems
  3. Microsoft can put in a DCR and fix it before it goes gold in a few days.

#3 is not likely, so I'd love to hear what you think. Hope this trick is useful.

VS2008 Web Server Here Shell Extension

VS2008 Web Server Here Shell Extension


UPDATE: Updated the registry settings per James Curran’s comment. Thanks James!

One of the most useful registry hacks I use on a regular basis is one Robert McLaws wrote, the “ASP.NET 2.0 Web Server Here” Shell Extension. This shell extension adds a right click menu on any folder that will start WebDev.WebServer.exe (aka Cassini) pointing to that directory.

Webserver-Here

I recently had to repave my work machine and I couldn’t find the .reg file I created that would recreate this shell extension. When I brought up Robert’s page, I noticed that the settings he has are out of date for Visual Studio 2008.

Here is the updated registry settings for VS2008 (note, edit the registry at your own risk and this only has the works on my machine seal of approval).

32 bit (x86)

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\VS2008 WebServer]
@="ASP.NET Web Server Here"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\VS2008 WebServer\command]
@="C:\\Program Files\\Common Files\\microsoft shared\\DevServer
\\9.0\\Webdev.WebServer.exe /port:8080 /path:\"%1\""

64 bit (x64)

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\VS2008 WebServer]
@="ASP.NET Web Server Here"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\VS2008 WebServer\command]
@="C:\\Program Files (x86)\\Common Files\\microsoft shared\\DevServer
\\9.0\\Webdev.WebServer.exe /port:8080 /path:\"%1\""

For convenience, here is a zip file containing the reg files. The x64 one I tested on my machine. The x86 one I did not. If you installed Visual Studio into a non-standard directory, you might have to change the path within the registry file.

WebDev.WebServer Copy to another PC


WebDev.WebServer Copy to another PC


You need 3 files

1. \WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.EXE
2. \WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.exe.manifest
3. \Windows\assembly\GAC_32\WebDev.WebHost\8.0.0.0__b03f5f7f11d50a3a\WebDev.WebHost.dll

no:3. you can’t copy with windows explorer, go to console and copy it

Using WebServer.WebDev For Unit Tests

Using WebServer.WebDev For Unit Tests

ASPX Web Server

If you cannot or do not want to use IIS as your Web server, you can still test your ASP.NET pages by using the ASPX Web Server.

About
The ASPX Web Server is a standalone web server written in C# that can be used to run your ASP.NET applications with minimal effort.

Features
  • You are developing ASP.NET Web pages while working with Windows XP Home Edition, which does not support IIS.
  • The ASP.NET Web Server only accepts authenticated requests on the local computer. This requires that the server can support NTLM or Basic authentication.
  • Hosts and runs multiple ASP.NET applications.
  • ASPX Web Server fully supports all ASP.NET features.
  • Can guarantee that the port you specify will be available when you run your ASP.NET applications.
  • Windows Shell integration, one click to run ASP.NET applications.

Running the ASPX Web Server

Run by command line :

ASPX.WebServer.exe /port: /path: /vpath:/open
Command line options
  • Port number : Between '1' and '65535' (Default is '80') or use 'auto' to use dynamic port
  • Physical Path : A valid directory on your hard disk where is located your Web Site
  • Virtual Path : A virtual path for your Web Application (Default is "/")
  • Open : auto open in web browser

Here is a example of starting standalone Web Site by command-line :

ASPX.WebServer.exe /port:auto /path:"D:\WebSite" /vpath:"/MyApplication" /open

Running the ASPX Web Server

Running the ASPX Web Server

Run by command line :

ASPX.WebServer.exe /port: /path: /vpath:/open
Command line options
  • Port number : Between '1' and '65535' (Default is '80') or use 'auto' to use dynamic port
  • Physical Path : A valid directory on your hard disk where is located your Web Site
  • Virtual Path : A virtual path for your Web Application (Default is "/")
  • Open : auto open in web browser

Here is a example of starting standalone Web Site by command-line :

ASPX.WebServer.exe /port:auto /path:"D:\WebSite" /vpath:"/MyApplication" /open

WebDev.WebServer

The ASPX Web Server is a standalone web server written in C# that can be used to run your ASP.NET applications with minimal effort.
Features
  • You are developing ASP.NET Web pages while working with Windows XP Home Edition, which does not support IIS.
  • The ASP.NET Web Server only accepts authenticated requests on the local computer. This requires that the server can support NTLM or Basic authentication.
  • Hosts and runs multiple ASP.NET applications.
  • ASPX Web Server fully supports all ASP.NET features.
  • Can guarantee that the port you specify will be available when you run your ASP.NET applications.
  • Windows Shell integration, one click to run ASP.NET applications.