Hugoware

The product of a web developer with a little too much caffeine

Archive for April 2010

Goodbye Courier, Goodbye Innovation…

with 3 comments

The Courier project was canceled today. Despite all the excitement and buzz that a handful of concept art was able to generate, the Courier was abandoned without anything more than this short and uninformative explanation…

At any given time, we’re looking at new ideas, investigating, testing, incubating them. It’s in our DNA to develop new form factors and natural user interfaces to foster productivity and creativity. The Courier project is an example of this type of effort. It will be evaluated for use in future offerings, but we have no plans to build such a device at this time.

Really? Is that really how the Courier dies? Dismissed as quietly as it was introduced?

In my opinion, Microsoft really needed this to shake things up. The had simultaneously gotten the interest of students, graphic designers, businessmen and Inspector Gadget fans all with the same device!

More importantly, this showed that Microsoft could innovate truly unique experiences that were both functional and “magical”. Sure, Windows Phone 7 is cool, but it’s still Microsoft playing catch up. This was something completely different which is why I think it created the buzz that it did… not like their other recent innovations which aren’t even registering as a blip on the radar.

Recently, or more specifically today, conducted a highly scientific poll (of 4 family members) to see how the whole “brand recognition” thing was going for Apple vs. Microsoft.

I started with “Tell me everything that you know Apple makes” which they breezed through easily. The 8 and 4 year old for the most part nailed it — iPhone, iPods (Apple-Pods) and laptops. These kids don’t even own these things.

Then I asked “Tell me everything that you know Microsoft makes”. Neither of the kids could name anything. The adults stumbled through it as well but they did at least name off a few versions of Windows and a couple of the Office products – but from their perspective that was it.

Keep in mind that I’m a Microsoft developer – I own a Zune, I use Windows, I search with Bing… okay, that last one is a lie… but these people see Microsoft stuff all the time.

Of course, my family and in-laws are hardly representative of a larger, growing consumer base, right?

Oh…

To be clear, I’m a big fan of Microsoft, in fact some day I hope I’ll be working for them… but today I’m dumbfounded by their decision. Microsoft needed this…

Goodbye Courier, goodbye innovation…

Written by hugoware

April 29, 2010 at 10:20 pm

100th Blog Post and Hugoware Podcast #1

with 2 comments

Today is my 100th blog post and the end of my first year of blogging so I thought I’d do something a little different.

Each Monday I lead a small programming group/class where we talk about… well… just whatever. One of people in the group is Keagan Williams, who is a high school student, recently competed in a regional programming competition. He and the rest of his team took first place.

Keagan works in a variety of languages and has written some apps for the Android app store, some of which have thousands of downloads.

I’d love to take some credit for how good this kid is but I really can’t.

Anyways, we talked with Keagan for a bit about what the competition was like and some of the things he did. Interesting to hear some of the stuff the upcoming talent is working on.

Download Hugoware Podcast: #1

Written by hugoware

April 26, 2010 at 11:25 pm

Using A Page Control For MVC Templating

with 2 comments

In previous posts I’ve talked about using WebControls along with ControlAdapters to have cleaner markup by using the built in ASP.NET page life cycle to assign values to the correct elements on the page. This approach can make views easier to read by removing server side code blocks and allowing logic to be handled within the code behind of the view and not within the page itself.

This post continues the discussion by looking at how you can use a Controller to create instances of views before rendering them to the page.

In previous examples, I used the View method as you normally would in MVC. This worked well enough – We had access to the Model property and the ViewData which gave us enough information to render our page.

However, this example approaches the same problem but a little differently. Instead, we are going to create the view and assign to the properties immediately and then render the content for the view. Below is some code that illustrates the idea.

//Keep in mind, this is sample code and needs more work
//before you plug it into a project but it should give a 
//general idea of how this could work.

using System;
using System.Web;
using System.Web.Compilation;
using System.Web.Mvc;

namespace MvcTemplating.Controllers {

    public class SampleController : Controller {

        /// <summary>
        /// Creates a new instance of a view 
        /// </summary>
        public T CreateView<T>(string path) where T : class {
            return BuildManager.CreateInstanceFromVirtualPath(path, typeof(T)) as T;
        }

