Alexander Beletsky's development blog

My profession is engineering

ASP.NET Articles Mobile Application

Do you like asp.net web site content? Do you enjoy reading fine selected articles about ASP.NET and related technologies? Me too, but I spent most of the reading from my iPad. And unfortunately asp.net is not that mobile friendly yet, moreover articles are just a bunch of links to developers blogs, that might not so be adapted for mobile devices as well.

So, I would like to introduce mobile application that I created to close the gap. Please welcome http://aspnetmobile.apphb.com/.




aspnet.mobile is rather simple application. Despite of many similar apps that uses RSS channel, it goes for ASP.NET portal simple external API. RSS is bad in the way that you are limited with initial content (typically up to 25 articles on channel). With aspnet.mobile you freely can access any article ever posted on ASP.NET.

It’s powered by jQuery Mobile that currently provides more “iOS-look” interface. I’m happy with that currently but I plan to have native look for Android and WP7 as well, so I thinking either to change the framework or to create custom one. But it currently looks and works great on iPad.




I didn’t want to just refer reader to developers blog, for the reason above. Instead, I much inspired by iOS 5.0 Safari feature called ‘Reader’. A bit of googling and I found that Safari using technology called Readability. There are different ports of that technology for a different platforms: Ruby, PHP, Python, Node.js.. and I was happy to find great implementation of NReadability by Marek Stoj. Basically, it allowed me to render nice looking pages, like:




Besides of that it has a basic support of offline mode. All read articles are stored in Local Storage, so once the application offine it will provide proper behavior and propose some content.

I will be happy if you try and let me know your impression. Feel free to check sources at github.

New in ASP.NET MVC4: Razor changes

Razor has been changed a little with ASP.NET MVC 4 beta. It’s not a kind of radical changes, but rather improvements that make developers happier. As for me, developers happier then you need to write less code to get the same function. It reminded me a ideal device, which is part of TRIZ theory. Ideal device is a device that does not exit, but does it function. By analogy, ideal code is the code that not exist but it’s function exist. Razor is not that ideal, through.. But it’s “more ideal” than previous version.

No more @Url.Content

I got used to @Url.Content and used that for all CSS and JS references. Since it’s to commonly used, developers decided to include it on a level of engine. Now, instead of

<script src="@Url.Content("~/Scripts/Controls.js")"></script>

You simply can write,

<script src="~/Scripts/Controls.js"></script>

If Razor detects ~/ it would created an output identical to @Url.Content. Just got rid of several bytes within view files.

Conditions

Conditions in attributes were pretty noisy. Have you ever create something like this?

<div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div>

I had and I did not like it much. I usually ended up with creation of some simple HTML helper instead. With new Razor it a little simpler, not you can write

<div class="@myClass">Content</div>

If @myClass is null, it won’t output class attribute at all. Very handy.

And a little more

This is an update section I created after this post has been twitted by Scott Guthrie and some valuable comments has been received.

Brad Wilson stated, conditions does not only support nullable types, but also booleans. Say, I have code:

<input checked="@ViewBag.Checked" type="checkbox"/>

If the @ViewBag.Checked in null or false, it will be rendered as:

<input type="checkbox"/>

Else if @ViewBag.Checked is true, it will be rendered as:

<input checked="checked" type="checkbox"/>

Erik Porter also mentioned the custom support for data-* attributes. Data attributes are little special, so even if you missing particular value you still want to have those as empty data-role = "". So, if you have code like:

<ul data-role="@ViewBag.ListRole">
</ul>

and @ViewBag.ListRole is null or false, data attribute will be eliminated. That’s how it work in Beta. But for next releases data-* attributes will be treated specially, so even if value is null or false they will be rendered as empty ones.

Conclusions

I haven’t noticed any more changes so far. It’s great to see that Razor has not been “frozen” and still improving. I like that view engine first of all by it’s simplicity. So making it even more simple would definitely make it more attractive.

Why I’m Not Using Bundling.. Yet

Last time I a posted some initial info about Bundling and Minification abilities of MVC4. In this post, I describe some concerns that prevents me of using it right now. Let me remind that I’m doing review of MVC 4 beta and I hope some of those concern would not be actual at the time of release. This is only personal considerations, you might not agree with everything here.

It’s contra-intuitive

Maybe the ‘contra-intuitive’ is not exact word that reflects my frustration. What I mean, it does not do what you might expect by default. Remember I described two methods RegisterTemplateBundles() and EnableDefaultBundles()? It was really unclear to me what they do until I looked into code. Modern frameworks tend to be as less surprise as possible, but not in case of System.Web.Optimizations.

Development and production mode

The fact it does not take into account ‘Debug’ and ‘Release’ mode is also very confusing. As same as in point above, I have a different expectations how it should behave. For ‘Debug’ mode it simply should do nothing - no optimization, no compression. For release mode it should do as much as possible to minify the number of HTTP request. It turns out that you have to create some code on your own to make it happen.

Bundling is bad during debugging

While you in development mode you do debug, no surprise here. Having FireBug or Chrome Development tools it’s very easy to debug javascript, you can pick up any file and place breakpoint inside.


chrome development

It is no so easy with bundling, cause it will package all your files in one big chunk, so you need to open and find right place there. Since the total number of line could be huge there, it’s turns to be big deal.

As a workaround you have to have a copies of references, one you using on development and ones you use on production.

<!-- Development -->
<script type="text/javascript" src="~/Scripts/jquery-1.6.4.js"></script>
<script type="text/javascript" src="~/Scripts/jquery.mobile-1.0b3.js"></script>
<script type="text/javascript" src="~/Scripts/knockout-2.0.0.js"></script>
<script type="text/javascript" src="~/Scripts/underscore.js"></script>
<script type="text/javascript" src="~/Scripts/App/CacheInit.js"></script>     

