Method of Simplifying Reporting Errors/Success to Users

Since updating users to what is going on is so common, I use a simple group of extensions to simplify my life

There is most likely crap going on in your apps, so there will be success and errors. If the users don't see these things going on, they will assume nothing is. Therefore, it is in your best interest to keep them posted. Since you have to do this basically all the time, it makes sense to make it simple.

I output all of my stuff to an asp:panel control, so I decided just to extend it to handle these conditions.

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

public static class Extensions
{
  public static void Error(this Panel pnl, Exception ex)
  { // reporting extension for Panel indicating error
    try { pnl.Report(false, "Error: " + ex.Message, ex.InnerException.Message); }
    catch { pnl.Report(false, "Error: " + ex.Message, null); }
  }

  public static void Success(this Panel pnl, string headline, string message)
  { // reporting extension for Panel indicating success
    pnl.Report(true, headline, message);
  }

  public static void Report(this Panel pnl, bool successful, string headline, string message)
  { //this is a helper used by the Success and Error extensions in extensions.cs - for ease of error/success reporting
    string msg = "<h5 class='" + (successful ? "success" : "error") + "'>" + headline + "</h5>";
    msg += !string.IsNullOrEmpty(message) ? "<div>" + message + "</div>" : "<br />";
    pnl.Controls.Add(new LiteralControl(msg));
    pnl.Visible = true;
  }
}

Nothing fancy here, Report just takes in a bool which switches the css class to 'success' if true, 'error' if false, and outputs the 'headline' in h5 tags and the 'message' in a smaller line underneath it. You can use this method by itself, but I also have the Error and Success classes to make it even easier for myself. Of course you have to set up your css to work with this, but it shouldn't be too hard. I will often use it like this:
try
{
  //do some crap here
  myReportPanel.Success("Success!", "whatever you did worked");
}
catch(Exception ex) { myReportPanel.Error(ex); }

And that is it, centralizing your error/success handling also makes it easier to change formatting and be consistent throughout your project. Not to mention it makes it extremely easy to use and implement.


An improved Email Class for .Net

Nothing too special, just combining a couple classes for a more logical approach to email

Most all of my websites/projects require some email to be sent. The System.Net.Mail class is great, but to me, sending an email is not a logical process. Also, the fact that you will likely only use one smtp server throughout a project seems to make the SmtpClient setup a bit repetetive to me. With my class you can setup and send an email as simply as this:
new Email("recipient@hotmail.com", "sender@gmail.com", "You stink", "here are the reasons why...").Send();

Now you wouldn't have to do it all in one line, but this demonstrates that the smtp is already taken care of in the background, this simply builds on the SmtpClient class. Here is the code:
using System;
using System.Net.Mail;

public class Email : SmtpClient
{
  public MailMessage Message { get; private set; }

  // keep in mind I don't recommend hard coding these values in, this is just for example

  public Email(string to, string from, string subject, string body) : base("smtp.gmail.com", 587)
  {
    // this next line is only necessary if you want to enable SSL
    this.Credentials = new System.Net.NetworkCredential("some_guy@gmail.com", "crap_nugget");
    this.Message = new MailMessage(from, to, subject, body);
  }

  public void Send()
  {
    try { this.Send(Message); }
    catch (Exception ex) { throw ex; }
  }
}

Notice that I do not recommend hard-coding your username/password and/or smtp server in the class -- but it will work. Also, this example is to use Gmail, but it will work just as well with another SMTP (I use this with a local Exchange server some times).

Just polishing up an already good tool and making it a bit better.




Setting the row background color in a GridView based on a value in the the row

This is something that needs to be done often, but it is not always obvious how to do it

Often times you want a row to be colored different or highlighted based on values, this can be useful for multiple reasons. This is a very simple thing, but not all that obvious.

Make your different CSS classes

Set up some CSS classes that will be used for the row coloring:
.blue { background:Blue; }
.orange { background:Orange; }
.normal { background:Transparent; }

Set your RowDataBound event in your GridView

This is going to happen on the RowDataBound event, so be sure to call one in your GridView:
<asp:Repeater ID="gv" onrowdatabound="gv_RowDataBound" ...

Set up your event to handle the row

Now handle each row in the event:
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
  e.Row.CssClass = e.Row.Cells[0].Text.Equals("1") ? "blue" : "normal";
}

It's just that simple. Now, if the text in Cell[0] (the first cell) of a row is equal to "1" the row will have it's CssClass set to "blue", otherwise it will be "normal".

Now if you want to have multiple different cases:
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
  switch(e.Row.Cells[0].Text)
  {
    case "1" : e.Row.CssClass = "blue"; break;
    case "2" : e.Row.CssClass = "orange"; break;
    default : e.Row.CssClass = "normal"; break;
  }
}

