Archive

Archive for the ‘ASP.NET’ Category

Pro ASP.NET MVC 3 Framework

December 27, 2011 Leave a comment
December 27th, 2011 | Kevin Kershaw

Pro ASP.NET MVC 3 Framework

This is a brief review Pro ASP.NET MVC 3 Framework by Adam Freeman and Steven Sanderson. Now in its third edition this already good book continues to get better. This book provides thorough and comprehensive of MVC3 that functions well for both learning the subject and as a reference. This book includes a substantial example web site that is developed through the course of three chapters. This sample covers many aspects and issues that you would encounter developing a web site using MCV 3. Also within this sample are several interesting methods and techniques. I am selecting two that I found most interesting to explore below.

Using DI And Mock Objects To Replace DB And Repository Code

Many of the projects and features I have worked on have proceeded from the database first and then built code towards the UI. The technique below allows the UI to be developed earlier in the cycle and can facilitate prototyping the UI with a lower investment in backend code. First some infrastructure setup is needed. We will start by defining a controller factory that uses the Ninject dependency injector .

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninjectKernal;

    public NinjectControllerFactory()
    {
        ninjectKernal = new StandardKernel();
        AddBindings();
    }

    protected override IController GetControllerInstance(
        System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        return controllerType == null ? null :
             (IController)ninjectKernal.Get(controllerType);
    }
    ...
}

 

Wire this controller factory in by replacing the default controller factory in Global.asx

    protected void Application_Start()
    {
        ...
        ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
        ...
    }

This infrastructure is desirable in the project by itself. Its existence will eliminate much trivial and annoying code. The fact that it also supports the technique we are discussing is just a bonus.

We will continue by defining a DTO that will be used by the front end.

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
}

 

Next, define the repository interface that will be used by the controllers to access the data.

 

public interface IProductRepository
{
    IQueryable<Product> Products { get; }
}

Finally, we will setup a fake repository using Moq and wire it into the Ninject container. Add to the NinjectControllerFactory defined above the using the following function.

private void AddBindings()
{
    Mock<IProductRepository> mock = new Mock<IProductRepository>();
    mock.Setup(m => m.Products).Returns(new List<Product>{
        new Product{Name="Football", Price=25, Description="Standard issue ball"},
        new Product{Name="Surf board", Price=179, Description="A wave rider you will love"},
        new Product{Name="Running shoes", Price=95, Description="Move your fat butt!"}
        }.AsQueryable());
        ninjectKernal.Bind<IProductRepository>().ToConstant(mock.Object);
}

At this point you can start defining controllers and views and considering other front side issues leaving the database and repository definition for later. This allows the inverting of the more normal construction of the database and backend first, with the UI areas being developed second. Instead with a small amount of infrastructure in place, issues of UI design and actual data requirements of screens can be explored earlier.

I have used mock objects in tests, but it never occurred to me to use them as temporary filler in applications. This is a thought provoking technique in the sample code.

Using Model Binder To Access Session Data

This section of the sample code creates a model binder to allow access in the controller of data stored in the session. This has a twofold benefit, first it simplifies the controller code. Second it simplifies the testing of those controller methods.

The example application implements a shopping cart object that is stored in session. To access this shopping cart object a model binder is created. The effect is to decouple controller from session, since the controller accesses the cart via a parameter instead of directly through the session object of the http context.

First, starting with the Cart definition, the details are not important for our discussion here.

public class Cart
{
    ...
}

Next a model binder is defined .

public class CartModelBinder : IModelBinder
{
    private const string sessionKey = "Cart";

    public object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        var cart = (Cart)controllerContext.HttpContext.Session[sessionKey];
        if (cart == null)
            {
                cart = new Cart();
                controllerContext.HttpContext.Session[sessionKey] = cart;
            }
        return cart;
    }
}

Register this new binder in Global.asx.

    protected void Application_Start()
    {
        ...
        ModelBinders.Binders.Add(typeof(Cart), new CartModelBinder());
        ...
    }

 

Following is an example of a controller method that accesses the cart. Notice no references to http context and session.