<!-- Production 
<script type="text/javascript" src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>
-->

It’s not well ironed

Since it’s very young obviously it has some problems.

Be honest, I haven’t seen on my own but one of the comments in my previous post described the issue with minification of CSS files that include -ie- specific selectors. That’s probably not only one issue found.

What did I expect?

To do not have only critics I try to put some constructive part in post as well. Ok, so I see it should work to meet my needs?

First of all, it should be implemented as simple HTML razor helpers. You just specify the name of bundle there, like “scripts/js” and that’s it. Helper is smart enough to understand what is active environment at the moment. In case of ‘Debug’ it expanded to a bunch of script references or links, for JS and CSS respectively. In ‘Release’ mode it’s indeed refers the bundle, so it’s packaged and minified for best performance.

You might say, that 1. this is out of scope for System.Web.Optimization framework 2. you can create this behavior easily on your own. This is right, but in the same time if you deal with ASP.NET MVC4 you have some expectation that is should work right and you are not forced to invent the wheel again, so you have kind of consistency between numerous projects.

I’ve been thinking about to create something like that, but during the chat with fellow developer @andrexx about bundling and he showed me something interesting. Tom DuPont has already implemented something that’s really reflects my needs. It’s the way of configuring bundles both from code and web.config. It looks like a very handy tool.

New in ASP.NET MVC4: Bundling and Minification

Next new feature that appeared in MVC 4 beta is bundling and minification. Idea is simple: modern web application contains of many static resources, especially css and javascript files. To load the page browser have to load each resource. Each resource is being requested by HTTP request. Browser have to make as many request as page refers, wait till all are completed and only after that render the page.

The problem is, each HTTP request takes time. One of the most critical Yahoo web applications performance recommendation says - Minimize HTTP request. As few HTTP requests you need to load application as better.

System.Web.Optimization

Bundling and minification is located in it’s own namespace System.Web.Optimization and resides in assembly named Microsoft.Web.Optimization, which is installed by default with new ASP.NET MVC4 application template as NuGet package. Since it’s still in beta, namespaces and class names are probably be changing, but let’s look on that we have now.

What is bundle?

Bundle is simply logical group of files that could be referenced by unique name and being loaded with one HTTP request. Suppose, we have a Layout.cshtml that might look something like that:

<meta charset="utf-8" />

<title>@ViewBag.Title</title> 
        
<link rel="stylesheet" href="~/Content/jquery.mobile-1.0b3.min.css" />
<link rel="stylesheet" href="~/Content/reset.css" />
<link rel="stylesheet" href="~/Content/foundation.css" />
<link rel="stylesheet" href="~/Content/Fonts.css" />
<link rel="stylesheet" href="~/Content/Site.Layout.css" />
<link rel="stylesheet" href="~/Content/Site.Mobile.css" />

<script type="text/javascript" src="~/Scripts/jquery-1.6.4.js"></script>
<script type="text/javascript" src="~/Scripts/jquery.mobile-1.0b3.js"></script>
<script type="text/javascript" src="~/Scripts/knockout-2.0.0.js"></script>
<script type="text/javascript" src="~/Scripts/underscore.js"></script>
<script type="text/javascript" src="~/Scripts/App/CacheInit.js"></script>        

You can see, that’s a lot of css and javascript that will be loaded for page. With bundling we can rewrite it with very simple code

<meta charset="utf-8" />

<title>@ViewBag.Title</title> 
        
<link rel="stylesheet" href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/css")" />

<script type="text/javascript" src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>

In this case "~/Content/css" and "~/Scripts/js" are no longer virtual paths, but bundle names.

The the browser would load this page, rendered HTML would look like:

<link href="/Content/css?v=q_sftc19r22licIM8-Ar58FwviyWry1JuYbA-iATm4M1" rel="stylesheet" type="text/css" />
<script src="/Scripts/js?v=_8kyYWxz-Je_VE0p3_w5nbcjAhq0Qj4vZiNxvYU_oBg1"></script>

Note, it would reference the bundle with version. The version is a kind of hash taken on all files in bundle content. This enables browser caching, if content of bundle is not change browser will take it from cache, which is much faster. In case of changes, new version token is generated, so browser would be forced to reload bundle.


chrome development tools

Bundle registration

In global.asax file you will see new line:

    BundleTable.Bundles.RegisterTemplateBundles();

It’s only one small line of code that enables bundling and minification framework.

RegisterTemplateBundles() vs. EnableDefaultBundles()

It looks fine so far, so I tried to add new javascript file into Scripts folder. Unfortunately, my application did not work. I think this is first very contra-intuitive fact of bundling framework. Googling a bit I found quick solution, change RegisterTemplateBundles() to EnableDefaultBundles().. I tried that and it really works.

Since the System.Web.Optimization has not been opened sourced yet (in case you haven’t heard - ASP.NET web stack is open source, even with accepting pull request) I had to go to JustDecompile to understand why is that.

So, RegisterTemplateBundles() is looks like that,