Now if the first cell is equal to "1", it will be blue, if it is equal to "2" is will be orange, or else it will be transparent; so simple!

Using jquery.autosuggest.js with Asp.Net

Simple Auto-Suggest with Asp.Net and jQuery

After getting fed up with the Ajax Control Toolkit's AutoCompleteExtender and it's inability to deal with strings that are numbers, I decided to look to my new friend jQuery. Apparently they decided for you if you are feeding it an array of number strings (i.e. { "001","002", etc.}) that the auto-suggest will strip all leading zeroes... BUT I NEEDED THOSE ZEROES!

The jQuery solution is pretty simple, much easier than I thought thanks to this awesome plugin: jquery.autocomplete.js. All you really need to do is make a simple aspx page that spits out the data you want based on a QueryString, use a little jquery to tie it up with a TextBox and you are all set. Here is how its done:


Make your data retrieval page

This plugin consumes it's data in one form: text, with one item per line. This makes it very easy to use and very versatile. You could simply point it at a static .txt file, feel it a javascript variable, or, what we are going to do, use Asp.Net to get you some filtered data.

This tutorial is going to use two examples, one pulling from a list of numbers 1-1000, and another pulling form an xml file.

First, the code-behind for number.aspx:
protected void Page_Load(object sender, EventArgs e)
{
  if (!string.IsNullOrEmpty(Request.QueryString["q"]))
  {
    int q = 0;
    if (Int32.TryParse(Request.QueryString["q"], out q))
    {
      for (int i = q; i < 1001; i++)
        if (i.ToString().Contains(q.ToString())) Response.Write(i + Environment.NewLine);
    }
    else
      Response.Write("Not a number fool!");
  }
}

Doesn't get much easier than that... simply writes out any numbers that contain the number (not mathematically, though we could do that) passed in the 'q' QueryString, so if you were to pass the url: number.aspx?q=100 you will get the results:
100
1000

simple.

Now we do the same thing, but dig into an xml file with Linq:
protected void Page_Load(object sender, EventArgs e)
{
  string q = Request.QueryString["q"] ?? string.Empty;
  IEnumerable<string> things = from p in XDocumentLoad(path).Descendants("thing")
        where p.Value.Contains(q) select p.Value;
  foreach(string s in things) Response.Write(s + Environment.NewLine);
}