[HttpPost]
public ViewResult Checkout(Cart cart, ShippingDetails shippingDetails)
{
    if (cart.Lines.Count() == 0)
    {
        ModelState.AddModelError("", "Sorry, your cart is empty!");
    }
    if (ModelState.IsValid)
    {
        processor.ProcessOrder(cart, shippingDetails);
        cart.Clear();
        return View("Completed");
    }
    return View(shippingDetails);
}

 

The implications for testability are great. For example, the following test.

[Test]
public void CannotCheckoutEmptyCart()
{
    var mock = new Mock<IOrderProcessor>();
    var cart = new Cart();
    var shippingDetails = new ShippingDetails();
    var controller = new CartController(null, mock.Object);

    var result = controller.Checkout(cart, shippingDetails);

    mock.Verify(m => m.ProcessOrder(It.IsAny<Cart>(), It.IsAny<ShippingDetails>()),
        Times.Never());
    Assert.AreEqual("", result.ViewName); //default view name
    Assert.AreEqual(false, result.ViewData.ModelState.IsValid);
}

 

Gone is the need to stub out the http context and session. I don’t want to even imagine the mocking setup that would be required to perform the above test if the Controller access the Cart object directly in Session. This is a big simplification.

Summary

Pro ASP.NET MVC 3 Framework is informative in the broad sense about the many aspects of MVC 3. I think the quality of the sample is indicative of the quality of the book. And in the details of that sample are many points of insight, two of which are discussed above.

Categories: ASP.NET Tags: , ,

The AJAX UpdatePanel Is it your worst enemy?

November 17, 2009 1 comment

November 17th 2009 | Kevin Jones

The AJAX UpdatePanel: Is it your worst enemy?

A recent code camp presentation I did sparked a debate about the “UpdatePanel” in AJAX. It’s no secret I believe it barely qualifies as real AJAX at all.

Most AJAX Frameworks have the UpdatePanel, and they are all similar in function, but I’m referring specifically to the one built into the Microsoft AJAX Framework. If you haven’t used AJAX before, it’s a useful tool to know and understand, but I wouldn’t recommend going much further than that.

The UpdatePanel is a control that simply designates its contents as an asynchronous callback, or “AJAX” call. Take a look at this ubiquitous example of updating a label with the servers time – sans a postback:

<asp:ScriptManager runat="server" ID="MyScriptMap" EnablePartialRendering="true" />
<asp:UpdatePanel runat="server" ID="TimeUpdatePanel">
    <ContentTemplate>
        <asp:Label runat="server" ID="TimeLabel" />
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="UpdateTimeButton" EventName="Click" />
    </Triggers>
</asp:UpdatePanel>
<asp:Button runat="server" ID="UpdateTimeButton" OnClick="UpdateTimeButton_Click" Text="Update Time" />

The code behind it looks like this:

protected void Page_Load(object sender, EventArgs e) {
    SetTime();
}

private void SetTime() {
    TimeLabel.Text = DateTime.Now.ToString("G");
}

protected void UpdateTimeButton_Click(object sender, EventArgs e) {
    SetTime();
}

Pretty simple. When we click the UpdateTimeButton the label updates the time with the current time, and without causing a postback. Great, right? It’s easy and requires little knowledge of advanced AJAX functionality.

Then what’s the problem?

Firstly, it’s slow and cumbersome. Secondly, it’s not very flexible. Let’s use our trusty tool – Firebug – to see what the AJAX Framework is really doing under the covers.

Here’s the post:

MyScriptMap MyScriptMap|UpdateTimeButton
UpdateTimeButton Update Time
__ASYNCPOST True
__EVENTARGUMENT
__EVENTTARGET
__EVENTVALIDATION /wEWAgLsi+LQBwLJqc+YBE5RYQbIcM8reKtnUnkQkSFh4HRl
__VIEWSTATE /wEPDwULLTE4MzQ0ODUyNDIPZBYCAgMPZBYCAgMPZBYCZg9kF

gICAQ8PFgIeBFRleHQFFDExLzgvMjAwOSA3OjEzOjEwIFBNZG

RktDZ2TbaSW4PmU5zi/+6LeFQPeOA=

According to IIS, this is about 344 bytes. That’s a lot of data to post just to get a new date. So why did we need to post so much information?