public void RegisterTemplateBundles()
{
    bool flag;
    bool flag2;
    bool flag3;
    bool flag4;
    bool flag5;
    bool flag6;
    bool flag7;
    Bundle bundle1 = new Bundle("~/Scripts/js", new JsMinify());
    bool flag8 = false.AddDirectory("~/Scripts", "jquery-*", flag, flag8);
    bool flag9 = false.AddDirectory("~/Scripts", "jquery.mobile*", flag2, flag9);
    bool flag10 = false.AddDirectory("~/Scripts", "jquery-ui*", flag3, flag10);
    bool flag11 = false.AddDirectory("~/Scripts", "jquery.unobtrusive*", flag4, flag11);
    bool flag12 = false.AddDirectory("~/Scripts", "jquery.validate*", flag5, flag12);
    bool flag13 = false.AddFile("~/Scripts/MicrosoftAjax.js", flag13);
    bool flag14 = false.AddFile("~/Scripts/MicrosoftMvc.js", flag14);
    bool flag15 = false.AddDirectory("~/Scripts", "modernizr*", flag6, flag15);
    bool flag16 = false.AddFile("~/Scripts/AjaxLogin.js", flag16);
    this.Add(bundle1);
    Bundle bundle2 = new Bundle("~/Content/css", new CssMinify());
    bool flag17 = false.AddFile("~/Content/site.css", flag17);
    bool flag18 = false.AddDirectory("~/Content/", "jquery.mobile*", flag7, flag18);
    this.Add(bundle2);
    Bundle bundle3 = new Bundle("~/Content/themes/base/css", new CssMinify());
    bool flag19 = false.AddFile("~/Content/themes/base/jquery.ui.core.css", flag19);
    bool flag20 = false.AddFile("~/Content/themes/base/jquery.ui.resizable.css", flag20);
    bool flag21 = false.AddFile("~/Content/themes/base/jquery.ui.selectable.css", flag21);
    bool flag22 = false.AddFile("~/Content/themes/base/jquery.ui.accordion.css", flag22);
    bool flag23 = false.AddFile("~/Content/themes/base/jquery.ui.autocomplete.css", flag23);
    bool flag24 = false.AddFile("~/Content/themes/base/jquery.ui.button.css", flag24);
    bool flag25 = false.AddFile("~/Content/themes/base/jquery.ui.dialog.css", flag25);
    bool flag26 = false.AddFile("~/Content/themes/base/jquery.ui.slider.css", flag26);
    bool flag27 = false.AddFile("~/Content/themes/base/jquery.ui.tabs.css", flag27);
    bool flag28 = false.AddFile("~/Content/themes/base/jquery.ui.datepicker.css", flag28);
    bool flag29 = false.AddFile("~/Content/themes/base/jquery.ui.progressbar.css", flag29);
    bool flag30 = false.AddFile("~/Content/themes/base/jquery.ui.theme.css", flag30);
    this.Add(bundle3);
}

As you can see it adds all recourses that came just in template, including jQuery Mobile and jQuery UI.

In the same time, EnableDefaultBundles()

public void EnableDefaultBundles()
{
    this.Add(new DynamicFolderBundle("js", JsMinify.Instance, "*.js"));
    this.Add(new DynamicFolderBundle("css", CssMinify.Instance, "*.css"));
}

So, what it does - it matches all javascript and css files in project, minify them and create to bundles out of it.

As you can see EnableDefaultBundles() is also uses Minification policy for bundle content.

How add my own custom bundle?

As simple as create new Bundle object, put files inside and then add it to Bundles collection.

var bundle = new Bundle("~/Scripts/libs", new JsMinify());
bundle.AddFile("~/Scripts/knockout-2.0.0.js");
BundleTable.Bundles.Add(bundle);

But there two issues here. First of all, you don’t always want to minify. Second, adding bundles with many files will make global.aspx.cs looks messy. I really liked approached proposed by Scott K. Allen in his Yet Another Bundling Approach for MVC 4 blog post. He does it in more object-oriented way including smart code to decide, should the bundle be minified or not. All you need is just take code he created and after you are able to make bundles like that.

public class JsLibsBundle : JsBundle
{
    public JsLibsBundle() : base("~/js/libs")
    {
        AddFiles(
            "~/Scripts/jquery-1.6.4-vsdoc.js",
            "~/Scripts/jquery-1.6.4.js",
            "~/Scripts/jquery.mobile-1.0b3.js",
            "~/Scripts/knockout-2.0.0.js",
            "~/Scripts/modernizr-2.0.6-development-only.js",
            "~/Scripts/underscore.js"
        );
    }
}

public class CssAppBundle : CssBundle
{
    public CssAppBundle() : base("~/css/mobile")
    {
        AddFiles(
            "~/Content/jquery.mobile-1.0b3.css",
            "~/Content/Site.Mobile.css"
        );
    }
}

And put them to registered those classes in global.asax.cs

    BundleTable.Bundles.Add(new JsLibsBundle());
    BundleTable.Bundles.Add(new CssAppBundle());

Ok, how all that stuff works?

Now let’s do a really brief look under the hood. Again, JustDecompile is our friend here.

It was interesting to me to find out new cool way of registration modules in ASP.NET. No longer entry points in web.config or other magic. You can have a special class PreApplicationStartCode that would be called then assembly is loaded, but before application is stated.

public static class PreApplicationStartCode
{
    private static bool _startWasCalled;

    public static void Start();
}

Here System.Web.Optimization register it’s own module, called BundleModule.

public static void Start()
{
    if (PreApplicationStartCode._startWasCalled)
    {
        return;
    }
    PreApplicationStartCode._startWasCalled = 1;
    DynamicModuleUtility.RegisterModule(typeof(BundleModule));
}

Then the module is intialized, it subscribes for event called HttpApplication.PostResolveRequestCache and inside the callback it would register the BundleHandler.

private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
{
    HttpApplication httpApplication = (HttpApplication)sender;
    if (BundleTable.Bundles.Count > 0)
    {
        BundleHandler.RemapHandlerForBundleRequests(httpApplication);
    }
}

The handler is now responsible for dirty job. Through the RequestBundle class it finally comes to ProcessRequest method.

