March 2011 Blog Posts

Hosting a Simple “Read-Only” NuGet Package Feed on the Web

As you may know, NuGet supports aggregating packages from multiple package sources. You can simply point NuGet at a folder containing packages or at a NuGet OData service.

A while back I wrote up a guide to hosting your own NuGet feed. Well, we’ve made it way easier to set one up now! And, surprise surprise, it involves NuGet. Smile I’ll provide step by step instructions here. But first, make sure you’re running NuGet 1.2!

Step 1: Create a new Empty Web Application in Visual Studio

Go to the File | New | Project menu option (or just hit CTRL + SHIFT + N) which will bring up the new project dialog and select “ASP.NET Empty Web Application” as in the following screenshot (click to enlarge).

new-project-dialog

This results in a very empty project template.

empty-web-project

Step 2: Install the NuGet.Server Package

Now right click on the References node and select Add Library Package Reference to launch the NuGet dialog (alternatively, you can use the Package Manager Console instead and type Install-Package NuGet.Server).

Click the Online tab and then type NuGet.Server in the top right search box. Click Install on the NuGet.Server package as shown in the following image (click to enlarge).

nuget-dialog

Step 3: Add Packages to the Packages folder

That’s it! The NuGet.Server package just converted your empty website into a site that’s ready to serve up the OData package feed. Just add packages into the Packages folder and they’ll show up.

In the following screenshot, you can see that I’ve added a few packages to the Packages folder.

packages-folder

Step 4: Deploy and run your brand new Package Feed!

I can hit CTRL + F5 to run the site and it’ll provide some instructions on what to do next.

package-site

Clicking on “here” shows the OData over ATOM feed of packages.

package-feed

Now all I need to do is deploy this website as I would any other site and then I can click the Settings button and add this feed to my set of package sources as in the following screenshot (click to enlarge).

Options

Note that the URL you need to put in is http://yourdomain/nuget/ depending on how you deploy the site.

Yes, it’s that easy! Note that this feed is “read-only” in the sense that it doesn’t support publishing to it via the NuGet.exe command line tool. Instead, you need to add packages to the Packages folder and they are automatically syndicated.

NuGet 1.2 Released

I’m happy to announce the release of NuGet 1.2. It took us a bit longer than we expected to get this release out there, and I’ll explain why later, but for now, go install it!

Upgrade! If you go into Visual Studio and select Tools | Extension Manager, click on the Update tab and you’ll see that this new version of NuGet should be available as an update. It only takes a minute and it really is that easy to upgrade.

For more details about what’s in this release, check out the announcement on nuget.org.

There’s also a new version of NuGet.exe corresponding with this release as well as the Package Explorer. If you have a fairly recent version of NuGet.exe, you can upgrade it by simply running the following command:

NuGet.exe u

076583 fg1019

Thanks to everyone who helped make this happen. I’ll be writing about our plans for 1.3 fairly soon. Smile

Tags:

Want to work on datajs?

A colleague of mine from the Data and Modeling Group mentioned that they have a new senior developer position open working on their new datajs project.

This developer would be responsible for defining how modern web and mobile applications use and interact with data on JavaScript platforms. We deal with and work on defining a number of standards including HTML5’s IndexedDB and OData, as well as provide a new set of end-to-end experiences for accessing, managing, and storing data in JS.

What’s interesting to me is that datajs appears to be an open source project under the MIT license!

From its description on the datajs CodePlex page,

datajs is a new cross-browser JavaScript library that enables data-centric web applications by leveraging modern protocols such as JSON and OData and HTML5-enabled browser features. It's designed to be small, fast and easy to use.

For more details about the position, check out the job posting online.

For those of you who are interested but don’t live in Redmond, Washington, this position is in Redmond and requires relocation.

How do I apply?

If you’re interested in the position, please contact Jeff Derstadt jeffders@microsoft.com. I don’t know anything more about the job than what I posted here in this blog post.

I do know that I’ve worked with people on that team as partners on in various capacities and they’re smart folks doing good work. I’m sure my team and your team (should you get the job) would end up working closely together. Smile

Model Binding Decimal Values

I’m in the beautiful country of Brazil right now (I’ll hopefully blog more about that later) proctoring for the hands-on labs that’s part of the Web Camps agenda.

However, the folks here are keeping me on my toes asking me to give impromptu and deeply advanced demos. It almost feels like a form of performance art as I create brand new demos on the fly. Smile

During this time, several people reported issues binding to a decimal value that prompted me to write a new demo and this blog post.

Let’s look at the scenario. Suppose you have the following class (Jogador is a soccer player in Portugese):

public class Jogador {
    public int ID { get; set; }
        
    public string Name { get; set; }
        
    public decimal Salary { get; set; }
}

And you have two controller actions, one that renders a form used to create a Jogador and another action method that receives the POST request.

public ActionResult Create() {
  // Code inside here is not important
  return View();
}