The ViewState is the biggest part of this. ASP.NET fundamentally uses the ViewState for a whole slew of reasons, but in order for ASP.NET to process the request it needs the ViewState. There is also a field called the EventValidation. It contains information that ensures the ViewState hasn’t been tampered with. Since the EventValidation goes together with the ViewState, the AJAX call needs to send this information too. The rest of the data tells the ASP.NET runtime exactly what happened: which button was clicked; the name of the ScriptManager; etc.

That’s quite a bit of information. This is what the server sent back:

55|updatePanel|TimeUpdatePanel|<span id=”TimeLabel”>11/8/2009 7:13:35 PM</span>|128|hiddenField|__VIEWSTATE|/wEPDwULLTE4M

zQ0ODUyNDIPZBYCAgMPZBYCAgMPZBYCZg9kFgICAQ8PFgI

eBFRleHQFFDExLzgvMjAwOSA3OjEzOjM1IFBNZGRkbHZ0Gxr67

EAa/bNdqZfXC6A7YPA=|48|hiddenField|__EVENTVALIDATION|

/wEWAgLUiOrpBgLJqc+YBK3kgBaC8Pr4C9SpWuCECT5qBkBH|16|

asyncPostBackControlIDs||UpdateTimeButton|0|postBackC

ontrolIDs|||16|updatePanelIDs||tTimeUpdatePanel

|0|childUpdatePanelIDs|||15|panelsToRefreshIDs||TimeUpda

tePanel|2|asyncPostBackTimeout||90|20|formAction|

|UpdatePanelTime.aspx|

Much more than just a simple date and time. ASP.NET is sending back a lot of information in the form of a single string that is delimited by pipes, and parsing it. The total size of it as IIS is 556 bytes. After the third pipe you’ll find the content of the label we were updating – HTML and all. This is the essence of the UpdatePanel. It works by sending its content to the server and the server sends back new content. The client framework then replaces the old content with the new content.

Clever enough, but it can lead to poor performance and bad design.

Is there a different way?

Yes, and though it can be a little inconvenient you gain more in the long term.

AJAX is Asynchronous JavaScript and XML. Ironically, XML is becoming the less popular means of AJAX communication. JSON (pronounced Jason) has become the primary means of AJAX based requests. JSON is easy to work with, and more compact than XML. Here is a simple example of a key and value pair.

[
    {"Key":"The Key 1","Value":"The Value 1"},
    {"Key":"The Key 2","Value":"The Value 2"}
]

In .NET, it’s fairly easy to return JSON data from a web service so long as all of the types returned can be serialized. If we were to create a simple web service that returns the date and time, we could use JavaScript to request it from the web service. The Microsoft AJAX Framework includes a framework to make this much easier than hand coding requests from JavaScript. Here is what our web service method looks like:

[WebMethod]
[ScriptMethod(UseHttpGet = false)]
public string GetDateAndTime()
{
    return DateTime.Now.ToString("G");
}

It looks like a typical web service method, but notice the addition of the ScriptMethod attribute on the method. In order to wire AJAX into a web service, additions to the web.config file are required. Visual Studio 2008 will create a new web.config file with all of the correct settings in place to get you started with AJAX.

Calling it from our client side script is very simple:

<div>
    <asp:ScriptManager runat="server" ID="MyScriptMap" EnablePartialRendering="true">
        <Services>
            <asp:ServiceReference Path="~/DataSource.asmx" />
        </Services>
    </asp:ScriptManager>
</div>
<script language="javascript" type="text/javascript">
    function updateTime() {
        var service = new Ajax4Samples.DataSource();
        service.GetDateAndTime(iHaveDateAndTime, null, null);
    }

    function iHaveDateAndTime(theTime) {
        var myTimeSpan = $get('MyTimeSpan');
        myTimeSpan.innerHTML = theTime;
    }
</script>
<span>The Server's Time is: </span>
<span id="MyTimeSpan"><%= DateTime.Now.ToString("G") %></span>
<input type="button" onclick="updateTime();" value="Update Time" />

This is a page that updates a span—MyTimeSpan—with the response from what the web service returns. We do this by adding our web service as a ServiceReference. It generates a large piece of JavaScript that allows communication with the web service. From there, a few lines of JavaScript request the data from the service. When we click Update Time, we don’t actually send any data to the server. And why should we?