internal void ProcessRequest(BundleContext context)
{
    context.EnableInstrumentation = Bundle.GetInstrumentationMode(context.HttpContext);
    BundleResponse bundleResponse = this.GetBundleResponse(context);
    Bundle.SetHeaders(bundleResponse, context);
    context.HttpContext.Response.Write(bundleResponse.Content);
}

So, the GetBundleResponse is there magic is happens.

private BundleResponse GetBundleResponse(BundleContext context)
{
    BundleResponse bundleResponse = Bundle.CacheLookup(context);
    if (bundleResponse == null || context.EnableInstrumentation)
    {
        bundleResponse = this.GenerateBundleResponse(context);
        if (!context.EnableInstrumentation)
        {
            Bundle.UpdateCache(context, bundleResponse);
        }
    }
    return bundleResponse;
}

What’s important here is that it uses cache. So, it makes bundling rather efficient. In case if there are no cached result, it will run the GenerateBundleResponse to generate actual response:

public virtual BundleResponse GenerateBundleResponse(BundleContext context)
{
    if (context == null)
    {
        throw new ArgumentNullException("context");
    }
    IEnumerable<FileInfo> fileInfos = this.EnumerateFiles(context);
    fileInfos = context.BundleCollection.IgnoreList.FilterIgnoredFiles(fileInfos);
    fileInfos = this.Orderer.OrderFiles(context, fileInfos);
    fileInfos = this.ReplaceFileExtensions(context, fileInfos);
    string str = this.Builder.BuildBundleContent(this, context, fileInfos);
    BundleResponse bundleResponse = new BundleResponse(str, fileInfos);
    this.Transform.Process(context, bundleResponse);
    return bundleResponse;
}

Yet another interesting finding here is this.Orderer. Sometime ago I did smalltalk on Kiev ALT.NET meeting about new stuff in VS2011 and being asked a question, how is possible to order the files. I didn’t know answer then. It is actually possible to setup the order of files inside bundle, in case you have cross-file dependencies:

public interface IBundleOrderer
{
 IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files);
}

That’s it, the generated response than just being written to context.HttpContext.Response.

Conclusions

Bundling and minification is something that I personally wanted so much, to appear in new MVC framework. Now it’s there, it works.. but I would not say I’m 100% happy. There are several things that makes it a little difficult to use, as for me. I did want to place it in this post, but appeared to big.. So, I’ll probably do a separate one on this matter.

MS SWIT 2012

The 22-23 of March this year I had a chance to participate biggest event organized by Microsoft Ukraine - MS SWIT 2012.


ms swit 2012

It’s been almost two years ago I visited MS SWIT 2010. If the primary topic of last conference was cloud technologies - Azure, SQL etc. This time I would say the buzz was around Windows 8, Market Place and Metro-style applications. Of cause, there was still a lot of attention to Azure as well.

I really much enjoyed the Keynote of first day by Wolfgang Ebermann. Indeed, Microsoft opens pretty much interesting opportunities for developers on Windows 8 and Windows Phone markets. Not long time ago Ukraine officially is a part of MarketPlace, so no time to wait - go and create you first Metro style app. And with new Microsoft policies regarding adoption of open standards like HTLM5, EcmaScript - it looks really attractive to me.

Big attention was also about new recent releases like: Share Point, SQL Server Denali, Windows Server 8 etc. I would not say this is exactly interesting to me, since I more focus on web technologies, but it’s always good to be aware what’s going on around. First day of conference got a lot people moving around, so if you wanted to listen for some interesting speech you have to be in time to get free sit. Second day was not so overcrowded as for me, so the people who didn’t come have to be sorry, cause Second day was much more interesting.

My talk was about new stuff in ASP.NET MVC4, with more focus to mobile web applications. That was the biggest audience I ever speak to. There was almost no free sits.. I don’t know for sure it contained 150-200 people.. Huge!

Being much inspired by Steve Sanderson talk on TechDays 2012, I decided to make something similar. I came up with idea of simple mobile web application, namely it is a web client to http://asp.net portal and develop it just during the speech. I had several issue’s there, first one I did a little more longer introduction and then some issues with internet that made me a little nervous and I lose tempo a bit. That forced me to skip the last part of talk regarding Offline mode for apps. Anyway, I hope I was able to show new sweet available stuff like CSS3 Media Queries, Display Modes and jQuery Mobile framework.


Thanks a lot for everyone who listened to me and came up with questions. I appreciate your attention and hope my talk was useful for you.


asp.net portal mobile

Regarding the app, I polished it a bit and going to release closer to the end of next week. The sources are hosted on https://github.com/alexbeletsky/aspnet.mobile, feel free to clone and send a pull request.

New in ASP.NET MVC4 Beta: Web API

This is a high level overview of new stuff that appeared within VS2011 release. So, let’s briefly look inside. Today will take a look on changes appeared to Web API.

Web API

The biggest and most important change as for me is integration of Web API into ASP.NET. Web API is most known as WCF Web API - an attempt of .NET team build framework for creation of RESTfull services based on WCF infrastructure. There was several releases of WCF Web API made and general feedback from community was - “it’s good enough”. Since when, Microsoft did a strategic change, merged WCF Web API and ASP.NET teams together, so both products to be developed in sync. From now Web API is integral part of ASP.NET (and does not have any WCF prefix any more) and called ASP.NET Web API. It is not just re-branding, but it reflects changes both the programming model and processing architecture.

Simple Start

If we create a new ASP.NET MVC4 application, we see the following change into global.asax file.

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

