Link here

Link here

Pro ASP.NET MVC 2 Framework

ASP.NET, MVC, Pro ASP.NET MVC 42 Comments »

imageThis week Apress is sending the second edition of my ASP.NET MVC book to the printers. Hopefully this means you can get your hands on physical copies by the end of this month.

The first edition went deep into the details of the MVC Framework, providing both tutorials and reference material. Judging by sales and review scores, it was a success. The second edition:

  • … is thoroughly updated for ASP.NET MVC 2. It explains all the new features, including templating, metadata, validation, asynchronous controllers, areas, HTTP method overloading, strongly-typed input helpers, default parameters, etc., and many are demonstrated in the various tutorials.
  • … is updated to account for .NET 4 and Visual Studio 2010. Even though .NET 4/C# 4 is the preferred technology throughout the book, all the documentation and code accounts for readers using .NET 3.5 as well.
  • … is updated to reflect more recent patterns and best practices. For example, discussions of automated testing apply ideas from Behaviour Driven Development (BDD) where relevant, and tutorials and descriptions now consistently distinguish between view models and domain models.
  • … is updated in light of reader feedback from the first edition. Certain explanations and terminology are overhauled, and the tutorials make use of more effective third-party libraries (e.g., Ninject for Dependency Injection).

This blog post is partly intended to build awareness of the new book, and is partly intended to deal with some of the questions I regularly get by email. So, here are some questions that people frequently ask:

Is this a new book, or an update?

It’s an update of the first edition. The following diagram should clarify what proportions of the book are new, dramatically changed, or just refreshed:

image

Where and exactly when can I get it?

I don’t know the exact date when it will ship; this depends on physical production and distribution schedules that are beyond my knowledge.

  • For printed copies, your best bet is to pre-order with Amazon. Hopefully these will ship around the end of June, but I can’t guarantee it.
  • For the eBook version, keep checking the Apress web site.

There’ll probably be a Kindle version in due course, too.

If I already have the first edition, should I buy the second edition?

If you use ASP.NET MVC regularly - especially if plan to use the new MVC 2 features but haven’t yet learned about them in depth - you may well get a lot out of reading the new edition and seeing what’s the same and what’s new. You may also have colleagues who need a deeper knowledge of the whole MVC Framework, including both v1 and v2 features.

However if you don’t use ASP.NET MVC much and don’t intend to migrate your development to v2, perhaps there isn’t such a strong case for buying an update of a book you already own.

Some readers have asked if they can get a sort of “upgrade” edition which contains only the new material. That wouldn’t really make sense for this book, as the new concepts and practices are applied throughout. I don’t present “old” material followed by “new” material – the whole manuscript is updated as a single coherent guide to ASP.NET MVC 2 from the beginning as I believe this gives the clearest understanding.

What new and updated in the second edition?

There are far too many updates and enhancements in the new edition to describe them all. Here’s a brief outline of the table of contents and roughly how each chapter has changed.

Chapter 1: What’s the Big Idea?

Updated to account for ASP.NET 4, including improvements to WebForms and how this impacts the comparison between the two frameworks. Gives an overview of what’s new in ASP.NET MVC 2. Changed the discussion general software development practices to account for more recent trends.

Chapter 2: Your First ASP.NET MVC Application

Tutorial now accounts for your choice of Visual Studio 2008 or Visual Studio 2010. Uses new ASP.NET MVC 2 features, including empty project template, automatic HTML encoding, and Data Annotations validation. Streamlined the flow of the tutorial to improve readability.

Chapter 3: Prerequisites

Describes newer architectural patterns including MVVM. Discussion of automated testing expanded to cover integration testing as well as unit testing, and demonstrates Cucumber-style BDD testing and explains the tradeoffs between this and traditional unit TDD. Various updates to terminology and explanations.

Chapter 4, 5, 6: SportsStore tutorial

Now accounts for your choice of Visual Studio 2008 or Visual Studio 2010. Improved the code: better project structure, uses Ninject instead of Castle Windsor for DI, has better unit test naming (BDD-style) with a clearer description of the limitations of such testing. Applies the viewmodel pattern and related terminology more consistently.

Adapted the tutorial to benefit from MVC 2 features including optional parameters, metadata, scaffolding, client-side validation, automatic (de)serialization, etc. Some parts of the tutorial now go in a different order to make it easier to follow.