The response is as simple as this:

{“d”:”11/8/2009 8:22:26 PM”}

Just a date and a time that totals 28 bytes. The “d” is a little bit of magic that the AJAX Framework itself is using. However when you consume it you needn’t worry about the “d”. The AJAX Framework includes some metadata in responses to make things easier, such as type names, to allow for a typing system.

Sure there’s a little more coding to it but it allows a greater degree of freedom and functionality with AJAX. There are other frameworks that complement the Microsoft AJAX one, including jQuery which allows for easy manipulation of the DOM and finding controls.

My conclusion: avoid the update panel at all costs. It’s cheap and easy to implement, but it’s slow and doesn’t allow adequate flexibility.

Kevin Jones is a Team Lead at Thycotic Software, an agile software services and product development company based in Washington DC. Secret Server is our flagship password management software product. On Twitter? Follow Kevin

Categories: Ajax, ASP.NET

Refactoring Code: A Programmers Challenge Part 2

April 9, 2009 2 comments

Kevin Jones: Refactoring

April 9th 2009 | Kevin Jones

Refactoring Code: A Programmer’s Challenge

In a previous blog post– Refactoring Code: A Programmer’s Challenge Part 1—we went over refactoring basics, and took a not-so-easily-tested piece of code and made it easy to test.

Our final bit of code was this:

public class DisplayPanelDecider
{
    public bool ShouldDisplayPanelOnPage(string pageName)
    {
        string[] pagesToHideElement = new[]
        {
            "/index.aspx",
            "/sitemap.aspx",
            "/404.aspx",
            "/status.aspx",
            "/online_help.aspx",
        };
        return !Array.Exists(pagesToHideElement, s => s == pageName);
    }
}

The objective of the code is clear: “Given the name of a page, should I display a panel?”

Furthermore, the code is compact and does no more or less than it should – so we can test it easily.

Some of our tests would look like this:

[TestClass]
public class DisplayPanelDeciderTests
{
    [TestMethod]
    public void ShouldDisplayThePanelIfThePageIsNotInTheExclusionList()
    {
        DisplayPanelDecider decider = new DisplayPanelDecider();
        Assert.IsTrue(decider.ShouldDisplayPanelOnPage("/foobar.aspx"));
        Assert.IsTrue(decider.ShouldDisplayPanelOnPage("/main.aspx"));
        Assert.IsTrue(decider.ShouldDisplayPanelOnPage("/blog.aspx"));
    }

    [TestMethod]
    public void ShouldNotDisplayThePanelIfThePageIsInTheExclusionList()
    {
        DisplayPanelDecider decider = new DisplayPanelDecider();
        Assert.IsFalse(decider.ShouldDisplayPanelOnPage("/index.aspx"));
        Assert.IsFalse(decider.ShouldDisplayPanelOnPage("/map.aspx"));
        Assert.IsFalse(decider.ShouldDisplayPanelOnPage("/status.aspx"));
    }
}

An interesting side note: Did you notice that the names of our tests start with the word “should?” It’s such a simple thing, but the name of tests is important. One should be able to figure out the purpose of the test by reading its name. Using the prefix “should” forces you to think about the test name.

But as we know, software requirements grow and change. What’s happened to our software developer a few months down the line? (Put on your pretend cap!)

Well, at this point, his list of pages grown considerably. Rather than the handful we have in our code, we now need to hide the panel for many pages. As an additional requirement, it now needs be configurable too, so compiled code is not the best solution.

A natural place to put configuration for now is in the appSettings section of the web.config file, and for simplicity sake, we’ll separate our pages with a semicolon, so they’ll look like this:

<configuration>
    <appSettings>
        <add
key="PagesToHidePanel"
value="/index.aspx;/map.aspx;/404.aspx;/status.aspx;/online_help.aspx"/>
    </appSettings>
</configuration>

Now, we need a class that is responsible for retrieving these page names and parsing them. Rather than throw that code in our existing class, introduce a new dependency.

The implementation I came up with looks like this:

public interface IDisplayPanelExclusionProvider
{
    string[] GetPageNames();
}