public ActionResult Create(Jogador player) {
  // Code inside here is not important
  return View();  
}

When you type in a value such as 1234567.55 into the Salary field and try to post it, it works fine. But typically, you would want to type it like 1,234,567.55 (or here in Brazil, you would type it as 1.234.567,55).

In that case, the DefaultModelBinder chokes on the value. This is unfortunate because jQuery Validate allows that value just fine. I’ll talk to the rest of my team about whether we should fix this in the next version of ASP.NET MVC, but for now it’s good to know there’s a workaround.

In general, we recommend folks don’t write custom model binders because they’re difficult to get right and they’re rarely needed. The issue I’m discussing in this post might be one of those cases where it’s warranted.

Here’s the code for my DecimalModelBinder. I should probably write one for other decimal types too, but I’m lazy.

WARNING: This is sample code! I haven’t tried to optimize it or test all scenarios. I know it works for direct decimal arguments to action methods as well as decimal properties when binding to complex objects.

using System;
using System.Globalization;
using System.Web.Mvc;

public class DecimalModelBinder : IModelBinder {
    public object BindModel(ControllerContext controllerContext, 
        ModelBindingContext bindingContext) {
        ValueProviderResult valueResult = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try {
            actualValue = Convert.ToDecimal(valueResult.AttemptedValue, 
                CultureInfo.CurrentCulture);
        }
        catch (FormatException e) {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

With this in place, you can easily register this in Application_Start within Global.asax.cs.

protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();
    
    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

    // All that other stuff you usually put in here...
}

That registers our model binder to only be applied to decimal types, which is good since we wouldn’t want model binding to try and use this model binder when binding any other type.

With this in place, the Salary field will now accept both 1234567.55 and 1,234,567.55.

Hope you find this useful. I’ve had a great time in Buenos Aires, Argentina and São Paulo, Brazil. I’ll probably be swamped when I get back home, but I’ll try to make time to write about my time here.

Defining Default Content For A Razor Layout Section

Layouts in Razor serve the same purpose as Master Pages do in Web Forms. They allow you to specify a layout for your site and carve out some placeholder sections for your views to implement.

For example, here’s a simple layout with a main body section and a footer section.

<!DOCTYPE html>
<html>
<head><title>Sample Layout</head>
<body>
    <div>@RenderBody()</div>
    <footer>@RenderSection("Footer")</footer>
</body>
</html>

In order to use this layout, your view might look like.

@{
    Layout = "MyLayout.cshtml";
}
<h1>Main Content!</h1>
@section Footer {
    This is the footer.
}

Notice we use the @section syntax to specify the contents for the defined Footer section.

But what if we have other views that don’t specify content for the Footer section? They’ll throw an exception stating that the “Footer” section wasn’t defined.

To make a section optional, we need to call an overload of RenderSection and specify false for the required parameter.

<!DOCTYPE html>
<html>
<head><title>Sample Layout</head>
<body>
    <div>@RenderBody()</div>
    <footer>@RenderSection("Footer", false)</footer>
</body>
</html>

But wouldn’t it be nicer if we could define some default content in the case that the section isn’t defined in the view?

Well here’s one way. It’s a bit ugly, but it works.

<footer>
  @if (IsSectionDefined("Footer")) {
      RenderSection("Footer");
  }
  else { 
      <span>This is the default yo!</span>   
  }
</footer>

That’s some ugly code. If only there were a way to write a version of RenderSection that could accept some Razor markup as a parameter to the method.

Templated Razor Delegates to the rescue! See, I told you these things would come in handy.

We can write an extension method on WebPageBase that encapsulates this bit of ugly boilerplate code. Here’s the implementation.

public static class Helpers {
  public static HelperResult RenderSection(this WebPageBase webPage, 
      string name, Func<dynamic, HelperResult> defaultContents) {
    if (webPage.IsSectionDefined(name)) {
      return webPage.RenderSection(name);
    }
    return defaultContents(null);
  }
}

What’s more interesting than this code is how we can use it now. My Layout now can do the following to define the Footer section:

<footer>
  @this.RenderSection("Footer", @<span>This is the default!</span>)
</footer>

That’s much cleaner! But we can do even better. Notice how there’s that ugly this keyword? That’s necessary because when you write an extension method on the current class, you have to call it using the this kewyord.

Remember when I wrote about how to change the base type of a Razor view? Here’s a case where that really comes in handy.

What we can do is write our own custom base page type (such as the CustomWebViewPage class I used in that blog post) and add the RenderSection method above as an instance method on that class. I’ll leave this as an exercise for the reader.

The end result will let you do the following:

<footer>
  @RenderSection("Footer", @<span>This is the default!</span>)
</footer>

Pretty slick!

You might be wondering why we didn’t just include this feature in Razor. My guess is that we wanted to but just ran out of time. Hopefully this will make it in the next version of Razor.