May 2011 - Posts - Jon Galloway

May 2011 - Posts

Dynamic ASP.NET MVC 3 models using Mono’s Compiler as a Service

I had an idea for an interactive MVC sample which will let you see the scaffolded editor and display for a model. I thought about a few ways to do this, the first being Mono’s compiler as a service. So far it’s a partial success – the model scaffolding works, but the attributes don’t (very possibly my mistake).

Getting the latest Mono Compiler

Miguel recommended that I grab the latest Mono build off Github, since there have been some improvements and bug fixes in the compiler. He wasn’t kidding, there’s a lot of active work going on in the compiler, and the Evaluator class (the main compiler service class) is no exception. Here’s the commit history just for the Evaluator (eval.cs):

https://github.com/mono/mono/commits/871ad48b98346cffc194b6ebe458a93d88dba009/mcs/mcs/eval.cs

A quick skim of the mcs (mono csharp compiler) commit messages in general shows a lot of work going on, including work on async: https://github.com/mono/mono/tree/master/mcs/mcs

The biggest change since the last Mono release, as Miguel blogged about in February, is the change from static API to an instance API:

…we turned the static API Evalutor.Eval (string expression), into an instance API. The instance API allows developers that are embedding the C# compiler-as-a-service in their application to have different contexts.

This required the entire compiler to be updated from being a giant set of static classes that could safely use global variables and state into a state that was properly encapsulated.

The API is now richer, we provide a way to configure the compiler settings using a settings class. This can be populated either manually, or by using the build-in command-line parser for compiler options.

This is good news – I find the new API easier to work with. The magical static stateful service API pattern works great for the REPL sample but causes problems if you’re doing anything much more complex. The downside, though, is that just about all the code samples and blog posts on the the Mono compiler service stuff don’t work as-is against the new compiler.

I didn’t want to set up a build environment for Mono. Fortunately, most established open source projects offer regular builds if you look around a bit. I grabbed the most recent MonoCharge package from http://mono.ximian.com/daily/, which includes all the precompiled binaries. They’re packaged as a .tar.gz, which opens up just fine in 7-zip. I just grabbed the Mono.CSharp.dll assembly.

2011-05-20 22h14_44

Using the Mono Compiler Service in an application

It’s pretty easy to put use the compiler in an app:

  1. Reference Mono.CSharp.dll
  2. Add a using statement for Mono.CSharp
  3. New up an Evaluator and get to work:
var report = new Report(new ConsoleReportPrinter());
var evaluator = new Evaluator(new CompilerSettings(), report);
evaluator.Run("DateTime.Now");

The evaluator constructor requires a ConsoleReportPrinter and CompilerSettings, neither of which we care about, so we’re just passing them in to make everyone happy. Are you happy? Me, too. Onward!

Using Mono Compiler in an ASP.NET MVC Application

ASP.NET MVC 3 views are typed as ViewPage<dynamic> and the Html.EditorForModel scaffolding stuff works via reflection, so theoretically we could create a new model on the fly and lob it over to the view and things should just work, right? Let’s see.

First, we’ll create the controller that builds a dynamic class. I’m throwing in a property with a dynamic name just to make it clear that this entire model is coming from a string.

using System.IO;
using System.Reflection;
using System.Web.Mvc;
using Mono.CSharp;
using System;

namespace DynamicModelCompilation.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            string modelDefinition =
            @"
              public class Monkey
              {
                    public string Name { get; set; }
                    public string Password { get; set; }
                    public bool IsHappy { get; set; }
                    public bool GetsDownOn" 
                        + DateTime.Now.DayOfWeek + 
                    @" { get; set; }
                }
            ";

            var report = new Report(new ConsoleReportPrinter());
            var evaluator = new Evaluator(new CompilerSettings(), report);
            evaluator.Run(modelDefinition);
            dynamic model = evaluator.Evaluate("new Monkey();");

            return View(model);
        }
    }
}

The above code:

  1. Builds a string which we’ll be passing to the compiler
  2. Creates a compiler (as we saw earlier)
  3. Calls Evaluator.Run, which executes the code string passed to it
  4. Calls Evaluator.Evaluate on “new Monkey()” which news up an instance of our model and returns it

Next, we’ll set up a simple Index view that displays an editor template for based on whatever model object is passed to it:

@{
    ViewBag.Title = "Home Page";
}
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.")

    <fieldset>
        @Html.EditorForModel()
    </fieldset>
    <input type="submit" value="Processinate Form" />
}

Running the application show that our nefarious plan has succeeded:

2011-05-21 01h51_12

Pushing Our Luck – Trying Out Some Attributes