        /// <summary>
        /// Renders a handler to the page
        /// </summary>
        public ActionResult Handler(IHttpHandler handler) {

            //update and process the handler
            this.HttpContext.Handler = handler;
            this.HttpContext.Handler.ProcessRequest(System.Web.HttpContext.Current);

            //quit handling this request
            this.Response.End();
            return null;
        }

    }

}

The Handler function takes care of performing the work for the view and then returns a null since the action is still going to be wanting a return value. If you know a better way to handle this please let me know. 🙂

Instead of reading values from the ViewData or the Model we can now just assign them directly to the view.

namespace MvcTemplating.Controllers {

    [HandleError]
    public class HomeController : Controller {

        //displays content using an instance of the view
        public ActionResult Index() {

            //create the view
            var view = this.CreateView<MvcTemplating.Views.Home.Index>("~/Views/Home/Index.aspx");

            //assign to properties
            view.LatestBlogPosts = BlogPosts.Recent(5);
            view.LatestTweet = TweetRepository.GetLatest();
            view.Title = "Welcome Visitor!";

            //and then show the view
            return this.Handler(view);
            
        }
 
    }

}

This sample requires we know the path to the view but that can be fixed by using standard path names or possibly scanning the site in advance and saving the paths in memory (which is something I’ve done before with UserControls)

This approach, combined with ControlAdapters, can result in clean markup and provide additional logical functionality for some of the more complex views in your existing MVC projects.

Of course, this is just “proof of concept” stuff… I’ll hopefully have more code to share before long.

Written by hugoware

April 25, 2010 at 11:00 pm

Work Sequences Using Lambdas

with 2 comments

Occasionally I’ll run into some code that I want to “undo” in case the entire thing doesn’t go as planned. Normally placing this code into a separate class and then performing each work item one at a time works pretty well. You have to keep track of your progress so you know where to rollback from but overall it isn’t a very complicated process.

I had pretty much the same scenario the other day, but this time I thought I’d approach it a little differently. Instead of writing the sequence management into the class I was using I decided to see if I could come up with the same concept using lambdas instead.

[Download Source Code: WorkSequence.cs] : Hosted on gist.github.

The idea is to make some reusable code that can be used within a class to handle sequences of code. Let’s look at a sample of how you might use this code – We’re going to pretend this code is part of a class responsible for moving some data around. If one transfer fails then all of the work should be reverted.

