Generic Equals Function for Comparing Two Objects in .NET 
So I have two objects in .NET. They are loaded from my database with a bunch of values as members (fields, in .NET parlance). I'd like to know if the two objects are identical.

In .NET, two objects only == each other if they are the same reference. So a pointer to string A won't equal a pointer to string B if the contents of the two are the same but they reside in a different place in memory. Instead, you must do this:


string a = "test";
string b = "test";
if (a.Equals(b)) { something }


This is all well and good, but what happens when I have two RegionObjects loaded from my database? One way to do this would be to write a custom Equals function that looks like this:


class RegionObject
{
public string country;
public string postal_code;

public override bool Equals(RegionObject obj)
{
if (country.Equals(obj.country) && postal_code.Equals(obj.postal_code)) return true;
return false;
}
}


This works great until I start adding new fields to the RegionObject. Then, I have to remember to add a new test each time I add a new field. I don't like that.

Instead, here's a generic function that gets the job done for any compound object using .NET reflections:


public static bool AreEqual(object o1, object o2)
{
// Make sure both classes are of the same type
Type _t = o1.GetType();
if (!o2.GetType().Equals(_t)) return false;

// Compare all properties and ensure they're the same
PropertyInfo[] props = _t.GetProperties();
for (int i = 0; i < props.Length; i++) {
object value1 = props[ i ].GetValue(o1, new object[] { });
object value2 = props[ i ].GetValue(o2, new object[] { });
if (!value1.Equals(value2)) {
return false;
}
}

// Compare all fields (members) and ensure they're the same
FieldInfo[] fields = _t.GetFields();
for (int i = 0; i < fields.Length; i++) {
object value1 = fields[ i ].GetValue(o1);
object value2 = fields[ i ].GetValue(o2);
if (!value1.Equals(value2)) {
return false;
}
}

// Got this far - they must be identical!
return true;
}


  |  permalink  |  related link  |   ( 3 / 78 )
Sending an Email with an Absolute URL in ASP.NET 
So I'm writing an authentication system with notifications. I want to send an email to the user and say "Click on this link to authorize your account."

The best way I know of to do this is to create a GUID, store it in the database, and email a link to the user with that GUID. When the user clicks on the link, verify that the GUID is correct and then flag their account as authenticated.

Since I always forget how to do the easy things, here's how to construct an absolute URL for use with your email message.


string url = HttpContext.Current.Request.Url.Scheme + "://"
+ HttpContext.Current.Request.Url.Host + ":"
+ HttpContext.Current.Request.Url.Port
+ HttpContext.Current.Request.ApplicationPath + "/AuthorizeYourAccount.aspx?userid=USERIDTOAUTHENTICATE&securitykey=GUID";


  |  permalink  |  related link  |   ( 3 / 255 )
Nifty Button Trick 
I hate the way the default HTML buttons look in Internet Explorer. They stretch and they're awful. Here's a great trick for new buttons:

http://www.oscaralexander.com/tutorials ... h-css.html

And if you're using C# in ASP.NET like I am, here's how to define the button he cites:


<asp:LinkButton ID="login" CssClass="formbutton" runat="server" width="200" Text="<span>Login</span>" OnClientClick="this.blur();" OnClick="login_click" />


Here are the CSS definitions you'll want:


.formclear { overflow: hidden; width: 100%; }
a.formbutton { font-family: Arial, Helvetica, Sans-Serif; background: transparent url('../images/button_right.gif') no-repeat scroll top right; color: #444; display: block; float: left; height: 24px; margin-right: 6px; padding-right: 18px; text-decoration: none; }
a.formbutton span { font-family: Arial, Helvetica, Sans-Serif; background: transparent url('../images/button_background.gif') no-repeat; display: block; line-height: 14px; padding: 5px 0 5px 18px; }
a.formbutton:active { background-position: bottom right; color: #000; outline: none; }
a.formbutton:active span { background-position: bottom left; padding: 6px 0 4px 18px; }

  |  permalink  |  related link  |   ( 3.1 / 153 )
Simple Javascript IsNumeric function 
I like the simple tips the best. I found a great IsNumeric function here - http://www.codetoad.com/javascript/isnumeric.asp - and streamlined it a little bit.


function IsNumeric(sText)
{
var ValidChars = "0123456789.";
for (i = 0; i < sText.length; i++) {
if (ValidChars.indexOf(sText.charAt(i)) == -1) {
return false;
}
}
return true;
}

  |  permalink  |  related link  |   ( 3.2 / 192 )
Calculate the Median Value in a Table in Microsoft SQL Server 
So you've got a table with 30,000 rows and you want to find the median value. Microsoft provides a built in function called "AVG" which calculates the average. But what you really want is the median (or any other percentile calculation).

I've found a few different solutions online, but here's the one that seems to work the best.

WITH numbered AS (
SELECT myvalue, rn_up = row_number() OVER (ORDER BY myvalue, myrowidentity),
rn_down = = row_number() OVER (ORDER BY myvalue DESC, myrowidentity DESC)
FROM mytable
)
SELECT AVG(myvalue)
FROM numbered
WHERE ABS(rn_up - rn_down) <= 1

Why does this work? This function produces a temporary table called "Numbered" and it gives every record a number, both in terms of ascending rank and descending rank. As you can imagine, the record where ascending rank equals descending rank is the one in the middle. This happens when you have an odd number of records.

When you have an even number of records, you get one row where the ascending rank - descending rank = 1, and one row where the descending rank - ascending rank = 1. In that case, you average between the two values, and that's your median.

Now, what happens if you want to produce a range of medians? Let's say you have three types of products: books, DVDs, and CDs, and you want to find the median price for each. In this case, you use a partitioned with clause.

WITH numbered AS (
SELECT product_type, product_id, price, rn_up = row_number() OVER (PARTITION BY product_type ORDER BY price, product_id),
rn_down = row_number() OVER (PARTITION BY product_type ORDER BY price DESC, product_id DESC)
FROM products
)

SELECT product_type, AVG(price)
FROM numbered
WHERE ABS(rn_up - rn_down) <= 1
GROUP BY product_type
ORDER BY product_type
  |  permalink  |  related link  |   ( 3 / 164 )

Back Next