A lot of the goodness in the MVC templates comes from the way the helpers work with data annotations. You can set display names for properties (e.g. changing the display label for IsHappy to "Is this monkey happy?"), setting validation requirements for edit forms, etc. I took a shot at adding those in to the model class.

First off, I needed to include a reference to the System.ComponentModel.DataAnnotations assembly in my Mono Evaluator session. That's easy enough to do with a call to LoadAssembly, presuming you have the full path to the assembly. I copied System.ComponentModel.DataAnnotations to my /lib file and referenced it like this:

System.Uri uri = new System.Uri(Assembly.GetExecutingAssembly().CodeBase);
string path = Path.GetDirectoryName(uri.LocalPath).Replace("\\DynamicModelCompilation\\bin", "\\lib");
evaluator.LoadAssembly(Path.Combine(path, "System.ComponentModel.DataAnnotations.dll"));

That adds the reference to the compiler session, but you still need to run a using statement, like this:

evaluator.Run("using System.ComponentModel.DataAnnotations;");

Finally, I added some annotations to my model:

public class Monkey
{
	[Required]
	[StringLength(3, ErrorMessage = ""The {0} must be at least {2} characters long."", MinimumLength = 1)]
	public string Name { get; set; }

	[Required]
	[DataType(DataType.Password)]
	public string Password { get; set; }
	
	[Display(Name = ""Is this monkey happy?"")]
	public bool IsHappy { get; set; }
}

Note: if you get any of those things wrong, you get a slightly cryptic exception on your call to evaluator.Evaluate() - Argument Exception: The expression did not set a result.

Here's how the entire controller looks:

Unfortunately, the attributes didn't have any effect. It's not like anything broke, but the form looked the exact same:

2011-05-21 01h51_12

I dug into the model properties using model.GetType().GetProperties() - it looks like they're present, but maybe there's something about them that ASP.NET MVC finds repugnant? Spelunking through the model properties' custom attributes shows that they are indeed present.

The end? We'll see - I'll ask / poke around and see why the attributes aren't being picked up.

References / more info on using the Mono compiler as a service:

http://docs.go-mono.com/Mono.CSharp.Evaluator.Compile%20(string)

http://docs.go-mono.com/Mono.CSharp.Evaluator.Evaluate%20(string)

http://docs.go-mono.com/Mono.CSharp.Evaluator.Run%20(string)

http://www.amazedsaint.com/2010/09/how-to-host-monos-csharp-compiler-in.html

http://tirania.org/blog/archive/2011/Feb-24.html

Posted by Jon Galloway | 10 comment(s)
Filed under: , ,

Tips for avoiding e-mail disasters

There's something about hitting the send button on an e-mail that remind me of some important detail, such as:

  • That I didn't intend to Reply All
  • That there were other related, important details to add
  • The need to spell check / proofread / add facts / otherwise try not to look stupid
  • The consideration that maybe this e-mail might be better unsent

If you've ever done this, you've possibly tried to recall the message, which does nothing but draw attention to the e-mail and get you laughed at. I use Outlook for work and Gmail for everything else; here are a few tips for avoiding e-mail disasters on both.

Outlook - Defer Send Rule

If you're using Outlook, that's very easy to do using a rule. In Outlook 2010, you can create a rule using the File / Info view, then clicking on Manage Rules & Alerts.

2011-05-09 15h47_45

Click on New Rule:

2011-05-09 15h50_06

Next, click on "Apply Rule on messages I send"

2011-05-09 15h51_39

On the next dialog, you'll be asked which conditions you want to check. Just click Next, as we want the rule to apply to all outgoing mail.

On the following dialog, you're asked what you want to do. Check the "defer delivery a  number of minutes," then click the link in the Step 2 area and select the number of minutes to delay outgoing messages. The default, 1 minute, works pretty well for me.

2011-05-09 15h54_38

You may want to set some exceptions for this rule. In my case, I've said that I want all High Importance e-mails to be delivered immediately. I know some other folks include other exceptions for words in the text body or certain recipients, but with a short delay I don't find that I need to do that.

2011-05-09 15h55_07

Finally, just name the rule and press Finish to close the wizard.

2011-05-09 15h55_35

Gmail options

Gmail's filters are really useful for sorting inbound mail, but doesn't have as much in the way of handling outbound mail. I've seen a few options that offer a little help here, but aren't quite as configurable. Let me know if you've got better suggestions.

Gmail Labs - Undo Send

The Undo Send labs project is easy to set up and use:

2011-05-20 14h27_05

The problem is that it only gives you 5-10 seconds after sending to cancel, which isn't enough time for me. I've got it enabled, but haven't ever used it.

Boomerang

Boomerang for Gmail has options for delaying and scheduling e-mails you send, but the shortest you can delay for is 1 hour, unless you want to specify exact times for each e-mail you send.

