Showing posts with label dev. Show all posts
Showing posts with label dev. Show all posts

Tuesday, November 16, 2010

Enforcing HTTPS or HTTP in ASP.NET WebForm Pages

This is really simple and yet extremely effective... I add these two methods to my Page base class, and suddenly all of my WebForm pages redirect to https when the Request is not to localhost.

protected override void OnInit(EventArgs e)
{
  base.OnInit(e);
  PushSSL();
}

private void PushSSL()
{
  const string SECURE = "https://";
  const string UNSECURE = "http://";

  //Force required into secure channel
  if (!Request.IsLocal && !Request.IsSecureConnection)
    Response.Redirect(Request.Url.ToString().Replace(UNSECURE, SECURE));
}


This code is a simplified version of what I found in this post: 443 <--> 80 - Seamlessly moving requests in and out of SSL. His use of the System.Diagnostics.Conditional("SECURE") attribute on the PushSSL method is very interesting. I like it, but decided I didn't want the extra bit of build configuration complexity this round.

Friday, November 12, 2010

Find it and lose find it and lose it

Periodically, I need the ability to fetch any single item from an arbitrary Linq to SQL ITable based on the primary key value. I've seen this code elsewhere on the Internet, but every time I go looking for it I struggle to find it. So now I'm saving it here once for all. In this case the expectation is that my primary key ID is an integer, but int could easily be replaced by GUID or anything else.

public static class ITableHelpers
{
  public static object SingleOrDefaultByID(this ITable table, int id)
  {
    var param = Expression.Parameter(table.ElementType, "e");
    var predicate = Expression.Lambda(
      Expression.Equal(
        Expression.Property(param, table.PrimaryKey().Name),
        Expression.Constant(id)
      ),
      param
    );

    var call = Expression.Call(typeof(Queryable), "SingleOrDefault", new Type[] { table.ElementType }, table.Expression, predicate);
    return table.Provider.Execute(call);
  }

  public static System.Reflection.PropertyInfo PrimaryKey(this ITable table)
  {
    var matchingProperties = table.ElementType.GetProperties().Where(p => p.GetCustomAttributes(true).OfType<System.Data.Linq.Mapping.ColumnAttribute>().Any(c => c.IsPrimaryKey));

    if (matchingProperties.Count() != 1)
      throw new NotSupportedException(String.Format("Class '{0}' does not contain exactly one property that is a Linq to SQL primary key.", table.ElementType.FullName));

    return matchingProperties.Single();
  }
}

Wednesday, November 10, 2010

SubSonic 3.0's SimpleRepository Auto Migrations - What's the point?

I recently began taking a serious look at SubSonic 3.0 for .NET 3.5. The feature that interested me most is called SimpleRepository and is intended to enable code-first development. It is the primary motivation for trying out SubSonic instead of sticking with my tried and true Linq to SQL workflow of design the DB, update the data context, generate classes using my custom T4 template, and then tweak partial classes. Just writing the steps down makes me tired!

SubSonic's built-in SimpleRepository class provides an implementation of code-first and tweak the database later (a.k.a. auto migrations). Initially I didn't get it, but as I read more and more about how coders are using databases these days, the NoDB concept, MongoDB, etc. etc. it started to sink in. What started to sink in? Well being able to just code, being able to forget about the DB and know that the POCOs I'm creating and changing are being accurately mapped to and retrieved from a magical elf-prince named Database. Of course there will be more to it then just magic like that, but I understand and am perfectly ok with dealing with needs like indexing and production DB migration paths. Those issues are discussions for other posts some other day because they concern the test and production environment and not prototyping/developing.

What's the point of auto migrations?