public class DisplayPanelExclusionProvider : IDisplayPanelExclusionProvider
{
    public string[] GetPageNames()
    {
        string unparsedContent =
            ConfigurationManager.AppSettings["PagesToHidePanel"];
        string[] pageNames = unparsedContent.Split(';');
        return pageNames;
    }
}

Notice I created an interface. This will have a key role later on. The next step is getting our two classes, DisplayPanelExclusionProvider and DisplayPanelDecider talking to each other.

The constructor is a simple and useful approach to dependency injection. Our goal here is to get the DisplayPanelDecider to ask the DisplayPanelExclusionProvider, “On which pages should I not display this panel?”

We’ll modify the DisplayPanelDecider to take in a IDisplayPanelExclusionProvider. Again, notice I used the interface in this example. So our class now looks like this:

public class DisplayPanelDecider
{
    private readonly IDisplayPanelExclusionProvider _displayPanelExclusionProvider;

    public DisplayPanelDecider(IDisplayPanelExclusionProvider displayPanelExclusionProvider)
    {
        _displayPanelExclusionProvider = displayPanelExclusionProvider;
    }

    public bool ShouldDisplayPanelOnPage(string pageName)
    {
        string[] pagesToHideElement = _displayPanelExclusionProvider.GetPageNames();
        return !Array.Exists(pagesToHideElement, s => s == pageName);
    }
}

Our DisplayPanelDecider now asks the IDisplayPanelExclusionProvider for a list of pages. However, by introducing our constructor, we broke our tests! The next step is to start getting our tests working again.

Important note: even though our class examples seem contrived, we are keeping decision-making logic separate. This is important from the testability aspect as well as for future maintenance. The key part here is single dependency, and that applies for our tests as well. We don’t want our tests testing multiple classes at once: keep them separate.

This is where the interface saves us: we can inject our own classes for the purpose of testing.

[TestClass]
public class DisplayPanelDeciderTests
{
    private class MockDisplayPanelExlusionProvider : IDisplayPanelExclusionProvider
    {
        public string[] GetPageNames()
        {
            return new[]
                   {
                       "/index.aspx",
                    "/map.aspx",
                    "/404.aspx",
                    "/status.aspx",
                       "/online_help.aspx"
                   };
        }
    }

    [TestMethod]
    public void ShouldDisplayThePanelIfThePageIsNotInTheExclusionList()
    {
        DisplayPanelDecider decider = new DisplayPanelDecider(new MockDisplayPanelExlusionProvider());
        Assert.IsTrue(decider.ShouldDisplayPanelOnPage("/foobar.aspx"));
        Assert.IsTrue(decider.ShouldDisplayPanelOnPage("/main.aspx"));
        Assert.IsTrue(decider.ShouldDisplayPanelOnPage("/blog.aspx"));
    }

    [TestMethod]
    public void ShouldNotDisplayThePanelIfThePageIsInTheExclusionList()
    {
        DisplayPanelDecider decider = new DisplayPanelDecider(new MockDisplayPanelExlusionProvider());
        Assert.IsFalse(decider.ShouldDisplayPanelOnPage("/index.aspx"));
        Assert.IsFalse(decider.ShouldDisplayPanelOnPage("/map.aspx"));
        Assert.IsFalse(decider.ShouldDisplayPanelOnPage("/status.aspx"));
    }
}

Note that we are injecting a fake class that allows us to implement a hand rolled mock. The single purpose of this test class is to ensure that the DisplayPanelDecider decision logic works. It isn’t the DisplayPanelDecider’s responsibility to know the real list of pages from our configuration. That should be tested somewhere else. In effect, we are testing against dummy data. When we want our class to use the real provider, we just create an instance of that and hand it in. In fact, with constructor chaining we can implement a default constructor that uses the real provider:

public DisplayPanelDecider() : this(new DisplayPanelExclusionProvider())
{
}

We have the option of using the DisplayPanelDecider with the real provider, or handing in our own – which we do for testing.

Now the thought on most people’s mind at this point is most likely “This seems like overkill.” If you stand back and look at it for all it is now, I might agree. However, maybe the programmer we’re helping finds himself with more challenging requirements. The other part is the hand rolled mock.