MapHttpRoute is new extension method for RouteCollection. Similarly to ASP.NET MVC routing definition, it maps HTTP request with matching URL into corresponding API controller action. By default, the are all prefixed with “api” to do not “interfere” to ASP.NET MVC routing. It’s not a problem to change that prefix to anything you want, like “services”, “methods” etc.

    /api/contacts/      <- Web API
    /api/contacts/1     <- Web API
    /contacts/1         <- ASP.NET MVC

The API controllers are really similar to ASP.NET MVC controllers. Instead of inherit from Controller class, they inherited from ApiController class. Instead of returning ActionResult from action, in API controllers you return either IEnumerable or concrete instance, like Product (there are some more dedicated scenarios with returning types, we will see later).

By just looking into example from project template it is very easy to understand, what’s going on. There are some small details you should know before API controller usage.

Action methods naming

API controllers are “Convention over configuration” based. The actual HTTP verb that action handles could be specified in method name.

public class ProductsController : ApiController
{
    // Handles GET
    public IEnumerable<Product> Get() { }
    // Handles POST
 public Product Post(Product product) { }
    // Handles PUT
 public Product Put(Product product) { }
    // Handles DELETE
 public void Delete(int id) { }
}

This convention applies only to GET, POST, PUT, and DELETE methods. You might be more specific in methods names, like GetProducts or DeleteProduct, the important is the prefix (Get, Post, Put etc.) of method.

If you don’t want to rely of named based conventions, you can explicitly specify target HTTP verb by decorating methods with HttpGet, HttpPut, HttpPost, or HttpDelete attribute.

public class ProductsController : ApiController
{
    [HttpGet]
    public IEnumerable<Product> AllProducts() { }
    [HttpPost]
 public Product CreateProduc(Product product) { }
    [HttpPut]
 public Product UpdateProduct(Product product) { }
    [HttpDelete]
 public void DeleteProduct(int id) { }
}

One handler per one controller

API Controller are different from ASP.NET MVC controller. The main difference is that API controller handles exactly one HTTP request belongs to particular entity.

If you try to create the code like:

public class ProductsController : ApiController
{
    public IEnumerable<Product> Get() { }
    public IEnumerable<Product> GetAnother() { }
}

It would be build OK, but on a runtime if you try to access ‘/api/products’, you will get an exception:

"Multiple actions were found that match the request: 
\u000d\u000aSystem.Collections.Generic.IEnumerable`1[MvcApplication7.Api.Controllers.Product] 
Get() on type MvcApplication7.Api.Controllers.ProductsController\u000d\u000aSystem.Collections.Generic.IEnumerable`1[MvcApplication7.Api.Controllers.Product] 
GetAnother() on type MvcApplication7.Api.Controllers.ProductsController"

The less stuff is very similar to something we get used in ASP.NET MVC. And you might think - why do we need this Web API at all, I can do exactly the same stuff with good-n-old ASP.NET MVC controllers? Not exactly. Web API has several killer features that makes it favorite for data oriented API’s. Let’s go on.

Content Negotiation

Content Negotiation is the process for mutual agreement between client and server about the received/sent data formats. Good news here, Web API does a lot of job for you, leaving content negotiation internals behind the scene. Let’s take a brief look of how things happen.

When client sends HTTP request to server, besides the query string and payload it also provides different kind information. This information is being placed into HTTP header and provides server with specific details for better understanding each other. In particular, it contains Accept header field which specifies client preferences on response format. I’m going use Fiddler to check how Web API behaves on different conditions.

First, let’s do not specify the Accept field at all. So, the payload we going to send to server from our client (Fiddler) will be like:

    GET /api/products HTTP/1.1
    User-Agent: Fiddler
    Host: localhost:5589

For that request, we will receive the response like:

    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/7.5
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?RDpcRGV2ZWxvcG1lbnRcUHJvamVjdHNcZXhwZXJpbWVudHNcTXZjQXBwbGljYXRpb243XE12Y0FwcGxpY2F0aW9uN1xhcGlccHJvZHVjdHM=?=
    X-Powered-By: ASP.NET
    Date: Mon, 19 Mar 2012 17:31:23 GMT
    Content-Length: 88

    [{"Description":"iPad","Id":1,"Price":1000},{"Description":"iPhone","Id":2,"Price":500}]

As you can see, the default Content-Type is “application/json; charset=utf-8”, there is a json string in HTTP response payload.

Let’s make our request a little more specific.

    GET /api/products HTTP/1.1
    User-Agent: Fiddler
    Host: localhost:5589
    Accept: text/xml

The corresponsing response:

    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: text/xml; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/7.5
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?RDpcRGV2ZWxvcG1lbnRcUHJvamVjdHNcZXhwZXJpbWVudHNcTXZjQXBwbGljYXRpb243XE12Y0FwcGxpY2F0aW9uN1xhcGlccHJvZHVjdHM=?=
    X-Powered-By: ASP.NET
    Date: Mon, 19 Mar 2012 17:33:34 GMT
    Content-Length: 329

    <?xml version="1.0" encoding="utf-8"?><ArrayOfProduct xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Product><Id>1</Id><Description>iPad</Description><Price>1000</Price></Product><Product><Id>2</Id><Description>iPhone</Description><Price>500</Price></Product></ArrayOfProduct>

As you can see, without any code changes we made it “adapt” for particular client needs. This is a very decent feature of Web API and available for use, just from the box. You even don’t need to care about it at all. Leave the content negotiation for the infrastructure.

IQueryable<T> Support

Next cool feature is IQueryable<T> support. If you need to, instead of returning “plain” IEnumerable objects from the API action, you might return IQueryable<T>. Why?

Remember the times we implemented paging & sorting with ASP.NET MVC application. It was possible of cause, but it required a lot of manual job. Actions had to be extended with additional parameters, code have to respect those parameters and return exact portion of data we require to. The same story with sorting. In Web API it much simpler.