string path = Path.Combine(@"\\server\share\", this.FileName);

//creating a default sequence
WorkSequence work = new WorkSequence();

//when a rollback takes place
work.Error += (sequence, item, index) => {
    string name = item.GetPerformMethod().Name;
    Console.WriteLine("Failed item {0}", name);
};

//when the work finished
work.Complete += (sequence) => {
    Console.WriteLine("Finished work!");
};

//1. calling a method without a rollback step
work.Add(this.GenerateLibrary);

//2. calling a method that has an undo step
work.Add(this.CreatePackage, this.RemoveTempCacheFile);

//3. calling methods that have arguments
work.Add(() => this.Transfer(path), () => File.Delete(path));

//4. calling a method using different credentials
work.Add(this.Archive, new ImpersonationContext("domain\\name", "passw0rd"));

//5. starts executing the work
work.Perform();

//6. or an async call
work.PerformAsync((sequence) => {
    Console.WriteLine("Finished in sequence");
});

The general idea for this code is to set the work that you need to do and then an optional ‘rollback’ option in case there is a problem. You’ll notice that none of the methods accept arguments. Instead, you can provide an action that invokes the action and then provides the arguments (in #3).

As each item is fired an index is used to keep track of the position in the sequence. That way, if there is an error, only the work that has actually executed will have the rollback method fired.

You’ll also notice that I’m using the code I recently published so you can provide credentials to use for impersonation. This can be per method or applied as a ‘default’ for the entire sequence.

Finally, you can either invoke the process and wait for all of the work to complete or fire it up in an asynchronously. You can provide a callback method or assign an event to fire off once the work has completed.

Not sure if there is a built in class to handle this kind of work but I’ve found it useful so far – Enjoy!

Written by hugoware

April 19, 2010 at 11:29 pm

Using Code Behinds For MVC Templates

with 2 comments

I’ve done quite a few posts about using WebControls in MVC mostly as experiments to see if it was possible to bring WebForm functionality into a MVC application. It wasn’t really that I wanted to use WebForms in MVC but rather I still really like Controls having logical functionality. Sometimes a View is a little more complicated than simply inserting a value into the correct location on the page.

In my last blog post I gave an example that seemed impossible to do all within the render phase of the page but was easy to accomplish with a few WebControls. My controls didn’t have to dump out horrible markup or use the ViewState – They we’re simple and easy to use controls the rendered exactly the content I wanted to display.

So I’ve been working on a templating framework for MVC that can fit into an existing project without needing to start over that makes use of CSS Friendly Control Adapters – Remember those things?

Here is an example – (this is just some demo code and is missing some parts)

using System;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.Adapters;

namespace MvcControlAdapters {

    /// <summary>
    /// Handles rendering controls to the page without IDs 
    /// and ensuring that DataBinding takes place on the page
    /// </summary>
    public class MvcControlAdapters : ControlAdapter {

        //perform data binding for the control
        protected override void OnLoad(EventArgs e) {
            (this.Control.Parent ?? this.Control).DataBind();
            base.OnLoad(e);
        }

        //create the HTML output for this control
        protected override void Render(HtmlTextWriter writer) {

            //clear this ID from view
            this.Control.ID = null;

            //check for an 'actualId'
            AttributeCollection attributes = this._GetAttributes();
            if (attributes is AttributeCollection) {
                attributes["id"] = attributes["_id"] ?? null;
                attributes.Remove("_id");
            }

            //perform normal rendering
            base.Render(writer);

        }

        //finds the attributes for a control (if any)
        private AttributeCollection _GetAttributes() {
            PropertyInfo property = this.Control.GetType().GetProperty("Attributes");
            return property is PropertyInfo
                ? property.GetValue(this.Control, null) as AttributeCollection
                : null;
        }

    }

}

Don’t compile and run just yet – You need to also add this XML to a new Browser File in your App_Browsers folder.

<browsers>
    <browser refID="Default">
        <controlAdapters>
            <adapter controlType="System.Web.UI.HtmlControls.HtmlControl" 
                adapterType="MvcWebControls.MvcControlAdapter" />
            <adapter controlType="System.Web.UI.Control" 
                adapterType="MvcWebControls.MvcControlAdapter" />
            <!-- snip... -->
        </controlAdapters>
    </browser>
</browsers>

The general idea behind this code is to attach an adapter onto any WebControl on the page and then either remove or replace the ID property with the correct value. This allows for the element to be referenced from the code behind but prevents the excessive ID from being displayed.

Keep in mind this is just a sample and won’t work exactly the way you’d like (for example, this doesn’t do anything about ‘name’ attributes on input tags).

In order to use this code we’re going to want to add a ViewPage that has a code behind that we can work with. You could add a script marked as runat=server at the top of the page but I don’t recommend it (which I’ll explain more of in a moment).

So here is a sample of what a page would look like now…

<%@ Page Language="C#" 
    CodeBehind="Index.aspx.cs" 
    Inherits="MvcAdapters.Views.Home.Index"  %>

<html>
    <body>
        <h1 runat="server" id="section" />
        <div runat="server" id="description" _id="desc" />
        <a runat="server" id="link" title="Check out the products!" >Learn More!</a>
    </body>
</html>

And then the code behind…

using System;
using System.Web.Mvc;
using MvcAdapters.Models;

namespace MvcAdapters.Views.Home {
    
    //the view for the page - STILL uses a Model
    public partial class Index : ViewPage<Product> {

        //prepare the content for the page
        protected override void OnLoad(EventArgs e) {

            this.section.InnerText = this.Model.Name;
            this.description.InnerHtml = this.Model.Description;
            this.link.HRef = this.Url.Action("Details", "Products", new { id = this.Model.ID });

        }

    }

}

And is finally rendered as…

<html> 
    <body> 
        <h1>Cheese Crackers &lt;3</h1> 
        <div id="desc">The best cheese crackers <strong>you've ever tasted</strong> - GUARANTEED!</div> 
        <a href="/Products/Details/18924" title="Check out the products!">Learn More!</a> 
    </body> 
</html> 

Which means we can assign the values for the model to the correct element on the page. We use properties like InnerText which will save us from calling Html.Encode or make logical changes to styles and attributes for elements without a mess of server side code blocks.

This might seem like an excessive amount of setup to populate content onto a page but it does have its advantages.

  1. Refactoring is easier – If a model is changed then the modification can be easily pushed into the rest of the project without requiring you to dig though server code blocks. (yes, you have precompilation but you’re still the one who has to change them.)
  2. View logic is cleaner – It is easier to write code to handle View logic outside of the view itself. For example, using a Visible property instead of an if-then statement wrapping HTML elements.

Of course, this might not make sense for every View, but the nice thing about this approach is that is works without needing to make a lot of changes to a project. This might make more sense in larger more complex views. Fortunately, an approach like this doesn’t require that you File->New Project to get it started.

Anyways, I’m still trying to decide what makes the most sense in this project so I’ll post more code as it moves along. Enjoy!

Written by hugoware

April 15, 2010 at 12:46 am

Adding Stylesheets, Scripts In ASP.NET MVC2

with 9 comments

A while back I worked on some code that allowed you to add content to different areas of a MVC view, specifically for dealing with headers and scripts. The code worked well enough but relied on a lesser used member in the Reponse class – the Filter property.

Except, now in MVC2 you see this little message when you try to mess with the Filter…

Filtering is not allowed? What? Why not?!?

Admittedly, the original solution was rather hackish because it tried to perform all of the work in the Render phase of the page life cycle and then update the correct content areas in a custom stream that as assigned to the Filter property. You could only pass content as a string value so it mean’t a lot of ugly escaping of characters instead of simply writing normal HTML.

Lately, I’ve been working on another personal project related to templating MVC pages. I won’t give away too much for now but let’s just say that I think that Web Controls still have great potential. Sometimes a page layout takes a couple passes to ensure everything is where it needs to be which is something that the page life cycle handles for you.

Let’s look at another example that uses Web Controls to update content in different parts of the page.

[Download Source Code: ContentArea / ContentDisplayArea] – Remember, I’m posting code on github.com and specifically using gist – If you aren’t using it then you might want to check it out! I hacked out this code this evening so if you discover bugs then feel free to report them to me. (and considering the developer who wrote it, you probably will) 🙂

After you’ve added the code to your project you’re going to have to add a reference to the controls by adding an entry to your web.config. It will look something like the example below.

<?xml version="1.0"?>
<configuration>
    <!-- Snip... -->
    <system.web>
        <pages>
            <controls>
                <!-- Snip... -->
                <add tagPrefix="mvc" namespace="MvcWebControls" assembly="YourProjectName" />
            </controls>
        </pages>
    </system.web>
</configuration>

So, now you have the controls added let’s pretend we have a view that looks like the example below and we want to add a few stylesheets to it.

[View.aspx]

<% @Page ... %>
<html>
    <head>
        <title>My Mvc Application</title>

        <!-- Consumes the content of areas with a target named 'header' -->
        <mvc:ContentDisplayArea ID="header" runat="server" />

    </head>
    <body>
        <% this.Html.RenderPartial("SomeControl.ascx"); %>
    </body>
</html>

And then in our partial control we use a ContentArea to add content to the header.

[SomeControl.ascx]

<% @Control ... %>

<mvc:ContentArea runat="server" Target="header" >
    <link rel="stylesheet" src="<% =this.Url.Content("~/resources/somecontrol.css") %>" />
</mvc:ContentArea>

<div class="control-container" >
    Hello World... uh... nevermind...
</div>

An just like that our content appears in the header of our page! Excellent!

How does it work? Some sort of magic? Maybe a fancy, super technical programming trick?

… or maybe it just uses the existing ASP.net functionality to track controls, render content and then move them to the correct containers by linking into different phases of the page life cycle. Not exactly ‘magical’ and somewhat anti-climatic but definitely reminds us that while MVC is the new hawtness it still is ASP.NET.

Anyways, in the next few weeks I’ll share more about my thoughts for alternative ways to create views in MVC and my new templating project… but for now try out the code and enjoy!

Written by hugoware

April 6, 2010 at 10:48 pm

Making UserControls And Namespaces Work

with 2 comments

Adding UserControls inside of a Web Application project can tend to be a pain. You either have to register the control on each of the pages you want to use them in or add each name and path into the system.web/pages/controls section of your web.config. Neither of these are very convenient.

However, there is another option – Namespaces. Simply add an entry in the same location with values for the namespace, tagPrefix and assembly values and your control becomes ‘available’!

<configuration>
    <!-- snip -->
    <system.web>
        <pages>
            <controls>
                <!-- the assembly should be the same name as the 
                name generated by the application -->
                <add tagPrefix="site" namespace="WebApp.Controls" assembly="WebApp" />
            </controls>
        </pages>
    </system.web>
</configuration>

Now, everything appears like it is ready to go. If you start to type in your control name then you’ll see it pop up in the intellisense. However, if you run you application the control won’t appear!

If you pay close attention to the AppRelativeVirtualPath you’ll notice it stays null the whole time! To make matters worse is that even if you set the value manually it doesn’t make a difference – nothing shows up. You can try the Register information to add the control the page and you’ll see that the inline control works fine. It appears that you need that ‘src’ attribute before this works.

At this point we could give up and move on or we could get a little creative in our solution.

[Source Code] Normally, I’d drop a giant block of code in my post right here but from now on I’m going to start using github for my snippets. You can download the whole snippet at gist on github.

So to summarize our situation…

  • UserControls ‘work’ when added by namespace but they don’t actually appear in the page. (technically, the code still runs it just doesn’t show the .ascx content)
  • We can add UserControls to each page using the Register option but it isn’t nearly as convenient as the namespace.
  • We could add each UserControl to the web.config with the virtual path but it would require we update the web.config every time we change something.

I’ve wrestled with this a lot – I’ve tried the precompilation, I’ve tried ILMerge… I even tried kicking my laptop (which admittedly seemed to improve my code… too weird) – nothing seemed to work unless the virtual path to the ascx file was available. So instead of trying to solve the problem at build time I opted to solve it as soon as the program starts. Below is the code that I add to the Application_Start event in my Global.ascx file.

protected void Application_Start(object sender, EventArgs e) {
    UserControlScanner scanner = new UserControlScanner();
    scanner.ScanAndUpdate();
}

This code starts by finding all of the .ascx files in your site and all of the UserControl types (and sub types) loaded into the assemblies. It then uses this information to compare against the web.config file and add each control to the controls section.

What does it compare against? Well – first, it assumes that you added the namespace to your web.config file to begin with (otherwise, how else are you using it?) If the code finds a match between the UserControl namespace and a namespace in the web.config then it is added. It is worth noting that the prefix is determined by the the tagPrefix of the web.config entry of the matching namespace.

So below is a good example of what to expect.

<!-- Before code executes -->
<controls>
    <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions (snip)..." />
    <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions (snip)..." />
    <add tagPrefix="site" namespace="WebApp.Controls" assembly="WebApp" />
</controls>

<!--After code executes-->
<controls>
    <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions (snip)..." />
    <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions (snip)..." />
    <add tagPrefix="site" namespace="WebApp.Controls" assembly="WebApp" />
    <add tagPrefix="site" tagName="MyControl" src="~/Controls/MyControl.ascx" />
    <add tagPrefix="site" tagName="SomeOtherControl" src="~/Controls/SomeOtherControl.ascx" />
</controls>

Now, this does cause a bit of a problem… the site just loaded and the web.config just changed – Our updates aren’t available! To remedy that you’ll find this bit of code right after it finishes saving the changes.

//get the path to redirect to
string url = HttpContext.Current.Request.Url.AbsolutePath;

//then reset the system
HttpRuntime.UnloadAppDomain();

//and redirect the request to start over
HttpContext.Current.Response.Redirect(url);

So, if any changes are found then the site is reset and the user is redirected to the same requested the originally attempted to reach. Doesn’t seem like a big issue to me but it is something you want to keep in mind. Of course, if no changes are detected then the site isn’t reset and the code runs normally.

Now, if you add or remove controls, change paths then your web.config is automatically kept up to date and your application runs normally!

Written by hugoware

April 4, 2010 at 10:17 pm