Rewinding a bit, in our new tests we saw a dummy class that provided fake data for the sake of testing. There are mock frameworks that remove the need for these dummy classes, but we’ll examine that in a future blog post. If you’re up for some homework, check out Rhino Mocks.

I pose this question to you: What advantages and disadvantages do you see with our approach? Is it worth the effort? I’d love to know what you think.

Kevin Jones is a Senior .NET developer and Product Team Leader at Thycotic Software Ltd. Thycotic is recognized for providing Agile TDD Training and Agile .NET Consulting Services, and its flagship password management software Secret Server. On Twitter? — > Follow Kevin

Announcement – Intro to TDD Presentation

March 24, 2009 Leave a comment

Our CEO, Jonathan Cogley, will be presenting an introduction to Test Driven Development on March 25th for the DC ALT.NET user group.  The session will focus on walking through and solving a “real world” problem by identifying and isolating the dependencies in the logic.

This is a great chance for aspiring and veteran TDD developers to touch up on the basics.

Details
Date: Wednesday, March 25
Time: 7-9pm
Location: Motley Fool, 2000 Duke Street, Alexandria, VA, 22314

The Case of the missing ASP.NET tab in IIS

July 26, 2007 Leave a comment

We recently had a problem on our development build server that had us puzzled. The ASP.NET tab disappeared and our CruiseControl.NET server quit working. We had seen the problem with CruiseControl.NET before – a serialization error on DateTime – and we knew it was related to running the dashboard in the wrong version of ASP.NET. So the two issues seemed to be related.

I finally came across a blog post today that named the cause of the issue and a fix that worked so I thought I would help spread the word in case anyone else comes across this annoying problem.

Monish Nagisetty’s Blog – VMWare Server – Missing ASP.NET tab in IIS

It appears to be related to installing VMWare Server (which we had done the day before the problem). Even though we had since uninstalled VMWare Server, the problem continued after the uninstall.

Hopefully this nugget will help another poor soul. 🙂

Jonathan Cogley is the CEO and founder of Thycotic Software, a .NET consulting company and ISV in Washington DC. Our product, Secret Server is a enterprise password manager system for teams to secure their passwords. Are you still putting your passwords into Excel?

Want a new email signature? (ShorterSigs)

February 18, 2007 4 comments

ShorterSigs is a newservice from Thycotic Software which solves the problem of communicating relevant contact information (and even your photo!) without cluttering up your email messages. This is just what every techie needs whether posting to forums, newsgroups or just a friendly chat among your peers.

Here is my public ShorterSig:
http://shortersigs.com/50454T3F7R3N

Get yours here.
http://shortersigs.com

They are secure, customizable and free.

Shortersigs is built in C#andASP.NET with a Microsoft SQL Server backend. It was also built test first and builds continuously.

Jonathan Cogley isthe CEO and founder of Thycotic Software, a .NET consulting company and ISV in Washington DC. Thycotic Secret Server is a secure web-based solution to both “Where is the password for this router?” and “Who has the password for our domain hosting?”. Secret Server isthe leader in secret management and sharing within companies and teams.

Ryan Olshan (ASP.NET MVP) joins the Thycotic team

August 30, 2006 Leave a comment

Ryan Olshan comes to us from California where his main line of work was focused on the non-profit sector. From redesigning the web presence of Pacific Wildlife Project to creating an application for tracking wayward pigeons for the 911 Pigeon Alert group, Ryan has extended his love for animals to a technological aspect. In 2006, he was awarded the Microsoft MVP award in the area of ASP.NET for his ongoing commitment to the ASP.NET community. You can catch him online on many Yahoo! Groups and the ASP.NET Forums as well as StrongTypes.com and blogs.strongcoders.com.

Ryan brings strong expertise in .NET, ASP.NET and new tools and technologies coming out of Redmond. We are excited to have Ryan onboard and look forward to the impact he will have on our practices, client work and products.

Jonathan Cogley isthe CEO and founder of Thycotic Software, a .NET consulting company and ISV in Washington DC. Thycotic has just released Thycotic Secret Server which is a secure web-based solution to both “Where is my Hotmail password?” and “Who has the password for our domain name?”. Secret Server isthe leader in secret management and sharing within companies and teams.