That was actually the hardest part. Notice that on the Response.Write() I used Environment.NewLine - that will make a newline in the proper format for the jquery to digest, a <br /> or a \n will not work with this plugin. What was made is a psuedo-web-service (it's not really becuase it does not output xml).

Tie it to some TextBoxes

Now just make a couple TextBoxes that will use them:
<asp:textbox ID="txtNumbers" runat="server" />
<asp:textbox ID="txtThings" runat="server" />

Now use jQuery to attach the pages we made to the proper TextBox:

$().ready(function() {
  $("#txtNumbers").autocomplete("number.aspx");
  $("#txtThings").autocomplete("thingXml.aspx");
});

And that's it, you have working auto-suggesters; pretty simple. One thing to notice that can give you some headaches in Asp.Net is that I used the IDs for selection in the code, which is fine if you are not using User Controls or Masterpages, but if you are you get those funky '...ctl100_...' ids that are made at runtime, so you might want to select them with a different method, like making a dummy class and using that as a selector in jQuery

That's about it - but don't forget to style your auto-suggest box or it will just be transparent; there is some basic css showing the classes produced by the jquery in the example. This was just enough to get you started; there is a bunch of documentation and other variables, settings, formatting tricks that you can use (this is a really powerful plugin) - you can read up on them here: http://docs.jquery.com/Plugins/Autocomplete.

IMPORTANT: Remember to delete *everything* on your handling .aspx page other than the '@' declaration so you don't have any extra html in there (I think I left it in there on the download...).


jQuery TextBox Water Mark with asp.net

A jQuery alternative to the AjaxControlToolkit TextBoxWaterMarkExtender

I stole majority of this code from http://www.aspcode.net/A-watermark-texbox-with-JQuery-and-aspnet.aspx but I added a bit to make it swap css classes as well

$().ready(function() {
  swapValues = [];
  $(".wm").each(function(i) {
    swapValues[i] = $(this).val();
    $(this).focus(function() {
      if ($(this).val() == swapValues[i]) {
        $(this).val("").removeClass("watermark")
      }
    }).blur(function() {
        if ($.trim($(this).val()) == "") { $(this).val(swapValues[i]).addClass("watermark") } }) })
});

To use it, make sure your TextBox has (one of) it's css classes set to "wm". If you want a seperate style to be applied add that initially as well, in my example, it swaps "watermark" in and out as a css class.

<asp:TextBox ID="txt" runat="server"
  Text="this is the watermark" CssClass="wm watermark" />

Common Asp.Net Regular Expression Validators

Some of my most commonly used RegularExpressionValidators

Regular Expressions (regexs) are infinitely uesful in validation, but they can be a pain in the butt. With constant help from two amazing websites: RegExLib to find regexs and regexpal to test my own I have been able to put together some of my most commonly users validators.

Email Address

<asp:RegularExpressionValidator ID="regEmail" runat="server"
  ControlToValidate="someTextBox" ErrorMessage="invalid email"
  ValidationExpression="^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$" />

Phone Number

<asp:RegularExpressionValidator ID="regPhone" runat="server"
  ControlToValidate="someTextBox" ErrorMessage="invalid phone"
  ValidationExpression="^(\+[1-9][0-9]*(\([0-9]*\)|-[0-9]*-))?[0]?[1-9][0-9\- ]*$" />

Zip Code

<asp:RegularExpressionValidator ID="regZip" runat="server"
  ControlToValidate="someTextBox" ErrorMessage="invalid zip"
  ValidationExpression="^\d{5}((-|\s)?\d{4})?$" />

Password Length (just change the 8's to your desired value)

<asp:RegularExpressionValidator ID="regPwLength" runat="server"
  ControlToValidate="someTextBox" ErrorMessage="too short"
  ValidationExpression="^.{8}.*$" />

Date

<asp:CompareValidator ID="cvDate" runat="server"
  ControlToValidate="someTextBox" ErrorMessage="invalid date"
  Operator="DataTypeCheck" Type="Date" />

If you noticed, for date it is CompareValidator - why reinvent the wheel?

Make sure you have consistent page titles on your web site

A simple way to catch inconsistency in your titles

Page Titles are often overlookd aspects of web design and can be a simple way to add a little value and professionalism to your site. Users can use your page title to quickly scan bookmarks or on tabs in their browser. Therefore, I feel it is good practice to have a consistent page title naming scheme across your site.

Often I seem to screw up making titles for my pages or forget to add one altogether, or even worse, have the dreaded 'Untitled Page' that was ever=resent before VS2008 SP1. I use MasterPages so there is a centralized structure to build on, and I used this to come up with a way to provide a consistent page title:
string TITLE_ROOT = "My Site";
protected void Page_Load(object sender, EventArgs e)
{
  this.Page.Title = (string.IsNullOrEmpty(this.Page.Title) || this.Page.Title.Equals("Untitled Page"))
    ? TITLE_ROOT : TITLE_ROOT + " :: " + this.Page.Title;


This way, any page that uses this MasterPage will have a nicely formatted title. If you forgot to set a title it would simply be:
My Site

But, say you titled the page "Welcome New Users!", it would then look like this:
My Site :: Welcome New Users!

An easy way to catch myself from making mistakes as well as making it much more consistent.

C-Sharpener.com - Another Project

Learn to Program Asp.Net/C# is Just Days - Guaranteed!

If you have been here before you have likely noticed the ad banner over to the right of the page. That is one of my newer projects that you can check out at C-Sharpener.com.

It is a video series provided with code and throrough explanations of how to get started in the web application and web programming world. The videos cover everything from setting up your environment (with all free tools) and arrays to things such as AJAX and Linq-to-SQL. If it doesn't work, I give you your money back - it's that simple.



Slick-Ticket Trouble Ticketing/Help Desk System

My first Open-Source Project!

This is a simple, to-the-point system. It was born out of loathing of the system that I was forced to use. It was tested in a live environment with hundreds of users and ultimately de-throned our expensive and bloated ticketing software. I really enjoyed developing this and my users and I really enjoy using it, I hope some other people out there like it.
  • Full Integrated with Active Directory means not another layer of permissions to add
  • Intuitive interface allows users to jump right in
  • Integrated help/faq system for administrators to inform users

Details

  • Utilizes .Net 3.5 (C#)
  • Asp.Net architecture built with Linq-to-SQL
  • Utilizes Asp.Net AJAX and the AJAX Control Toolkit
  • Completely customizable colors/themes
  • Installation program included, just load it on your machine and follow the directions

Requirements

  • SQL 2005 Database (SQLExpress works fine)
  • .Net 3.5
  • Active Directory

It is available for download at CodePlex. I also have a site up at http://slick-ticket.com with a demo site soon on the horizon.

Screenshots (Click for full-size images)

Settings interface for the administrator, including the theme customizer Adding a new ticket User profile, most data is pulled directly frorm AD (though you can change it)
*Also notice the different style with the sidebar on the opposite side
Integrated FAQ/Help section for information sharing Easy interface to view the tickets you are interested in View/comment a ticket in progress
*This is Licensed under the GNU General Public License version 2 (GPLv2)

Shout it kick it on DotNetKicks.com

Why I decided to stick with Linq-to-SQL over Linq-to-Entities

I tried to make the switch... but Linq-to-Entities is just so much more work!

Recently I tried, I really tried to like L2E, but I just can't do it! It adds layer upon layers of extra crap I have to do over L2S while offering little to no improvements over the soon to be deprecated ORM. I am officially sticking with L2S until they get L2E better developed. Now I am hardly the first person to write about this, but I feel my concrete examples are somewhat helpful when trying to decide.

Now I have read a bunch of reason of why not to switch, but I stubbornly went along and tried it myself. I like to dumb down my reasons to simple examples of why I have come to loathe L2E (these are all using the same exact DB):

DataSources

I'll just show you on this one, it may not seem like a lot, but try it for yourself and see how confusing the syntax can get:

Linq-To-Entities

<asp:EntityDataSource ID="edsState" runat="server"
  ConnectionString="name=J1Entities"
  DefaultContainerName="J1Entities"
  EntitySetName="state" Select="it.[state_id], it.[state_name]">

Linq-to-SQL

<asp:LinqDataSource ID="ldsState" runat="server"
  ContextTypeName="dbDataContext"
  Select="new (state_id, state_name)" TableName="states" />

Now I don't know about you, but the L2S is just easier to understand. Why the hell do I have to use it.[column_name]? That doesn't make any sense. Not to mention the GUI may as well not be there if you are trying to use automatic Delete, Update or Insert.

Relations

This one is HUGE! Let's say you have a Foreign Key relation of state_id that relates to a table states and Primary Key that is also named state_id; here is how you do that in both frameworks:

Linq-To-Entities

item itm = new item() { item_name = "party" };
itm.state = db.state.First(s => s.state_id = 5));
db.AddToitem(itm);
db.SaveChanges();

Linq-to-SQL

item itm = new item() { item_name = "party", state_id = 5 };
db.items.InsertOnSubmit(itm);
db.SubmitChanges();

Now this is a super abbreviated case, but you can see the huge amount of overhead this can create not to mention programming time. I made these as succinct as I could not to try to advantage one over the other and the L2E is just burdensome. Even if I were to make a simple Get() method for state it would still make another call to the DB when I already know the relation integer!!! What an unnecessary step. And this extra work increases like crazy on large object with multiple relations.

Updating your Model

Now I can't relaly show this as an example, so I will just try to explain it. One big pain (I thought) in L2S was the fact that you had to pull your tables back in to your dbml every time you made a change to the DB (I know there are tools for this, but I am talking stock). L2E had this nifty feature that allowed you to 'refresh from the database' that I thought would actually work. The problem is, that if you change anything with any complexity whatsoever, like a Foreign Key, or even something as simple as changing a data type from VARCHAR to INT it seems to completely break your edmx. And this isn't simple to fix like a dbml, not even close. You can't drag a table into a edmx, and you can't seem to fix it through the refresh so what do you do?
  • Delete your edmx completely
  • Go into your web.config and delete the ConnectionString (unless you want duplicates)
  • Completely remake your edmx
  • Redo any changes in the crappy naming conventions to ALL of your tables that you changed (more on this later)
Wow... all that because I changed a relation? No thank you. Dragging that table into the dbml doesn't seem so bad now.

Relations Part 2

This one isn't as big of a deal, but it is annoying.

Linq-To-Entities

item itm = db.item.First(i => i.item_id == 12);
itm.stateReference.Load()
string whatState = itm.stateReference.Value.state_name;

Linq-to-SQL

item itm = db.items.First(i => i.item_id == 12);
string whatState = itm.state.state_name;

Just simpler in L2S and you don't have to remember the Load() if you forget, and it's in a lot of code, it can be extremely aggravating wondering why your relation is empty. Not to mention that reference.value syntax in there... more unnecessary (in my eyes) crap.

Relations Part 3

And this was the straw that broke the camels back... I was so used to the simplicity and convenience of L2S that this drove me nuts and was the reason I decided to give up. Relations are used so well with L2S that to show relations in something like a Repeater or GridView is almost trivially easy

Linq-To-Entities

Who knows?!

Linq-to-SQL

<asp:BoundField DataField="item.state.state_name" HeaderText="State Name" SortExpression="item.state.state_name" />

but since L2E requires that wonderful Load() method, it is now not so easy - to tell you the truth, I never figured it out how to make it work, probably have to call something on the RowDataBound event, but at this point I figured what is the point?

I am officially resigning from L2E (for now) and going back to L2S... maybe next go-round L2E won't be such a pain? Isn't new technology supposed to make our lives easier? Going from L2S to L2E is like 'upgrading' from a blender to a hand-mixer; it will get done, it will just take you longer and be more frustrating. Hopefully, considering that is the was MS is heading.

Shout it kick it on DotNetKicks.com