Chapter 7: Overview of ASP.NET MVC Projects

Updated to account for ASP.NET MVC 2’s two project template options (empty and non-empty), and for changes in the core ASP.NET 4 platform regarding configuration and deployment.

Chapter 8: URLs and Routing

Now covers areas – reasons for using them, setting them up, their impact on routing, how to avoid common problems, how to unit test their routing configuration. Explains how .NET 4 changes where the routing code lives and how ASP.NET MVC 2 deals with controller namespaces. Many smaller changes.

Chapter 9: Controllers

The 1st edition’s “Controllers” chapter is now split in two – this first chapter now covers introductory topics – receiving input data with parameter binding etc, producing output with action results etc., unit testing.

Has many changes to account for ASP.NET MVC 2, such as its enhancements to TempData. Also describes .NET 4 features – using optional parameters (and how these differ from ASP.NET MVC 2’s parameter defaults), using “dynamic” as a model type, etc. Expands the coverage of unit testing, demonstrating 5 ways to make mocking controllers easier.

Chapter 10: Controller Extensibility

The 1st edition’s “Controllers” chapter is now split in two – this second chapter now covers more advanced topics – custom filters, method selectors, controller factories, etc.

Updated to reflect changes in the ASP.NET MVC 2 request-processing pipeline, new built-in filters, HTTP Method Overriding, etc. Adds (a lot of) coverage of asynchronous controllers – not just how to use them, but how to measure their impact and avoid common misconfiguration problems.

Chapter 11: Views

Goes into detail about how automatic HTML encoding works. Coverage of HTML helper methods expanded for ASP.NET MVC 2 (there’s now over 50 helpers, and that’s before you even start counting all their different overloads). Explains new ways to render partials.

Chapter 12: Models

Most of this massive chapter is totally new, and goes into great detail about metadata, templating, and validation. Covers how the built-in templates work, creating custom ones, using HTML field prefixes, implementing custom metadata sources, consuming metadata, custom validation providers, custom client-side validation, doing all this inside a multi-tier architecture, etc.

The explanation of model binding and value providers is significantly updated to account for the new architecture in ASP.NET MVC 2.

Chapter 13: User Interface Techniques

This new chapter inherits UI-related material from various parts of the 1st edition book, including wizards, CAPTCHAs, child actions, master pages, open-source view engines, custom view engines. All updated to match ASP.NET MVC 2, of course.

Chapter 14: Ajax and Client Scripting

Updated various aspects of the code and explanations to account for new framework features, and to make things work with more recent versions of IE. Expanded the coverage of JSON data services, including security issues and ways to handle cross-domain requests. Some recommendations are updated to account for client-side performance considerations(browser’s rendering pipeline, CDNs, etc).

Chapter 15: Security and Vulnerability

Mostly the same as in the first edition. Shows an alternative tamper-proofing mechanism using MVC 2 code, plus describes JavaScript string encoding and its relation to script injection. Various code changes to fit in with ASP.NET MVC 2.

Chapter 16: Deployment

Radically restructured chapter – now all organized with step-by-step guides and checklists for each targeted IIS version, so now you only have to read the material relevant to you. Covers new deployment options, including combinations of .NET 3.5 SP1, .NET 4, Server 2003, Server 2008, Server 2008 R2, Server 2008 R2 Core, shared hosting, classic/integrated pipeline mode, etc. Accounts for many changes to these deployment environments since the 1st edition, including IIS 7.5-specific issues

Clearer explanations of various IIS request-processing mechanisms. A new section describes VS2010’s improved publishing and packaging mechanisms, config file transforms, etc.

Chapter 17: Using ASP.NET Core Platform Features

Mostly the same as in the first edition. Updated to account for ASP.NET MVC 2, IIS 7.5, with tweaks to code and explanations. Information about configuration APIs moved from Deployment chapter into this chapter.

Chapter 18: Migrating Existing Applications to ASP.NET MVC 2.0

Various updates relating to .NET 4 / VS2010 / ASP.NET MVC 2, including how to upgrade Web Forms applications to support MVC, using routing when combining MVC with Web Forms (both on .NET 3.5 and .NET 4), ways you can use Web Forms server controls with postbacks in MVC 2, should you wish to.