2011-05-20 12h05_52

It's probably handy for other things, but not a real solution.

Mail Goggles

Mail Goggles is interesting to mention in passing. It's another GMail Labs project which requires you to solve some math problems before sending during certain hours. It might be effective in preventing drunk / ill advised late-night e-mails, but I don't think this would help with general "oops" e-mail problems, because you'd be too busy solving math problems to think about the e-mail you just sent. You might get better at arithmetic, though.

There's a thread on the support forums asking if better delay send options will be implemented: http://www.google.com/support/forum/p/gmail/thread?tid=1bfdef93eec31a9e&hl=en

Forgotten Attachment Detector

One of the most common faux pas email moments is forgetting to include an attachment you said you were sending. I actually looked into doing this via Outlook rule, but it didn't work for me. Here's the rule I tried:

2011-05-20 14h35_16

Unfortunately, that didn't work - messages would appear to be sitting in the Drafts folder, but would still be sent. A better solution is to just to use the Forgotten Attachment Detector from OfficeLabs.

This add-in does one thing, and does it really well.

Add the addresses last

This actually works best for me. When I'm writing an important e-mail, I don't add the e-mail addresses until after I've proofread it. If I'm replying to a thread, I'll cut the To / CC lines and paste them into the top of the e-mail, then move them back when I'm ready. Adding that manual step reminds me to think before sending.

What works for you?

Posted by Jon Galloway | with no comments
Filed under:

Copying Windows Live Writer accounts to another computer

I'm setting up a new laptop and needed to copy my Windows Live Writer accounts over. I've run through the Writer "add a blog" wizard so many times over the years and always wondered if there were a less tedious way to add all my blog settings at once. I first looked at an Import and Export Wizard for Windows Live Writer program, but it didn't seem to work. It turns out that it's pretty simple to do this manually using a registry file.

Export / Import the settings

First, export a registry file which contains your Live Writer accounts. You can do using regedit by navigating to "HKEY_CURRENT_USER\Software\Microsoft\Windows Live\Writer" and exporting the key, or you can do this from the command line, like this:


C:\Users\Jon>reg export "HKEY_CURRENT_USER\Software\Microsoft\Windows Live\Writer" "%userprofile%\desktop\blog-settings.reg" 
The operation completed successfully.

This will dump a registry file on your desktop. Copy this registry file over to the new computer and double-click on it to install it.

Updating passwords

Your password is encrypted in the registry settings, so it won't copy over. That's a good thing - you wouldn't want someone to be able to steal your blog account passwords by snooping through your registry. This works pretty smoothly, though, because the first time you try to use the account on the new computer, it'll prompt you to re-enter the password, and you're all set.

Looking up your old passwords

If you've any of your LiveWriter account passwords, it turns out that you can easily retrieve them using a the LiveWriter API. Javier Lozano had written this up a few years ago, and a commenter had posted an update that works with the current version of the Live Writer API.

Miscellany

  • I use Live Mesh to keep drafts and recent posts in sync across my work computer and laptop by syncing My Documents\My Weblog Posts. I'm sure this can be done using Dropbox (and that the Dropbox faithful will tell me about it in the comments).
  • This blog is on weblogs.asp.net, which requires some trickery to get WLW configured. For my future reference, you can set it up as a Community Server blog, but the metablog endpoint is at http://weblogs.asp.net/metablog.ashx
  • I don't bother with the style detection stuff anymore, but if you do be sure to delete the Temporary Post Used For Style Detection post if it doesn't get deleted.
Posted by Jon Galloway | with no comments

MVC Music Store Updates - MVC 3 Tools Update Features, Scaffolding, Save Points, VB.NET Code

Summary

The latest drop of the Mvc Music Store tutorial cover the ASP.NET MVC 3 Tools Update, Scaffolding, Entity Framework Code First, SQL Server CE, and more. Additionally, this drop includes a VB.NET translation of the finished project as well as save points how the code should look when you complete each section.

What's in the ASP.NET MVC 3 Tools Update

The ASP.NET MVC 3 Tools Update doesn't change anything in the ASP.NET MVC 3 runtime. If you've got the ASP.NET MVC 3 RTM (as released January 13) installed and I've got the ASP.NET MVC 3 Tools Update installed, we can both happily work against and deploy the same code without any issues at all. As the name (hopefully) suggests, this update really includes two main changes:

  • Updates to MVC 3 related project and file templates which include things like HTML 5 specific elements, updated JavaScript references included as NuGet packages, and an additional assembly reference for Entity Framework support. These template changes make it easier to leverage the new features in a new project, but you can easily take advantage of these features in your existing ASP.NET MVC 3 projects.
  • Updated Visual Studio tooling to take advantage of the above features. An obvious example is the new controller dialog, which takes advantage of the new MvcScaffolding package to generate views for the default actions as well.