Change the signature and return type to IQueryable.

public IQueryable<Product> Get()
{
    return _storage.AsQueryable();
}

Now, if Web API sees the method like that, it will allow to access with with Open Data Protocol (OData) query string parameters. OData provides support for following queries: $filter, $orderby, $skip, $top.

Now, if I do the request:

    http://localhost:5589/api/products?$top=3

I will receive, 3 top products. Or something like,

    http://localhost:5589/api/products?$skip=2&$top=3

I will skip 2 and take rest 3. In short, having IQueryable and 4 OData query parameters it’s much more easy to do the stuff required more time before.

Hosting

Hosting is a feature of Web API allow to run service inside the different hosts. What does it mean?

We are much get used to ASP.NET hosting as default. I saw no problem with that at all till working on one of my recent projects. The problem is for ASP.NET pipeline you need to have a web server (IIS), but web server always have some limitations (permissions and stuff). For simple things, that does not require any IIS benefits it is easier to host application just in .exe assembly. It’s now possible with Web API.

We have several hosting providers out of the box: self-hosting and web-hosting. Besides of that there are already some provided by community Louis DeJardin created a host on top of OWIN and Pedro Félix host for Azure.

Also, there is a great article by Pedro Felix about in-memory hosting. This is very useful type of hosting for unit testing of services.

IoC improvements

Since Web API now is inside ASP.NET MVC, it uses the same strategy of resolving types by IDependencyResolver. That means that Web API classes are now supporting same IoC style as ASP.NET MVC controller classes. Being setup once you can put different dependencies inside API class constructor.

public class ProductsController : ApiController
{
 public ProductsController(IServiceProvider service, IRepository<Product> productRepository)
 {
  // .. 
 }

Conclusions

This is not everything, but very light overview of new stuff coming within ASP.NET MVC4. ASP.NET Web API is very nice addition to framework. There are already some good feedback, so let’s hope it will be even more improved toward release.

VS2011 Beta is Ready for Review

29 February (leap day and huge failure of Azure Cloud) is the day then VS2011 Beta community preview has been released. As a lot of geeks around the globe I’ve downloaded installation image and tried it on my computer. With VS2011 Beta we also received .NET 4.5 framework and (drums here) - ASP.NET MVC4 Beta, that I really wanted to try since first CTP is out. I would not say I spent too much time with both products, but I already have some initial opinion on that.

VS2011 installation..

Well, I had some not really good experience with beta versions of VS2010 and compatibility between two visual studios on the same machine. Situation is different with VS2011. Installation very pretty smooth, I just run it on background while was working through RDP on another machine and it installed without any interaction. Whole process took about 40 minutes.

VS2010 and VS2011 beta could happily leave together without any interference. Moreover, you can freely work with your existing VS2010 solutions. Solutions for .NET 4, 3.5 and 2.0 are still supported in the same good way.

.. and first launch

VS2011 “cold” start up is a faster (about 40 seconds against 90 seconds, on my machine). The only one reason I see is VS2011 is not yet overloaded with different plugins I use in VS2010.

First very noticeable change is of cause the design. There were many blog posts with preview of VS2011 design before the beta release. And you know, I really liked what I saw on images. I changed my opinion on first launch. Probably it’s just the matter of taste or habits, but new VS design looks awful to me (especially in Dark Theme - 80’s monochrome display back!). It’s totally grey, with no colors in icons at all. Fonts are in METRO style (all uppercase) looks very unusual. Solution explorer contains grey icons, it’s a little difficult to distinguish between project types and file types inside. So, fellow developer - get ready to order new glasses since you decide to switch to VS2011.


vs2011 solution

Nevertheless, I was happy to open my exiting solution, press Ctrl + Shift + B and it successfully built. The good thing is .sln file has not been transformed (except the Format Version 11.00 has been changed to Format Version 12.00) so it’s still can be opened both VS2010 and VS2011.

It also has been imported all my VS2010 settings. It is really nice, since you don’t need to spent much time setting up favorite color scheme and key bindings.

I haven’t seen any noticeable performance changes. Sometimes VS2011 works a little slower as for me (please note, this is only subjective feelings, does not pretend to be absolute truth). Looks like VS2011 has much larger memory footprint.


vs2011 memory usage

And for some mystical reason it spawns second devenv.exe process in a while, even if I have only one VS instance running.


vs2011 spawns process

Code editing

Code editor is almost the same. No new refactoring tools, no support of 3rd parties Unit Test systems (NUnit, XUnit etc.) from the box. Still Visual Studio requires to have ReSharper for more productive coding. My dream of using clean VS with minimum plugins installed seems not gonna come true with VS2011.

Some few nice moments I noticed for HTML/Razor/CSS editors. First of all, it updates closing HTML tag if you changed opening one (and vice versa). For CSS, it has much more better InteliSence + nice feature of picking colors.

I haven’t noticed any significant changes to JS editor. Except the fact, that there are no ‘Update JScript Intellisense’ menu command, so I suppose that now it’s done automatically. Still, it’s very primitive and does not work all the time. For instance, I haven’t managed to get any InteliSense during working with Knockout.js library, maybe I’m just doing something wrong.

I want my plugings

So, VS2011 is generally OK, so I would prefer to use it. Hope a lot of new fixes and some feature still will be included in RC.

What I personally lack is 2 plugins. ReSharper and NCrunch. Fortunately both appeared very fast. Remco Mulder released NCrunch 1.38b and JetBrains are came with ReSharper 7 EAP which is free for download and evaluation. Both plugins works really fine. Having good refactoring tools as ReSharper gives and having the power of Continuous Tests with NCrunch, makes the VS2011 ready to use IDE.

Conclusions

The beta looks very promising.. and in general it works fine! Except the design, nothing really new to IDE as for me. Probably I spent to few time to feel the power, so I’ll be updating if I see some cool or bad features. The most sweet things with new VS is surely updated .NET framework and MVC. I’m now trying to play with new stuff and much as I can, already checked some new nice stuff of MVC4 framework.

Second Year of E-conomic

Yeah, it’s been 2 years since I joined the e-conomic company. As it was last year, this year e-conomic still plays very important role in my life, so I’ll spent some time to write this blog post.

Well, a lot of things changed I would say. Some people came, some people left. Teams rotating all the time, I’m no longer work with guys I used to work last year. We are doing revolutionary things there, no doubts. It doesn’t mean, we are creating new search engines or inventing new type of computer. No, we are revolutionizing ourselves much.. doing the same type of products, but doing it differently.

Remember I wrote about how technologies helps to move product faster - that was an example of radical changes in framework and tools we did to successfully deliver the product. I believe something happened last year, something that gave much pulse for changes. And that pulse still affects us. We went much further of changing for Web Forms to MVC or jQuery to Backbone.js. Recently our back-end team finished up POC of using node.js + MongoDB as our perspective server side technology stack. And they actually proved that it will work for us.

From my perspective, e-conomic much improved in this year. And this is of cause happened, because people how work in e-conomic improved. Without any hesitate, I would say that currently we have the strongest team ever. Both Danish and Ukrainian parts. It’s amazing how smooth the technologies change was, how fast new concepts been adopted, how motivated and hardworking guys joined together.

We’ve been empowered not only by engineers, but also with our newly assembled UI/UX team. No secret, everybody want to work with beautiful things. I equally appreciate both the quality of code and quality of design. And this is want UI/UX team care about. And this is fantastic job as for me. We are changing the design quite regularly and each iteration it turns better and better. Colors, fonts, usability tricks - that’s something that gives a life to modern web applications.

As usually the developers see only the tip of iceberg of whole company business, but I really hope that all good stuff that’s happening inside engineering department will find it’s reflection in quality of service, usability and user happiness.. that at the end of the day bring the company more users and more money. Sure, the things are moved not only by developers. I would say, we are doing the easiest job. Our PO’s and Stakeholders - that’s where ideas are coming from. The quality of those “ideas” are directly proportional to output quality. And this quality is getting better and better each day.

We are doing finishing strokes on new product, called Debitoor.com. It’s amazing application and I hope it will find it’s audience very fast.

So, I’ll say goodbye to the past year and look forward for new journeys in next one.

Foundstyles.com - Ready to use styles based on Foundation

Foundstyles.com is a little project I’ve been working for last week. The idea is very simple. Remember, I blogged about Foundation Framework that works pretty nice for me. So, I’ve decided to do something similar that exist for twitter bootstrap framework - bootswatch ready to pickup .css that could be easily integrated to your site. Today the site is available!


foundstyles.com

Unfortunately Foundation does not support LESS from the package, so I need to move colors and layout into corresponding .LESS files, so after it’s just possible to have a basic template which is possible to customize with own colors.

As for now, I’ve created only 3 templates: Blades Of Steel, Evergreen Tree and Coffee and Milk.


foundstyles.com

I had a lot of joy making those styles. Making web designs and playing with colors is my next hobby, I think. Through, those styles are really simple ones, I’m going to add more eventually. Since the project is just hosted on github you are able to push you own styles. If you feel inspired, I would be really happy for submissions.

Nearest plans are apply some fixes for IE (both site and styles) and just go ahead and produce some more. Hope it could be useful for you guys.

NancyFX Migration from 0.9 to 0.10

Recently, I’ve upgraded IdeaStrike project from NancyFX 0.9 to the latest 0.10 version. There were some very unclear moments, fortunately due to great support of @thecodejunkie and @grumpydev they are solved. As a result, the issue 520 was born, that contains a lot of text inside. I’ll try to sum up all important things into one blog post.

Running update

With NuGet updating dependencies is very easy, just run in package manager console:

    PM> update-package

It will give you the information about the upgrade process, it should be very smooth, so the end you will see:

Successfully uninstalled 'Nancy.Hosting.Aspnet 0.9.0'.
Updating 'Nancy.Testing' from version '0.9.0' to '0.10.0' in project 'IdeaStrike.Tests'.
Successfully removed 'Nancy.Testing 0.9.0' from IdeaStrike.Tests.
Successfully removed 'Nancy 0.9.0' from IdeaStrike.Tests.
Successfully added 'Nancy 0.10.0' to IdeaStrike.Tests.
Successfully installed 'Nancy.Testing 0.10.0'.
Successfully added 'Nancy.Testing 0.10.0' to IdeaStrike.Tests.
Successfully uninstalled 'Nancy.Testing 0.9.0'.
The directory is not empty.

Successfully uninstalled 'Nancy 0.9.0'.

Fixing compilation errors

As you try to build the project after upgrade, it would fail because of compilation issues.

If you using Nancy bootstrapper and overriding RequestStratup method, you will see that method had changed the signature:

    // in 0.9
    protected override void RequestStartup(ILifetimeScope container, IPipelines pipelines);

    // in 0.10
    protected override void RequestStartup(ILifetimeScope container, IPipelines pipelines, NancyContext context)

So, it now receives additional parameter - NancyContext.

Next compilation errors is inside the Request.Headers.AcceptLanguage.

    // in 0.9
    public IEnumerable<string> AcceptLanguage { get; }

    // in 0.10
    public IEnumerable<Tuple<string, decimal>> AcceptLanguage { get; }

Both of these compilation errors are really easy to fix. See changes to src/Ideastrike.Nancy/IdeastrikeBootstrapper.cs in this commit.

After that, the compilation will be fine. I had to restart my Visual Studio after, since NCrunch was failing to compile the application.

Fixing failing unit tests

After VS is restarted and NCrunch able to pick up changes, I got 3 unit tests failures. All of them with the similar exception, like:

    System.Exception: System.Exception : ConfigurableBootstrapper Exception
    ---- Nancy.RequestExecutionException : Oh noes!
    -------- Nancy.ViewEngines.ViewNotFoundException : Unable to locate view '404'. Currently available view engine extensions: sshtml,html,htm,cshtml,vbhtml
    at Nancy.Testing.PassThroughErrorHandler.Handle(HttpStatusCode statusCode, NancyContext context)
    at Nancy.NancyEngine.CheckErrorHandler(NancyContext context)
    at Nancy.NancyEngine.HandleRequest(Request request)
    at Nancy.Testing.Browser.HandleRequest(String method, String path, Action1 browserContext)
    at Nancy.Testing.Browser.Get(String path, Action1 browserContext)
    at IdeaStrike.Tests.IdeaStrikeSpecBase1.Get(String path, Action1 browserContext) in D:\Development\Projects\Ideastrike\tests\IdeaStrike.Tests\IdeaStrikeSpecBase.cs:line 85

That was a mystery. All of those tests were fine, but suddenly stopped to work in 0.10.

The reason was very interesting. Those tests for views were actually never run. It’s been unseen for 2 reasons: Nancy 0.9 failed silently about missing view, IdeaStrike unit tests never tested view content.

To make those run, the IdeaStrikeSpecBase have to be setup with IRootPathProvider. IRootPathProvider, provides the path root for modules, so views could be located, based on default conventions. I finished up with this implementation:

public class CustomRootPathProvider : IRootPathProvider
{
    public string GetRootPath()
    {
        return Path.GetDirectoryName(typeof(IdeastrikeBootstrapper).Assembly.Location);
    }
}

This root provider is used with spec base class configuration:

public IdeaStrikeSpecBase()
{
 Bootstrapper = new ConfigurableBootstrapper(with =>
 {
  with.Module<TModule>();
  with.Dependencies(_Users.Object, _Ideas.Object, _Features.Object, _Activity.Object, _Settings.Object, _Images.Object);
  with.DisableAutoRegistration();
  with.NancyEngine<NancyEngine>();
  with.RootPathProvider<CustomRootPathProvider>(); // <- Here
 });
}

So, we are saying that root is the same folder as IdeaStike assembly. The problem is that location depends on actual Test runner. In case of NCrunch, it would be some deeply hidden folder in user\AppData\Local\Temp, in case of ReSharper runner it would be temp ASP.NET folder. That’s a little annoying.

Tests were still red, since neither NCrush nor ReSharper is copying actual views into target folder. Fortunately, I found this great article, explaining NancyFX view testing gotchas. I ended up with just saying “Copy if newer” for views under test, so they are in the same folder as target binary. That’s not cool, but currently I see no other option.

After those changes, tests became green, so I run the application. No surprise, it failed to start.

Fixing runtime errors

At the first run, I got nothing more as bunch of Razor compilation errors:

    Error Compiling Template: (51, 18) The name 'Url' does not exist in the current context)
    Error Compiling Template: (61, 33) The name 'Model' does not exist in the current context)
    Error Compiling Template: (68, 26) The name 'Model' does not exist in the current context)
    Error Compiling Template: (78, 7) The name 'Model' does not exist in the current context)
    Error Compiling Template: (83, 31) The name 'Model' does not exist in the current context)
    Error Compiling Template: (88, 14) The name 'Model' does not exist in the current context)
    Error Compiling Template: (103, 14) The name 'Model' does not exist in the current context)
    Error Compiling Template: (118, 14) The name 'Model' does not exist in the current context)
    Error Compiling Template: (132, 25) The name 'Model' does not exist in the current context)
    Error Compiling Template: (234, 19) The name 'Url' does not exist in the current context)

The proposed solution that NancyRazorViewBase should always be specified with generic parameter.

    // in 0.9
    @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase

    // in 0.10
    @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>
     

OK, that helped a little, but right after that error saying System.Web.IHtmlString type is not references:

    Error Compiling Template: (83, 1) The type 'System.Web.IHtmlString' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.)

NancyFX is being developed to be independent of System.Web. It was not totally true for 0.9 with Razor support, but it has been fixed in 0.10. That of cause, brings some surprises. So, if your application is using Razor view engine, you need to do following:

  • update all usages of IHtmlString to use Nancy.ViewEngines.Razor.IHtmlString
  • update all usages of McvHtmlString to use Nancy.ViewEngines.Razor.NonEncodedHtmlString
  • let the razor engine know about system.web (in case if HttpContext is used in layout)
<razor disableAutoIncludeModelNamespace="false">
    <assemblies>
        <add assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </assemblies>
    <namespaces>
        <add namespace="System.Web" />
    </namespaces>
</razor>

Changing the Partial views

After these steps were done, application finally started. But some page gave runtime exception:

Server Error in '/' Application.

Sequence contains no elements

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Sequence contains no elements

My dump analisys showed, that it works fine as soon as I removing partial views:

    @Html.Partial("Shared/Templates/upload.html")
    @Html.Partial("Shared/Templates/download.html")

The reason turned out to be really simple. All templates in IdeaStrike project were using .html extension. For 0.10 it required to be .cshtml. So, renaming from .html to .cshtml made the IdeaStrike up and running again.