Simple URI Tip for HTML

You may already know this, in which case you ran across it randomly, or are the kind of developer that reads specs. But if you haven’t run across this, prepare for a face-palm moment wondering why you didn’t know this years ago.

Using a uri like the following tells the browser to get the content over whatever protocol the current document was fetched from.

<script src="//platform.twitter.com/widgets.js"></script>

Think of all the little annoying server side script you’ve written to determine the protocol based on the request variables in order to avoid security warnings. Never again. Enjoy.

One warning… don’t do this in phonegap.

More detail, and links to rfcs at stackoverflow.

Strange NuGet Error

One of the projects that I work on uses NuGet for library management. We have a rake task that runs build, clean, etc. One of the rake tasks runs NuGet.exe which is stored in a tools directory. That way, everyone uses the same version of NuGet even if they have different versions installed in their program files directory.

For some strange reason I was getting errors when running the rake task that updated the packages. Sometimes it was a generic error, sometimes “Archive file cannot be size 0”. I verified that the NuGet version hadn’t changed. I tested on other machines. I tried running the command by hand to take rake out of the equation. On one machine, it wouldn’t work. Every other machine fine.

I even wiped the folder and checked out again with git. No luck. Finally, I decide to look for a NuGet local cache and see if I had bad packages. Delete the contents of C:\Users\YourUsername\AppData\Local\NuGet\Cache\ and this problem will go away. Hopefully this info saves you some time.

Safely Using an Insecure SA Development Account

As a consultant, I’m sometimes a part of projects that do things I wouldn’t choose to do. Welcome to the real world, right? For example, on one project I worked on in the past, the connection string for an asp.net project used the “sa” account for sql server. Further, it was in the web.config file and that file was checked into source control. First, I’m not a big fan of connection strings in source control, and have already posted on an easier way. If nothing else, use “Integrated Security=SSPI” in the connection string, and then each developer uses his local windows account to assign permissions.

But I’m a consultant on this project, and I can’t dictate that change. Fine. So I just lived with it for a while. But it bothered me that anyone on the project, or ever on that project, was walking around with the same sa password, and the password policy file unchecked. Until I came up with a simple solution.

Rename sa, and put the password policy back in place. And then create a new user called sa, that only has the necessary privileges on that database. If you don’t have need of your sa account for other reasons, you could just reduce the permissions in this case. But I still wanted a sql login that had permissions to administrate the database. Usually, you would do that kind of management from a domain account, but I don’t run a domain since I’m in so many different locations, and I might need to manage remotely, hence a sql login.

Anyway, here are the steps:

1. Rename the sa user:

alter login sa with name = mynewsystemaccount

2. Restart your sql server

3. Choose a new password for sa, and check the policy is enforced. I did this with management studio, but you can use t-sql if you prefer:

alter login mynewsystemaccount with password='some strong new password here', 
      check_policy = on, check_expiration = off;

4. Create a new sa user with the previously insecure password, and only grant them the necessary permissions on the database for that development application.

“sa” is still an insecure account, and any other developer can run any command they want on that development database, but they can’t administrate your whole server. There are plenty of other ways to solve this, if you have an interesting one, post in the comments below.

Rake Tasks For NuGet

If you use NuGet, and only check-in your packages.config files to source control, then your source control repository will stay smaller, and checkout faster. Checking in binaries is usually a nice thing to avoid. However, you need new developers to be able to get those libraries locally easily, and to allow your build server (continuous integration or otherwise) to keep libraries up to date.

After all, that’s one of the advantages of NuGet, you only download a new library when you first need it for that solution, or when you change versions.

In order to solve this problem, I use a rake task, as we use rake for other setup tasks (creating or seeding databases, continuous integration, etc). Rake may sound like an odd choice for a .Net environment, but it’s very good for customing cmd line tasks, and all the .Net building and setup we have run into can be done from the command line. Anyway, assuming the directory structure below, I thought I’d share the Rake tasks…

MySampleProject
|-Rakefile
|-tools
 |-NuGet.exe
|-Source
 |-Packages
  |-NHibernate
  |-MassTransit
 |-SampleProject.Web
  |-packages.config
  |-SampleProject.Web.csproj
  |-other files, etc
 |-SampleProject.ServiceBus
  |-packages.config
  |-SampleProject.ServiceBus.csproj
  |-other files, etc

Relevant tasks in the Rakefile below. Note the ci task using nuget task before it builds.

def nuget_for_project(project_dir)  
  sh "tools\\NuGet.exe " + 
    "i Source\\#{project_dir}\\packages.config " + 
    "-o Source\\Packages"
end

namespace :nuget do  
  desc "nuget for servicebus"  
  task "ServiceBus" do	
    nuget_for_project "SampleProject.ServiceBus"  
  end    

  desc "nuget for web"  
  task "Web" do	
    nuget_for_project "SampleProject.Web"  
  end  
  
  desc "nuget for all"  
  task "all" => ["nuget:ServiceBus", "nuget:Web"]
end

desc "continuous integration task"
task "ci" => ["clean", "nuget:all", "build", "test"]

NHibernate Named SQL Queries with Parameters

I had to create a stored procedure to be called from NHibernate. You could use Session.Connection to execute with ADO.Net, but I like the idea of staying in NHibernate for consistency. Anyway, I found a lot of documentation on how to call one, but not with a parameter, so I thought I’d document that here. Note that I recommend NHibernate in Action for understanding all the various query methods.

This will be a simple and contrived example, that in no way justifies not just using NH linq, Criteria, or HQL to query. But let’s say you have a book table, and you want to query by author and for some reason you need to do this in a stored proc, because there is some aspect of the code or optimization that you only can do in the db.

Create your stored proc:

Use [MyDatabase]
Go

if OBJECT_ID('[dbo].sp_BooksByAuthor') is not null
begin
	drop proc [dbo].sp_BooksByAuthor
end
go

create proc [dbo].sp_BooksByAuthor
   @author_id bigint
as
begin
Set NOCOUNT on
Select b.* 
From Books b
Where AuthorId = @author_id
end
Go

*Note the alias for books is optional, but if you do it, you need to specify it in the query mapping (see below).

Then map the query. Somewhere in one of your mapping files, but outside of a class put:

<sql-query name="MyBookByAuthorQuery">
  <return class="Book" alias="b" />
  exec sp_BooksByAuthor :AuthorId
</sql-query>

Finally, your NHibernate query would look like as follows:

public IList<Book> GetBooksByAuthor(Author author)
{
   var session = SessionFactory.GetCurrentSession();
   var qry = session.GetNamedQuery("MyBookByAuthorQuery");
   qry.SetParameter("AuthorId", author.Id);
   return qry.List<Book>();
}

Your data access may vary a lot from a simple method like that, but you get the idea.

One thing worth noting, if you get an error about clazz_, it’s related to polymorphism. Go read this post for how to write your sql to account for it: http://www.methodicmadness.com/2009/01/nhibernate-what-is-heck-clazz.html