For more information about the ASP.NET MVC 3 Tools Update, see Scott Guthrie's post (and the included links).

Where to get the updated tutorial

As always, you can download the latest release of the Mvc Music Store tutorial - PDF document and code - from http://mvcmusicstore.codeplex.com. You can also read the content online starting at http://www.asp.net/mvc/tutorials/mvc-music-store-part-1

New Feature: VB.NET Code

This release includes a translation of the the completed project code to VB.NET (thanks, Lisa Feigenbaum and team!). We've had a lot of VB.NET developers follow the tutorial in the past, converting each step to VB.NET as they went. Hopefully having a working sample of the completed project in VB.NET will make that a lot easier. VB.NET dev's, I'd be happy for any feedback on this!

Note: One thing that was interesting to me here - as a dev who started with VB "classic" a long time ago but transitioned to C# when I started .NET development - was the difference in how namespaces are handled and used in VB.NET vs. C#. We matched the namespacing style for VB.NET project and item templates, so the finished code should look as it would if you followed the tutorial steps starting with File / New / VB / Empty ASP.NET MVC 3 Application.

New Feature: Save Points

I always make several runs through the tutorial each time I update it to make sure the code is accurate, compiles at each step, etc. I've been capturing save points as I complete each chapter for my own sanity and efficiency, and for this release I'm publishing those as well. There's an optional zip download that includes a separate copy of the application as it looks at the completion of each major chapter. Since the first chapter is an overview of the install and file / new project experience, the snapshots start at Chapter 2:

2011-05-12 16h01_54

I anticipate this will be useful for (at least) two scenarios:

  • If you are having trouble with a section, you can grab the working code for the nearest chapter save point and compare against your code
  • This makes it easier to skip sections, jump in from a previous release of the tutorial, join at any point, use individual chapters in a lab or class environment, etc.

Changes related to the MVC 3 Tools Update

I published another big update for the MVC Music Store tutorial during MIX11 to coincide with the ASP.NET MVC 3 Tools Update release. It was a pretty major rewrite, so I published it as a Beta. Since then I've corrected and clarified a few things in the tutorial document (no code changes) and upgraded to a stable release.

The biggest changes to the tutorial were:

  • Converting the Store Manager (Admin) section to use the new scaffolding system
  • Switching data access to use SQL Server CE and Entity Framework Code First
  • Explaining software prerequisites and installation

Changing the Store Manager to use Scaffolding

This section of the tutorial focuses on building out admin create/read/update/delete support for the albums carried in the music store. Previously, the tutorial had you create the controller, write the required code, and manually create each view. The new update leverages the scaffolding system to generate the majority of this code via scaffolding, then explains how the generated code works. The end result is basically identical, but since I removed a lot of repetitive, manual steps (now add another view, following the same steps as the previous ones, but naming this one Edit...), I was able to add a lot more explanatory material and still drop the page count by about 20 pages.

I think the end result is good here:

  • The code is as good - frankly, in some ways, the generated code is a little better
  • I don't think we really lost any useful learning opportunities, since a lot of the code that was being typed in previous tutorials was repetitive
  • There was more opportunity to explain what the code was doing and why
  • By learning about scaffolding, the transition to leveraging some more advanced patterns - like using repositories - is simpler, since the MvcScaffolding package includes a repository-based scaffolder

Switching data access to use SQL Server CE

A large percentage of the support issues for previous releases have been due to data access. Like many .NET developers, I have a love / hate / really hate relationship with SQL Server Express. It's one of those technologies that either works transparently, or doesn't work for some bizarre reason that's really painful to troubleshoot. It was heartbreaking to try to help developers through previous versions of the tutorial at Web Camp events who couldn't get SQL Server Express running on their laptop for some reason or another. It generally works pretty well for me, but there are times where it's given me problems, as well. SQL Server Compact provides a much simpler getting started experience, where you just want your data to be persisted without troubleshooting service permissions and installation issues.

The tutorial materials still include an MDF file and SQL Scripts in case you want to use SQL Server Express or a dedicated SQL Server instance, but I think the SQL Server Compact experience should work a lot better for most people.

Explaining software prerequisites and installation

This tutorial includes more information up-front about what you need installed and how to get it. Again, some of this is based on user questions and issues from the forums, in person, etc. The first chapter now includes information about how to install the required software - either via Web Platform Installer (recommended) or via individual installers if you prefer.

Feedback Requested

As always, please leave any comments or suggestions on the project site at http://mvcmusicstore.codeplex.com. Use the discussion list if you need help, and use the issues list if you've got a suggestion or bug report.

Posted by Jon Galloway | 7 comment(s)
Filed under:
More Posts