If You Do .NET

Short description of the blog

How to unit test ASP.NET Web API 2 Route Attributes

Problem

What I thought was a simple search on the web turned out to be more than that.

The closets to a solution I found was from the person who first made it possible to use Attributes for routing in ASP.NET MVC 4: AttributeRouting not working with HttpConfiguration object for writing Integration tests

But what about ASP.NET Web Api 2?

HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes(); // This don't work. I guess there is needed some more plumbing to know what Controllers to search for attributes, but I'm lost here.
HttpServer server = new HttpServer(config);
 
using (HttpMessageInvoker client = new HttpMessageInvoker(server))
{
    using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, "http://localhost/api/accounts/10"))
    using(HttpResponseMessage response = client.SendAsync(request, CancellationToken.None).Result)
    {
        response.StatusCode.Should().Be(HttpStatusCode.Created);
    }
}

The solution

So … what is the problem.

It turns of that I was missing a simple little line, just after the “config.MapHttpAttributes();”

config.EnsureInitialized();

So finally I got this working.

But why on earth does the HttpServer class or something else not ensure that the config have been initialized.

Why

So I was searching for a reason why this was needed and why this should actually be called.

If you decompile: System.Web.Http.GlobalConfiguration.Configure(Action<HttpConfiguration> configurationCallback)

You will get something like this:

public static void Configure(Action<HttpConfiguration> configurationCallback)
{
  if (configurationCallback == null)
    throw new ArgumentNullException("configurationCallback");
  configurationCallback(GlobalConfiguration.Configuration);
  GlobalConfiguration.Configuration.EnsureInitialized();
}

Why on earth is it done like that … for me this has absolutely nothing to do with “Ensure” … THIS needs to be called after all configuration is done.

Is can be called multiple times with no side effects.

Why ohhh why do you sometime hate us so much Microsoft. Winking smile

Avoid razor compile errors in MVC 4 when deploying

Yesterday I yet again experienced, that my MVC 4 build went fine when built and deployed using teamcity, but still a compile time bug sneaked into production.

Then a combination of google and talking to a friend led me to a solution. I short, this allows you to define that views should be compiled with certain targets. As compiling views increases the build time conciderably, you may want to avoid it for local development.

How to configure this is all shown here: http://www.dotnetcurry.com/ShowArticle.aspx?ID=698

Windows Server 2008 R2 takes forever to start up–60 minutes or so

So a few weeks ago I disabled Ipv6 from the Local Area Connection on my Windows Server 2008 R2. I was changing the gateway and I thought, I’m not going to use it, so I could just as well disable it.

The server is running:

  • Active Directory
  • Exchange 2010
  • TFS 2010
  • DNS
  • IIS

BUT I SHOULD NOT HAVE DONE THAT.

Today I decided to install some windows updates. There were about 16 of them, and one for Microsoft Exchange 2010 SP1 Rollup2 ( I think the name was ).

It took forever to install … but finally after 1 hour is was done and I reboot the machine. It took forever to boot up ( Applying computer settings ) … again 1 hour … login took about ½ hour.

I could see it answered on the IP address … so it was not frozen or anything like that. Did a little googling and found a post mentioning NOT to disable ipv6 because some part of Windows Server 2008 R2 can’t function with out it, unless you also do some register editing. Ohh My Freaking God.

Microsoft … I’m sending Sons of Anarchy over to do some payback. Smile

Adding users to a TFS Project from the server

I have a few servers running, but they are all external to me, as they are placed in a data center, so my own computer aren't joined to the domain.

  • SS-Exchange: DC, Exchange
  • SS-SQL: SQL
  • SS-IIS: IIS. FTP, TFS

This haven't been a problem before at all. So the other day one of my friends asked if I could host a TFS Project for him on my server. No problem, so I created the user in the DC, created the project and the last thing to do was just to add him to the project so he would have access to it, and then the problems started. As my own computer was not part of the domain, I could only add local users, from my own computer. I hadn't been a problem before as my user was “TFS Administrator” so I had access to all projects.

So I started binging/goggling the net, but to no avail. I was puling my hair out … ARGHH.

Then I decided to ask a question on serverfault with the title TFS 2010 - Adding users to a Team Project. Is was slow with comments in the start, but there come a few, buy they did not really help me much.

So I thought it was not possible at all, and a BIG #FAIL by Microsoft.

Then a Anthony come with an interesting comment you can read here.

So I started looking around again as I could not make his suggestion work, probably because I did something wrong since it worked for him. But when jumping around in the “Team Foundation Server Administration Console” I found what I had been looking for all the time. Not the first place to look … but here are the details needed.

Follow the numbers on the above picture.

Again, click the number in the order.

Follow the numbers as before.

The rest for here should be like a walk in the part. God darn this is a well hidden feature that its done from the “Valid Users” properties on the group. But is was here.

Moving a table to another filegroup

So, how does one move a table to another filegroup.

Say I have the following table:

CREATE TABLE [dbo].[Tests](
    [TestID] [int] NOT NULL,
    [TestInt] [int] NOT NULL,
    [TestBigInt] [bigint] NOT NULL,
 CONSTRAINT [PK_Tests] PRIMARY KEY CLUSTERED 
(
    [TestID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Since tables are always stored with the clustered index. Moving the clustered index, also moves the table. So if we want to move the table, we can recreate the CLUSTERED index on another storage group. Here we are moving from “PRIMARY” to “PRIMARY2”.

CREATE UNIQUE CLUSTERED INDEX PK_Tests
   ON dbo.Tests(TestID)
   WITH DROP_EXISTING
ON [PRIMARY2]

This can also be done when the table is online and is also moving the indexes. There are some performance diff if you are moving the table while its still online, so consider if its worth the extra overhead.

You can extend the relation index options with the create index command like this, to move it while its still online.

CREATE UNIQUE CLUSTERED INDEX PK_Tests
   ON dbo.Tests(TestID)
   WITH (DROP_EXISTING = ON, ONLINE = ON)
ON [PRIMARY2]

Find duplicate rows in MS SQL

So, the other day I was reading T-SQL: Why “It Depends” and in the comments section a guys suggested using the “PARTITION BY” in the OVER clause.

I thought was the heck does that do … so i searched the web for an answer … and wow … what a great way to find duplicate post … and possible also a lot of other things it can be used for that I haven’t thought about.

To the code …

WITH Data AS
(
	SELECT 
	ROW_NUMBER() OVER ( PARTITION BY CID ORDER BY Added DESC) AS DupeNumber
	,CID, Added
FROM Servers
)
SELECT * FROM Data Where DupeNumber >= 2

This will check for dupes on the CID column … and then select all the rows where DupeNumber is over or equal to 2. You could then instead of select it … you could delete it.

Fancy way … I like it.