Ok, so what's the point of a feature called auto migrations that won't automagically migrate my production database from version B to version C? The goal of prototyping/developing is not to migrate my production DB up or down, but to be able to quickly create, experiment with, and refine features. Wouldn't it be nice if I didn't have to go through the endless routine of tweak database, update Linq to SQL datacontext, re-generate classes using my custom T4, dot, dot, dot. This is exactly where SimpleRepository with auto migrations enabled shines: if I make a change to my POCOs and then try working with it and the data it contains the SimpleRepository's auto migration feature steps in and alters the database...I'm guessing, just guessing here, but I think it waves a wand and cries out to the elf-prince named Database, "All Your Database Are Belong To Us", and the elf-prince reorganizes his kingdom accordingly. Crazy!

What's the catch?

Are you catching my drift, feeling my excitement, does it sound to good to be true? Is it? I'm not 100% sure yet, but I'm very close to finding out and when I do I'll create a post and supply some code that proves just how super-duper the tech is, and/or laments what is lacking.

If you already have experience with SubSonic 3.0's auto migration feature please share the love with a comment.

Friday, November 05, 2010

The greatest SQL Server development tools ever

A very special situation at work has required us to look into software for comparing and merging data between two databases with very similar data. Originally we had planned to use Microsoft's SQL Server replication, but the replication system's inability to cope with special constraints forced us to look elsewhere for a solution. A co-worker recommended Redgate's SQL Data Compare product, and as it turns out that it rocks something fierce. It does exactly what I hoped it would, and is stupid simple to use.

Whilst looking at that I also took a look at SQL Compare from the same company. Also mind numbingly good.

Like most shops (should have) we have three environments (or more): Dev, Test and Production. Migrating from the development environment on up has consistently been a chore (at best) and headache inducing, I hate this and want to quit (at worst). With these tools much of the pain is completely side-stepped with minimal tweaking required at migration time.

Wednesday, October 13, 2010

SQL Server cursors - How I got into and out of an infinite loop

Recently while coding at work, a sql server cursor of mine got stuck in an infinite loop. The infinite loop was very surprising to me because I did not expect the result set from the cursor query to change as I updated or inserted new records into the table my cursor query was based on. What I now know is that when a cursor is based on some table, and you update or insert a new record into that table, the cursor will take that data change into consideration. How exactly? Well I'm not sure... (...if you are sure please leave a comment :)

I side-stepped the issue by creating a table variable that I first inserted into, and then spun the cursor off of instead of the spinning directly off of the actual table. Since I am not making any changes to the table variable, but only the actual table, I have not gotten caught in the unending cursor trap.

In addition to the overly aware cursor issue was another problem I have no explanation for. A co-worker noted that one of the fields would sometimes but not always change from Run to Run Complete. Apparently the use of a cursor can induce strange behavior when updating a record that is part of the cursor's result set. In this specific case I was updating the record that the cursor was currently on. Until I have a better grasp of cursors, my use of a table variable seems to side-step this issue by keeping the table my cursor uses and the table I am populating separate.

Monday, October 04, 2010

Detecting Errors in Views at Compile Time

I got this tip from Steve Sanderson's fantastic book Pro ASP.NET MVC 2 Framework.

Open your ASP.NET Webforms or MVC .csproj file in WordPad and find:
<Target Name="AfterBuild">
</Target>
Make it look like this to cause views to compile when building in release mode:
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
</Target>
Be aware of xml comments <!-- --> around the AfterBuild tags that will keep your change from getting used.

The effect is compiler errors in your views will show up when you compile in release mode, and not just when that view is open in Visual Studio.

Thursday, September 30, 2010

Stumbling into unit testing

Well, I finally did it, I took a dip in unit testing last night. I've wanted to put it to use for some time, but have excused myself with the thought that it would take too long to figure out and what I really need to do is get on with writing real code. Riight... To my surprise and happiness, not only was it quick to get the unit testing ball rolling, but it was wonderfully satisfying to see those little tests succeed or even fail! It's one thing to write code that expresses some intent, and expect (more like hope) it will do what I want it to. It is quite another thing to write code, create a test [1], and see that test case prove that my original intent and the final result are one and the same.