New section describes upgrading from ASP.NET MVC 1 – using automated tooling, doing it manually, a post-upgrade checklist, workarounds for potential problems.

OK, enough details

Of course, there are other ASP.NET MVC 2 books in the pipeline too. No doubt you’ll enjoy and benefit from any of them.

Deleporter: Cross-Process Code Injection for ASP.NET

ASP.NET, BDD, Testing 5 Comments »

Deleporter is a little .NET library that teleports arbitrary delegates into an ASP.NET application in some other process (e.g., hosted in IIS) and runs them there. At the moment, it’s still pretty experimental, but I’ve found it useful so far.

Why would you want this? It’s mainly useful when you’re integration testing. Normally, integration tests can’t directly interact with your application’s code because it’s in a separate process (and possibly running on another machine). So, unlike unit tests, integration tests often struggle to test different configurations and have no option to use mocks.

Deleporter gets around that limitation. It lets you delve into a remote ASP.NET application’s internals without any special cooperation from the remote app (it just needs to include an extra IHttpModule in its config), and then you can do any of the following:

  • Cross-process mocking, by combining it with any mocking tool. For example, you could inject a temporary mock database or simulate the passing of time (e.g., if your integration tests want to specify what happens after 30 days or whatever)
  • Test different configurations, by writing to static properties in the remote ASP.NET appdomain or using the ConfigurationManager API to edit its <appSettings> entries.
  • Run teardown or cleanup logic such as flushing caches. For example,  recently I needed to restore a SQL database to a known state after each test in the suite. The trouble was that ASP.NET connection pool was still holding open connections on the old database, causing connection errors. I resolved this easily by using Deleporter to issue a SqlConnection.ClearAllPools() command in the remote appdomain – the ASP.NET app under test didn’t need to know anything about it.

Rails developers can already do this either by hosting their app in-process (e.g., with WebRat) or using a cross-process mocking tool. I’ve already talked about hosting ASP.NET (MVC) apps in-process with integration tests (the starting point for this code); now I wanted to get the same benefits while hosting my app on a real web server.

This library is built on regular .NET remoting. But unlike regular remoting, it run arbitrary delegates, not just methods specifically exposed by the remoting service. If the code for your delegate isn’t already loaded into the ASP.NET appdomain, Deleporter will serialize the code and send it across. This is really essential for being useful from an integration test suite, because the test code wouldn’t normally be in the real app.

Enough talk! Code now.

To use it, first download the binary or compile the source to get Deleporter.dll. Reference it from both your integration test project and the ASP.NET MVC/WebForms app you’re testing.

Next, to get your ASP.NET app to listen for commands, edit its Web.config file to reference this extra HTTP module:

<configuration>
  <system.web>
    <httpModules>
      <!-- If you're using Visual Studio's built-in web server, or IIS 5 or 6, add this: -->
      <add name="DeleporterServerModule" type="DeleporterCore.Server.DeleporterServerModule, Deleporter" />
    </httpModules>
  </system.web>
  <system.webServer>
    <modules>
      <!-- If you're using IIS 7+, add this: -->
      <add name="DeleporterServerModule" type="DeleporterCore.Server.DeleporterServerModule, Deleporter" />
    </modules>
  </system.webServer>
</configuration>

Now, when you next start up your ASP.NET app, it will listen on TCP port 38473 - a randomly-chosen default - for commands from your integration test suite.

In your integration test code, you can now run arbitrary delegates in the remote ASP.NET app, sending both data and code into it, and optionally pulling data back. As a trivial example, you can pull back the server’s time local time:

[Test]
public void ServerClockHasCorrectYear()
{
    DateTime serverTime = Deleporter.Run(() => DateTime.Now);
    Assert.AreEqual(DateTime.Now.Year, serverTime.Year, "The server's clock is way off");
}

You can use multi-statement lambdas, too, even if they capture locals from the containing method. Deleporter will send the captured locals into the remote app (as long as they’re serializable), and if the remote app edits them, it will pull back the new values and update your locals. In other words, anonymous methods and multi-statement lambdas work with captured local variables just as if all the code was running locally. Example:

[Test]
public void SendingAndUpdatingCapturedLocals()
{
    DateTime serverTime = default(DateTime);
    string fileToLocate = "~/web.config";
    string mappedPhysicalPath = null;
 
    Deleporter.Run(() => {
        // This code, which both reads and writes locals from the outer scope,
        // runs in the remote ASP.NET application
        serverTime = DateTime.Now;
        mappedPhysicalPath = HostingEnvironment.MapPath(fileToLocate);
    });
 
    Assert.AreEqual(DateTime.Now.Year, serverTime.Year);
    Assert.IsTrue(File.Exists(mappedPhysicalPath)); // Of course, this will only be true if the ASP.NET app runs on the same machine as the integration test code
}

More realistic applications

So far I’ve only shown very artificial examples designed to illustrate the syntax. To give you a more realistic idea of how you could apply it, I can offer two sample applications.

  • A very simple ASP.NET MVC app called WhatTimeIsIt whose sole behaviour varies according to the date. Like all good ASP.NET MVC applications, it uses the Dependency Injection pattern (in this example, with Ninject) to get the current date & time from an IDateProvider – the default implementation of which just returns DateTime.Now.
    It has simple integration tests that use Deleporter and Moq to inject a mock IDateProvider across the process boundary while the app is running, and then verifies some behaviour that only happens during specific dates. It also demonstrates an easy way of tidying up after the tests run (restoring the original IDateProvider) automatically without cluttering the test code with teardown logic.
    Here’s how the cross-process mocking works:
    // Inject a mock IDateProvider, setting the clock back to 1975
    var dateToSimulate = new DateTime(1975, 1, 1);
    Deleporter.Run(() => {
        var mockDateProvider = new Mock<IDateProvider>();
        mockDateProvider.Setup(x => x.CurrentDate).Returns(dateToSimulate);
        NinjectControllerFactoryUtils.TemporarilyReplaceBinding(mockDateProvider.Object);
    });
  • An enhanced version of the SpecFlow BDD-style integration test suite from my previous blog post. It now uses Deleporter to apply a mock repository to verify certain specifications.
    For example, one of the Gherkin files now specifies this scenario:
    Scenario: Most recent entries are displayed first
    	Given we have the following existing entries
    		| Name      | Comment      | Posted date       |
    		| Mr. A     | I like A     | 2008-10-01 09:20  |
    		| Mrs. B    | I like B     | 2010-03-05 02:15  |
    		| Dr. C     | I like C     | 2010-02-20 12:21  |
          And I am on the guestbook page
        Then the guestbook entries includes the following, in this order
    		| Name      | Comment      | Posted date       |
    		| Mrs. B    | I like B     | 2010-03-05 02:15  |
    		| Dr. C     | I like C     | 2010-02-20 12:21  |
    		| Mr. A     | I like A     | 2008-10-01 09:20  |

Gotcha: What you must remember to avoid confusing problems

One behaviour might surprise you at first. It’s certainly caught me out plenty of times already. Each time you edit and recompile your integration test code, you must also recycle your ASP.NET appdomain (e.g., by resaving its Web.config file, or the nuclear option - running iisreset) otherwise the old code will still be loaded into it. That’s because, as far as I’m aware, there’s no way to unload an assembly from a .NET appdomain. Once your delegates have been transferred over, they’re staying there and can’t automatically be replaced by newer versions.

This isn’t a problem if you’re running an integration suite through your continuous integration (CI) system – the app code would be recompiled and hence reset between test suite runs. It’s only something to watch out for during local development. In the Deleporter.Test.Client project I’ve shown a crude but working way of automatically recycling the ASP.NET appdomain when the test suite starts running; you may be able to work out a better way of automating this if you need one.

Important security note

You should not enable DeleporterServerModule on a production web site. It’s only supposed to be used in dev and QA environments, because it’s literally an invitation to upload and execute arbitrary code.

To reduce the chance of a mistake, DeleporterServerModule will refuse to run if your web site was compiled in release mode – it will demand that you remove the IHttpModule from your Web.config file. Technically you should be OK if your firewall doesn’t accept inbound connections on port 38473 (or whatever port you configure it to listen on) anyway. Obviously, no warranties, you use it at your own risk, etc.

License: Ms-Pl

kick it on DotNetKicks.com

Site Meter