Posts

Showing posts from 2014

How I Architect My ASP.NET MVC Apps (Circa Now, 2014)

I recently got a text message from a former co-worker of mine named Mark. Mark was embarking on a new project using ASP.NET MVC and wanted to know how I organize the code in my solutions. I replied with a few text messages giving a quick summary, and told him I'd write a post about it on my blog that would go into more detail.

Here's how I architect my ASP.NET MVC solutions. I'm not saying this is the way to do it, only that it's my way. A year from now it may be different. Software development is always evolving.
Before diving into the different layers of my solutions, there are certain design principles I adhere to that I find very useful and should be mentioned. These are outside the scope of this blog post, but if you aren't familiar with any of them, I highly recommend researching them. They are:
SOLID (Single Responsibility Principle, Interface Segregation Principle, Liskov Substitution Principle, Interface Segregation Principle, Dependency Inversion Principle…

Getting Your TFS Builds To Run Your Jasmine JavaScript Unit Tests

A month or so ago I was setting up an automated build and deployment using TFS 2013. I set my build up to run my unit tests, and to consider the build a failure if they didn't pass. If the build fails (either due to compilation failure or unit test failure), the deployment step shouldn't take place.

The application in question uses Angular.js and I've written a good number of unit tests to test my Angular controllers, services, etc. For these tests, I used Jasmine (instead of Karma, which is the most often recommended test framework for Angular -- long story). In Visual Studio, I make use of the awesome Chutzpah extension to allow my Jasmine unit tests to be integrated into the Test Explorer right-click context menu just like my MSTest unit tests of .NET code.

But how to get these to run as part of my automated build from TFS? It took a little digging, but thanks to an extremely helpful blog post and a little trial-and-error, I found the answer. Here's how:

1. Add Chut…

A Generic Method Using HttpClient to Make a Synchronous Get Request

A while back I wrote a post on how to make an HTTP Get request using the HttpWebRequest object in .NET, implemented in a Generic method. Last week I had two occasions during which to revisit this code, but using the HttpClient class introduced in .NET 4.5 instead. The code below is functionally similar to the code in my earlier post, but uses HttpClient instead of HttpWebRequest.

A few points of interest:

The HttpClient.GetAsync() method returns a Task that is executed asynchronously (hence the name), however, calling the Result property of that Task ensures that the asynchronous operation is complete before returning. By accessing it off of the GetAsync() return value as shown below, we are essentially blocking and changing the call into a synchronous one.The EnsureSuccessStatusCode() method of the HttpResponseMessage class will throw an exception of the response does not indicate success.
public T ExecuteGet(string url)
        { if (String.IsNullOrWhiteSpace(url)) thrownewArgumentExcept…

Register Types By Convention With Unity

Using Microsoft's Unity IoC container, you can register types by convention rather than having to explicitly register each interface to a concrete class. The convention is that interfaces beginning with "I" will map to concrete classes with the same name, minus the "I" (for example, interface IMyClass would map to concrete class MyClass). I only recently learned this, after watching a Pluralsight course that showed how to do the same thing using StructureMap. I'd used StructureMap a few years ago, but was unaware of this feature at the time, and am not sure if it existed then or not.

The example shown below will register types by convention (for example, uses of interface IMyClass yield concrete types of MyClass).
            container             .RegisterTypes( AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default);
This cut down on the size of my Unity bootstrapping code significantly. J

Windows Authentication Still Broken When Using Safari in iOS 7.1

When Apple released iOS 7 last fall, Windows Authentication no longer worked when using Safari. And even though they've released a few updates to the operating system since then, Windows Authentication is still broken when using Safari (Chrome on iOS was unaffected and has been working fine in iOS 7). This seems to just affect requests made from client-script, as making a request to a website that uses Windows Authentication still prompts you for your credentials and works fine for any non-AJAX requests.
Here are two lines from an IIS log showing the same request. The first is from a Safari on iPad and was unsuccessful, the second is from Chrome on iPad and worked fine. Notice the 401 response on the unsuccessful request, due to the missing username (which is visible in the 2ndrequest). The IP address has been obfuscated for these examples.
Unsuccessful (username missing):  2014-03-20 15:38:01 172.26.xxx.xxx POST /Orders/UploadAttachment/2 - 80 - 172.26.152.222 Mozilla/5.0+(iPad;+C…

Funny MVC Routing Quirk

I recently ran into a funny quirk with ASP.NET MVC’s routing. I have a method to retrieve attachments which have been uploaded for orders in an ordering system. Originally, I had the method and the route defined like this:
Method signature: publicActionResult AttachmentView(int orderId, string filename)
Route definition:             routes.MapRoute(name: "Orders_AttachmentView",                 url: "Orders/AttachmentView/{orderId}/{filename}",                 defaults: new { controller = "Orders", action = "AttachmentView" }             );
When I tried to call this method, I’d get an error from IIS saying that the resource wasn’t found. I checked and double-checked the route: no problems, everything was correct. I put a breakpoint in the method to ensure that the code wasn’t being reached, and it wasn’t.
Then I thought that maybe the extension on the filename parameter was throwing the route off. I changed the method signature and route definition …

More Retro Goodness

Image
I hadn't been born when either of these breakfast cereals debuted, yet I still get a kick out of the recent retro packaging for these two. 

Don't Do This With Microsoft's Unity IoC Container

I recently did something pretty dumb when using Microsoft's Unity IoC container. Because one of my classes depended on a string parameter for its constructor (a configuration value that I pass into it), I had to register the type rather than simply relying on dependency chaining. See below (this code is an example of the real code, but not the actual code as to protect my employer's intellectual property guidelines):

.RegisterType<IProjectRepository, ProjectRepository>( newInjectionConstructor( newResolvedParameter(typeof(IRESTServiceHelpers)), ConfigurationManager.AppSettings["CentralServiceURL"], newResolvedParameter(typeof(ICacheManager)), newWidgetFactory()))

See the problem? It's that "new WidgetFactory()" statement. The real class in question didn't implement an interface, so, like a dummy, I set it up to be injected by Unity as shown above.

Mistake!!!

What the code above ends up doing is maintaining a single, new WidgetFactory object that it…

Angular.js Unit Test with Custom Service Example

(Updated 7/13/2014)

I've been working a lot with Angular.js lately, and there were a lot of unknowns for me when it came to unit testing my code. Below is an example that I hope will help other people who have questions about how to write unit tests for Angular.

I use Jasmine as the unit testing framework, and in the example below I'm testing controller named DocumentController which makes use of a service called AttachmentService. In the example below, we're testing the ability of the DocmentController to delete attachments, which it does with the help of AttachmentService.

I've commented it heavily in an attempt to be very clear as to what this code is doing. I hope this helps you. :)

//References to the JS files that are required by these tests and everything involved.
//The order matters!

/// <reference path="../jasmine/jasmine.js" />
/// <reference path="../jasmine/boot.js" />
/// <reference path="../angular.js" />
/// <…