I now have a feel for its utility that makes me excited to continue using it. To my new and naive understanding, a unit testing project is like a small console application that runs quickly and tells me simple but important things like "code A threw exception X", "test case B did not match the expected value Y", or "all tests passed and all seems well, sweet dreams". When compared to how I have done "testing" up to this point the time savings is enormous. That is because my traditional technique (for web application development for example) is write some code, compile code, launch web server and browser, login, browse to affected web page, and perform test case B. Had I only stopped making excuses sooner, the time and headaches I could have saved.

[1] Yeah I know everybody says write the tests than the code, red-green-refactor and so on, but I'm just starting. I look forward to growing in understanding, and learning when is best time to do what.

Thursday, September 23, 2010

Create email files in .NET instead of sending emails with SpecifiedPickupDirectory

Normally in web.config we have:
<configuration>
    <system.net>
        <mailSettings>
            <smtp deliveryMethod="Network">
                <network host="smtp.example.com" />
            </smtp>
        </mailSettings>
    </system.net>
</configuration>
Recently I learned that when developing we can output to ".eml" files directly to our C:\ drive if we configure like so:
<configuration>
    <system.net>
        <mailSettings>
            <smtp deliveryMethod="SpecifiedPickupDirectory">
                <network host="ignored" />
                <specifiedPickupDirectory pickupDirectoryLocation="c:\ExampleEmailPickupFolder" />
            </smtp>
        </mailSettings>
    </system.net>
</configuration>
The .eml files can be opened and read using Notepad. I'm told Outlook can open them, but I'm not sure if Lotus Notes can.

If you ever want to test email capabilities while developing locally you no longer have to be shy about it, but can output directly to files. Another useful feature is that you don't have to be worry about accidently emailing a user since we know emails are not sent, but we can see what every email that would have been sent looks like.

Tuesday, September 14, 2010

POST values take precedence over GET values

This is something I have always suspected, but now I know for certain. If there is a posted value with the name ArticleID, a get value in the query string with the same name, and your action asks for "int ArticleID" then ASP.NET MVC 2 will give you the posted value and ignore the get value.

It makes good sense to me, but is nonetheless something every ASP.NET MVC developer should be aware of especially when dealing with security.

Tuesday, July 20, 2010

SQL Server - Enforce foreign key constraints and cascading deletes

Apparently if Enforce foreign key constraint is set to No in the designer cascading deletes will not take place. The programmatic variant of setting that to No is:

 ALTER TABLE MyTable NOCHECK CONSTRAINT MyFKConstraint


Swapping out NOCHECK with CHECK will enforce the fk constraint.

Although I think this behavior is reasonable, and even desirable it has put me on my heels more than once. Hopefully writing it down will keep me from forgetting again.

Monday, July 13, 2009

DI and IoC

Speak in acronyms others don't know and imply that you know something they don't whilst pretending it's so well understood by you that there's no need to use whole words. Better yet, use words or phrases like Gospel or Democrat with your friends only to say a lot whilst conveying little or nothing. [1]

I'm currently trying to wrap my head around Dependency Injection and Inversion of Control. I think I'm part way there and think these links make great stepping rocks.

http://www.lostechies.com/blogs/derickbailey/archive/2008/10/07/di-and-ioc-creating-and-working-with-a-cloud-of-objects.aspx

http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/09/12/some-ioc-container-guidelines.aspx

[1] Which isn't to imply that the use of Gospel and Democrat cannot be understood, but simply acknowledges that individuals can be thinking and imagining two totally different things when such expansive words arise in conversation. I've recently begun to learn the difference between hearing and listening. It's a dooser of a lesson I don't expect to complete this side of Heaven (another fascinating word that may have more to do with expanse then we can dare to imagine).

Friday, June 05, 2009

Deleting ASP.NET 2.0 Application Sub-Directories Shuts Down the AppDomain

This wrecked my mind for about 4 hours today. As the title suggests deleting a sub-directory shuts down the AppDomain. I really wish it would have thrown an exception or something helpful. Instead I thought I was doing something wrong when my Session would suddenly go blank. This forum post finally revealed the sneaking problem:
http://forus.asp.net/t/1287418.aspx
and this one explains some solutions that I did not implement:
http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx