The Problem Solver

Tell me and I will forget
Show me and I will remember
Involve me and I will understand
- Confucius -

Google Ads

This Blog

Syndication

Search

Tags

News





  • View Maurice De Beijer's profile on LinkedIn

Community

Email Notifications

Explore

Archives

In deze podcast spreekt Maurice de Beijer met Tom Verhoeff over zijn sessies op de TechDays. Tom presenteerde een sessie over hoe je geld kan verdienen met Windows Phone 7 applicaties. Het lijkt op het eerste gezicht zo eenvoudig, je maakt een app en het geld stroomt binnen. Maar in de praktijk blijkt het toch iets lastiger te zijn en zijn er best wel veel details waar je op moet letten.

 

Links:

 

Je kan hem hier afluisteren.

 

Met dank aan onze sponsor RedGate.
http://www.red-gate.com/

Enjoy!

Posted by Maurice | with no comments
Filed under: , ,

imageOne of the problems with running JavaScript in the browser is that everything usually executes on the same thread as the UI. With most scripts this is fine because they are short executing however if you start doing more complex calculations you might run into the vase where the UI becomes non responsive because of the JavaScript executing. And when that happens you will see one of these dialogs popup and you are at the mercy of the end user, not the best of places to be.

 

Update: Check out these live Simple Web Worker and Chunked Web Worker demos.

 

Fortunately there is a fix for this in the form of the new HTML5 Web Workers specification

Web workers are relatively well supported, IE9 being the big exception, as you can see from caniuse.com. Getting started with them is quite straightforward, basically you create a Worker object and pass it the URL of the script you want to execute. This has to be a URL, you can’t just pass a function, something that would have been handy.

The following HTML page contains all the code required.

   1: <!DOCTYPE html>
   2: <html>
   3: <head>
   4:     <title></title>
   5: </head>
   6: <body>
   7:     <button id='btnStart'>
   8:         Start</button>
   9:     <button id='btnStop'>
  10:         Stop</button>
  11:     <button id='btnPause'>
  12:         Pause</button>
  13:     <button id='btnResume'>
  14:         Resume</button>
  15:     <ul id='primes'>
  16:     </ul>
  17:     <script src="Scripts/jquery-1.7.2.js" type="text/javascript"></script>
   1:  
   2:     <script>
   3:         $(function () {
   4:             var worker = null;
   5:             $('#btnStart').click(function () {
   6:                 if (!worker) {
   7:                     $('#primes').empty();
   8:                     if (!!window.Worker) {
   9:                         worker = new Worker('Scripts/Primes.js');
  10:                         worker.onmessage = function (e) {
  11:                             $('<li>').text(e.data).prependTo('#primes');
  12:                         };
  13:                     } else {
  14:                         $('<li>').text('Web Worker is not supported :-(').prependTo('#primes');
  15:                     }
  16:                 }
  17:             });
  18:  
  19:             $('#btnStop').click(function () {
  20:                 if (worker) {
  21:                     worker.terminate();
  22:                     worker = null;
  23:                     $('<li>').text('Terminated').prependTo('#primes');
  24:                 }
  25:             });
  26:  
  27:             $('#btnPause').click(function () {
  28:                 if (worker) {
  29:                     $('<li>').text('Pause').prependTo('#primes');
  30:                     worker.postMessage('pause');
  31:                 }
  32:             });
  33:  
  34:             $('#btnResume').click(function () {
  35:                 if (worker) {
  36:                     $('<li>').text('Resume').prependTo('#primes');
  37:                     worker.postMessage('resume');
  38:                 }
  39:             });
  40:         });
  41:  
  42:     
</script>
  18: </body>
  19: </html>

 

The important part is the start button:

   1: worker = new Worker('Scripts/Primes.js');
   2: worker.onmessage = function (e) {
   3:     $('<li>').text(e.data).prependTo('#primes');
   4: };

This code creates a Worker object and points it to the JavaScript file to start executing. In this case we are going to calculate prime numbers.

As soon as the Worker has loaded the JavaScript file it will start executing, no need to do anything special.

 

Communicating with Web Workers

The code executing as part of the Worker is completely isolated from the UI document. You can send messages between the two using the postMessage() function but all data will be cloned, no shared references exist. When a message has been posted the other party can specify the onmessage callback and react to the message. The worker has restrictions to the data being passed, the most important one is that nothing related to the DOM can be passed to the worker object and everything that can be is cloned first.

image

A simple implementation of the worker to calculate prime numbers looks something like this. Note the postMessage being used to pass the computed prime numbers back to the user interface,

   1: for (var i = 2; i < 1000000; i++) {
   2:     var isPrime = true;
   3:     for (var d = 2; d < i; d++) {
   4:         if (i % d === 0) {
   5:             isPrime = false;
   6:             break;
   7:         }
   8:     }
   9:  
  10:     if (isPrime) {
  11:         postMessage(i);
  12:     }
  13: }

 

 

Controlling the workers execution

Suppose we want to stop the workers execution there is a terminate() function on the worker which is used in the Stop button.

   1: $('#btnStop').click(function () {
   2:     if (worker) {
   3:         worker.terminate();
   4:         worker = null;
   5:         $('<li>').text('Terminated').prependTo('#primes');
   6:     }
   7: });

This will kill the worker process and that is the end of it, there is no way to restart it. Nice, simple and effective however sometimes that is not quite what we want and we want to restart the worker.

 

Suspending and resuming a worker

Given the fact that we can send messages between the UI and the worker the code below might look like a valid approach. Unfortunately this doesn’t quite work Sad smile

   1: var isPaused = false;
   2:  
   3: onmessage = function (e) {
   4:     if (e.data == 'pause') {
   5:         isPaused = true;
   6:     }
   7: };
   8:  
   9: for (var i = 2; i < 1000000; i++) {
  10:     var isPrime = true;
  11:     for (var d = 2; d < i; d++) {
  12:         if (i % d === 0) {
  13:             isPrime = false;
  14:             break;
  15:         }
  16:     }
  17:  
  18:     if (isPrime) {
  19:         postMessage(i);
  20:     }
  21:  
  22:     if (isPaused) {
  23:         break;
  24:     }
  25: }

 

The problem here is that the postMessage()/onmessage pair works using the event loop and as long as the Web Worker is busy calculating it will never receive the message, instead it will be queued and remain queued until the worker is idle, something that doesn’t happen until all primes have been calculated.

 

Using  a chunking algorithm

The solution is to use a chunking algorithm. This algorithm brakes the calculation into different groups and use the setTimeout() API to execute the next chunk after a small delay. The result of using setTimeout() is that the message posted can be read and we can actually pause and resume the worker execution. Using a chunking algorithm out background worker JavaScript looks like this:

   1: var isPaused = false;
   2:  
   3: onmessage = function (e) {
   4:     if (e.data == 'pause') {
   5:         isPaused = true;
   6:     } else if (e.data == 'resume') {
   7:         isPaused = false;
   8:         testPrime();
   9:     }
  10: };
  11:  
  12: var i = 2;
  13: testPrime();
  14:  
  15: function testPrime() {
  16:     var isPrime = true;
  17:     for (var d = 2; d < i; d++) {
  18:         if (i % d === 0) {
  19:             isPrime = false;
  20:             break;
  21:         }
  22:     }
  23:  
  24:     if (isPrime) {
  25:         postMessage(i);
  26:     }
  27:  
  28:     if (!isPaused) {
  29:         if (i < 1000000) {
  30:             i++;
  31:             setTimeout(testPrime, 0);
  32:         }
  33:     }
  34: }


With this in place we can pause and resume our prime number calculation Smile

 

image

The only problem with this approach is that, in some browsers, it slows down calculations a lot. So instead of doing a setTimeout() after every prime you might want to do so once after a series of numbers has been checked. For example with the code below:

   1: var i = 2;
   2: testPrime();
   3:  
   4: function testPrime() {
   5:     var isPrime = true;
   6:     for (var d = 2; d < i; d++) {
   7:         if (i % d === 0) {
   8:             isPrime = false;
   9:             break;
  10:         }
  11:     }
  12:  
  13:     if (isPrime) {
  14:         postMessage(i);
  15:     }
  16:  
  17:     if (!isPaused) {
  18:         if (i < 1000000) {
  19:             i++;
  20:             if (i % 100 === 0) {
  21:                 setTimeout(testPrime, 0);
  22:             } else {
  23:                 testPrime();
  24:             }
  25:         }
  26:     }
  27: }

 

How about browsers that don’t support Web Workers?

It turns out that using this chunking approach in the UI is a very decent alternative to using a Web Worker as it prevents the user interface from completely blocking. It will still be somewhat slower to respond but is the best you can do in the circumstances.

 

Update: Check out these live Simple Web Worker and Chunked Web Worker demos.

 

Enjoy!

Posted by Maurice | with no comments
Filed under: ,

Last week the question of HTML5 and sensors came up. This wasn’t really strange as we where talking about the HTML5 GeoLocation features and using the, optional, GPS is just one device or sensor you might want to use.

It turns out the W3C has a Device APIs Working Group working on this problem. They are working on a whole range of interesting devices like:

  • Battery Status API
  • Contacts API
  • HTML Media Capture
  • Media Capture API
  • Network Information API
  • Sensor API
  • Vibration API
  • Calendar API
  • MediaStream Capture Scenarios
  • And more..

 

The Sensor API covers a group of others

  • AmbientTemperature   
    A ambient temperature
  • AtmPressure   
    A pressure sensor   
  • RelHumidity   
    A releative humidity sensor   
  • AmbientLight   
    A light sensor   
  • AmbientNoise   
    A ambient noise sensor   
  • DevMagneticField   
    A magnetic field sensor   
  • DevProximity   
    A proximity sensor

Sweet, this should open up some nice capabilities in the future. The problem is that for now this is just one of may standards out there and it seems it will be some time before these standards are actually usable. Guess we have to stick to native clients, or something like PhoneGap, for now.

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under: ,

I hadn’t really been paying attention to the popularity of browsers a whole lot for the last few months until this week as I was teaching HTML5 and the usage stats influence what is usable and what not. Sure I heard some time ago that Chrome was larger then IE but as most of these statistics are more about politics then anything else I tend to ignore them and just check some sites I know are producing real numbers for me. And the best I know way is to compare Google Analytics on some large sites.

 

And was I surprised this week when I checked.

 

These are the stats I collected last December for an HTML5 presentation I did back then:

image

As you can see there are three big players and Internet Explorer was the biggest with a 42% market share. Now your stats may vary slightly but I would be very surprised they where very different for a general purpose website.

 

However when I checked this week things where very different.

image

The total number of visits may be down quite a bit but we arte still looking at more than half a million visits here. And not only did Google Chrome pass Internet Explorer but so did Firefox. And even with the overall traffic being down more than 25% Chrome still manages to get more visits in now then it did in December.

 

Didn’t see that one coming, it sure seems we are living in a very interesting time as HTML5 developers.

 

Enjoy!

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under: ,

jQuery is one of the most useful frameworks out there for web development. And while most of jQuery is very much about working with the browser DOM there is also another side to it that makes doing networking real easy and that is all based around the $.ajax() and related, like the $.getJSON(), functions. Now HTML5 contains a real useful part in Web Workers for doing work that should not block the background thread. And using the XMLHttpRequest for network IO is fine in a Web Worker.

Unfortunately however working with the DOM is not ok in the Web Worker, which makes total sense, but as a result using jQuery, which has lots of DOM related code is not fine in a Web Worker. And that is a shame because using jQuery for just network IO would be much easier that the XMLHttpRequest and totally fine if it would load.

 

So removing the DOM code from jQuery should solve the problem right?

 

 

Enter the jQuery - No DOM Edition

 

It turns out Konstantin Pozin did just that with the jQuery - No DOM Edition Smile

 

You can find it here or download a test version here.

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | 1 comment(s)
Filed under: , ,

In deze podcast spreekt Maurice de Beijer met Patriek van Dorp over zijn TechDays presentatie over NuGet packages voor Windows Azure.

Links:

Met dank aan onze sponsor RedGate.

Posted by Maurice | with no comments
Filed under: , , ,

Here are the slides from my securing REST services session I did at Engineering World 2012.

 

Posted by Maurice | 2 comment(s)
Filed under: , ,

 

You can download the ASP.NET WebAPI demo here and the SignalR demo here.

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under: , , , ,

In this podcast Dennis Vroegop speaks with Jeff Prosise about the future of software development for the .NET developer.

Links:

Thanks to out sponsor RedGate.

 

http://dotned.nl/PodCasts.aspx?id=27

 

Enjoy

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments

Having the ASP.NET Web API as a REST service returning data is kind of nice but to be efficient on the wire we don’t want to return more data that required only to discard it in the client.

 

As we have seen in a previous post just returning a collection data was real easy.

 

As it turns out changing the service so the client can filter data is almost just as easy. In the previous example we returned an IEnumerable<Product>. All we need to do is change this to return an IQueryable<Product> instead of an IEnumerable<Product> and most of the work is done.

   1: public class ProductsController : ApiController
   2: {
   3:     private NorthwindContext _db = new NorthwindContext();
   4:  
   5:     // GET /api/<controller>
   6:     public IQueryable<Product> Get()
   7:     {
   8:         return _db.Products;
   9:     }
  10:  
  11:     // GET /api/<controller>/5
  12:     public Product Get(int id)
  13:     {
  14:         return _db.Products.Single(p => p.ProductID == id);
  15:     }
  16: }

Loading the products with the original URL returns exactly the same result as before.

image

But now the client can also decide to order and filter data. This request “http://localhost:6876/api/Products?$orderby=ProductName&$skip=10&$top=5” returns only product 11 to 15 ordered by the product name.

image

You can also search for specific data using the $filter clause like this “http://localhost:6876/api/Products?$filter=ProductName eq 'Chocolade'

image

Or something like “http://localhost:6876/api/Products?$filter=startswith(ProductName, 'Cha')

image

 

Sweet right? And all of that by just changing IEnumerable<T> to IQueryable<T> Smile 

 

In fact the only thing I would like to see added to this was projections. After all we don’t do a “Select * from Table where …” either right?

 

Enjoy!

Posted by Maurice | 2 comment(s)
Filed under: , , , ,

We where just bitten by this one and the problem was not immediately obvious.

You will see some error like

The name 'model' does not exist in the current context

or

'System.Web.WebPages.Html.HtmlHelper' does not contain a definition for 'ActionLink' and no extension method 'ActionLink' accepting a first argument of type 'System.Web.WebPages.Html.HtmlHelper' could be found (are you missing a using directive or an assembly reference?)

 

image

 

Additionally when you check the IntelliSense of @Html you will not see some of the extension methods like Action() or ActionLink()

 

Fixing it is not hard one you know the problem.

Include the webpages:Version key with a value of 1.0.0.0 in the appSettings section of your web.config, fix the references for System.Web.WebPages and System.Web.Helpers and restart Visual Studio 2010 to fix the problem.

   1: <appSettings>
   2:   <add key="webpages:Version" value="1.0.0.0" />
   3:   <add key="ClientValidationEnabled" value="true" />
   4:   <add key="UnobtrusiveJavaScriptEnabled" value="true" />
   5: </appSettings>

 

See the Known Issues and Breaking Changes in the ASP.NET MVC 4 Release notes. And this only applies to projects created using ASP.NET MVC 3 RTM. The projects created by the ASP.NET MVC 3 Tools Update release are fine.

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | 2 comment(s)
Filed under: , ,

With REST there is not a lot required on the client as far as sending requests goes. As long as you can send HTTP GET requests you are good to go and there are very few programming stacks that don’t allow for some form of doing that. Of course just doing an HTTP GET is going to give you some data back and you still have to understand that data but that is an application specific issue.

In order to make life even easier the ASP.NET Web API adds some client support in the form of the HttpClient class. But first lets see what happens if we just hit an ASP.NET Web API endpoint with a simple client.

I am using Entity Framework Code First here and the model and context look like this:

   1: public class Product
   2: {
   3:     public int ProductID { get; set; }
   4:     public string ProductName { get; set; }
   5:     public decimal UnitPrice { get; set; }
   6: }
   7:  
   8: public class NorthwindContext : DbContext
   9: {
  10:     public DbSet<Product> Products { get; set; }
  11: }
 
And the ASP.NET Web API controller looks like this:
   1: public class ProductsController : ApiController
   2: {
   3:     private NorthwindContext _db = new NorthwindContext();
   4:  
   5:     // GET /api/<controller>
   6:     public IEnumerable<Product> Get()
   7:     {
   8:         return _db.Products.ToList();
   9:     }
  10:  
  11:     // GET /api/<controller>/5
  12:     public Product Get(int id)
  13:     {
  14:         return _db.Products.Single(p => p.ProductID == id);
  15:     }
  16:  
  17:     protected override void Dispose(bool disposing)
  18:     {
  19:         if (disposing && _db != null)
  20:         {
  21:             _db.Dispose();
  22:             _db = null;
  23:         }
  24:         base.Dispose(disposing);
  25:     }
  26: }
 
 
Given that the Web API supports returning both XAML and JSON it would appear the following code would work just fine.
 
   1: static void Main(string[] args)
   2: {
   3:     var baseUrl = @"http://localhost.:6876/api/products";
   4:     var xml = XElement.Load(baseUrl);
   5:  
   6:     foreach (var product in xml.Descendants("Product"))
   7:     {
   8:         Console.WriteLine("Product '{0}' costs {1:C}", (string)product.Element("ProductName"), (decimal)product.Element("UnitPrice"));
   9:     }
  10: }

 

Unfortunately it doesn’t and we receive an XmlException with the message “Data at the root level is invalid”. The reason is that the XElement sends the request to the server without specifying an accept header. And where in the previous WCF Web API this would have worked because XML was the default type if nothing was specified this has changed. With the ASP.NET Web API the default is JSON. So this request returns a JSON data stream the XElement can’t handle. What we need to do is specify we want XML using the HTTP Accept header. There are different ways we can do this but here I am going to the the client side support in the form of the HttpClient.

 

Using the HttpClient

First we need to add a NuGet package named System.Net.HTTP that contains the required classes

image

With that in place we can start using the HttpClient instead. The code is a bit longer but that is mainly because we still need to set the HTTP Accept header to return XML instead of the default JSON

   1: static void Main(string[] args)
   2: {
   3:     var baseUrl = @"http://localhost.:6876/api/products";
   4:     var client = new HttpClient();
   5:     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
   6:     var stream = client.GetStreamAsync(baseUrl).Result;
   7:     var xml = XElement.Load(stream);
   8:  
   9:     foreach (var product in xml.Descendants("Product"))
  10:     {
  11:         Console.WriteLine("Product '{0}' costs {1:C}", (string)product.Element("ProductName"), (decimal)product.Element("UnitPrice"));
  12:     }
  13: }

And this works just fine Smile

image

Loading a single product is just as easy

   1: var baseUrl = @"http://localhost.:6876/api/products";
   2: var client = new HttpClient();
   3: client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
   4: var stream = client.GetStreamAsync(baseUrl + @"\42").Result;
   5: var product = XElement.Load(stream);
   6:  
   7: Console.WriteLine("Product '{0}' costs {1:C}", (string)product.Element("ProductName"), (decimal)product.Element("UnitPrice"));

image

 

Adding new data using the HttpClient

Adding a new product is almost just as easy. First we need to create a valid XML document containing a new product, then turn it into a steam and we can post it.

   1: var newProduct = new XElement("Product", new XElement("ProductName", "ASP.NET Web API"), new XElement("UnitPrice", 0));
   2: var stream = new MemoryStream();
   3: newProduct.Save(stream);
   4: stream.Position = 0;
   5:  
   6: var baseUrl = @"http://localhost.:6876/api/products";
   7: var client = new HttpClient();
   8: var content = new StreamContent(stream);
   9: content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
  10:  
  11: var response = client.PostAsync(baseUrl, content).Result;
  12: Console.WriteLine("StatusCode: {0}", response.StatusCode);

 

This code might seem a bit verbose but that is mainly because the client is real simple and uses POX and therefore a StreamContent. There are also richer ways of doing so with declared types and the ObjectContent<T>. The result is a predictable OK status with the new product being added to the database.

image

Of course this should really have been a 201 Created with the URL pointing to the location of the new resource but we still need to look at how to control the response message from the ApiController.

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under: , , , ,

 

In the previous blog post I demonstrated how to get started with the ASP.NET Web API and retrieve some products data from the Northwind database. Something that was really easy to do Smile But quite often we want to update data just as much as we want to retrieve it.

 

A quick recap of REST and HTTP methods used.

The convention for REST service as defined by Roy Fielding is to use different HTTP methods to signify our intent with the HTTP request. The HTTP GET method, by far the most commonly used one on the internet, is used to retrieve data. This should be a completely save action and have no side effects whatsoever for the client to worry about. When we start changing data we start using other HTTP methods. The following table are the most commonly used HTTP methods and the database CRUD actions they to.

HTTP Method CRUD Action
Get Select
Post Insert
Put Update a complete entity
Patch Update a partial entity
Delete Delete an entity

 

Quite simple right? And even the Patch method isn’t used that often, in most cases just 4 methods are used.

 

Implementing update methods in the ASP.NET Web API

As I explained in my last post the ASP.NET Web API uses convention over configuration and by convention is to create an ApiController with functions where the name starts with the HTTP method to support. We can do things differently with attributes if we want to but for now lets just stick to the convention.

 

Adding new products to the database.

As we have just seen creating new data is done with a POST method so we need to implement a Post() function in our ProductsController. Doing so is quite easy:

   1: public class ProductsController : ApiController
   2: {
   3:     private NorthwindEntities _db = new NorthwindEntities();
   4:  
   5:     // GET /api/<controller>
   6:     public IEnumerable<Product> Get()
   7:     {
   8:         return _db.Products.ToList();
   9:     }
  10:  
  11:     // GET /api/<controller>/5
  12:     public Product Get(int id)
  13:     {
  14:         return _db.Products.Single(p => p.ProductID == id);
  15:     }
  16:  
  17:     // POST /api/<controller>
  18:     public void Post(Product product)
  19:     {
  20:         _db.AddToProducts(product);
  21:         _db.SaveChanges();
  22:     }
  23:  
  24:     protected override void Dispose(bool disposing)
  25:     {
  26:         if (disposing && _db != null)
  27:         {
  28:             _db.Dispose();
  29:             _db = null;
  30:         }
  31:         base.Dispose(disposing);
  32:     }
  33: }

 

Of course in reality a Post action would be somewhat more complicated. For starters we would need some error handling in case the data was invalid. Another issue is that, if everything goes well, we are just returning a 200 Ok status where we should be returning a 201 Created status with the location of the newly created resource. But for now this is good enough.

We still need a way to test this and the perfect tool to monitor and test HTTP related traffic if Fiddler. Using Fiddler we can POST a new product, in this case the ASP.NET Web API itself, to the server.

image

And as we can see when we check the database or use the GET method in the correct URL the new record is inserted.

image

 

There are two interesting things to note here.

  1. All I had to do is have a function were the name starts with Post and it is automatically called when an HTTP POST is received.
  2. The function parameter is of type Product and the ASP.NET Web API does the proper deserialization for us.

How easy can they make things? Smile

 

And implementing PUT and DELETE would work in the same way.

The “complete” ApiController looks like this:

   1: public class ProductsController : ApiController
   2: {
   3:     private NorthwindEntities _db = new NorthwindEntities();
   4:  
   5:     // GET /api/<controller>
   6:     public IEnumerable<Product> Get()
   7:     {
   8:         return _db.Products.ToList();
   9:     }
  10:  
  11:     // GET /api/<controller>/5
  12:     public Product Get(int id)
  13:     {
  14:         return _db.Products.Single(p => p.ProductID == id);
  15:     }
  16:  
  17:     // POST /api/<controller>
  18:     public void Post(Product product)
  19:     {
  20:         if (ModelState.IsValid)
  21:         {
  22:             _db.AddToProducts(product);
  23:             _db.SaveChanges();
  24:         }
  25:     }
  26:  
  27:     // PUT /api/<controller>/5
  28:     public void Put(int id, Product product)
  29:     {
  30:         var orgProduct = _db.Products.Single(p => p.ProductID == id);
  31:         // Copy properties from product to orgProduct
  32:         _db.SaveChanges();
  33:     }
  34:  
  35:     // DELETE /api/<controller>/5
  36:     public void Delete(int id)
  37:     {
  38:         var product = _db.Products.Single(p => p.ProductID == id);
  39:         _db.Products.DeleteObject(product);
  40:         _db.SaveChanges();
  41:     }
  42:  
  43:     protected override void Dispose(bool disposing)
  44:     {
  45:         if (disposing && _db != null)
  46:         {
  47:             _db.Dispose();
  48:             _db = null;
  49:         }
  50:         base.Dispose(disposing);
  51:     }
  52: }

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under: , , , ,

Some time ago I did a number of blog posts about the beta versions of the WCF Web API. As it turns out the WCF Web API team has moved into the ASP.NET team, a good thing as far as I am concerned, and as a result it is now called ASP.NET Web API. Now this is much more that just a name change. For starters there is very little of the WCF bits still involved, in fact when you use ASP.NET as a host none at all. As a result it takes on quite a few characteristics of ASP.NET MVC with convention over configuration. Quite a difference from WCF which is all about taking configuration to the max.

In this blog post I am going to show how to get started with the ASP.NET Web API.

 

What is the ASP.NET Web API all about?

The ASP.NET Web API is a framework build on top of the core ASP.NET engine for creating REST services. And REST services have become relatively popular as a result of the popularity of web and mobile applications where the traditional SOAP service are a bit to rigid and cumbersome to work with. Now this certainly doesn’t mean that SOAP services are going to disappear but we will see an increasing number of REST services as an addition.

On .NET there are a number of different options for REST services. There are some pretty good open source alternatives like OpenRasta. And the WCF team has made a number of attempts at providing a REST framework in the past which where usable but less successful. The WCF Web API was a big improvement as that was much more inline with HTTP, as a RESTful service should be, but the tie to WCF was a bit a problem as the whole WCF stack was architected and build with SOAP in mind.

The ASP.NET Web API should provide a far more flexible framework for building RESTful services.

The ASP.NET Web API bits ship as part of ASP.NET MVC4 beta right now but that doesn’t mean you are tied to using an MVC application. Personally I like MVC but if you prefer ASP.NET WebForms that will work fine, in fact you can use any ASP.NET as a host. For that matter if you don’t want an ASP.NET host it is perfectly fine to self host the ASP.NET Web API in whatever host application you want. Console, Windows Service you name it and it should just work. But I am going to leave self hosting for another post as I suspect most people will host their Web API as part of an ASP.NET web site. So in this demo I am going to use ASP.NET MVC 4.

 

Creating a ASP.NET MVC 4 new application

When you create a new MVC 4 application you get the option of creating a Web API project. There is nothing wrong with that but in this case I am not going to do that and I am just going to create a standard Internet Application and add a Web API to that.

image

I have a copy of the Northwind database on my machine and I am going to create a Web API service to return the products data from that database. So first I need to create a Entity Framework model with the table definition.

image

 

Next we need a controller to return the product data. Instead of a normal MVC controller we should be using an ApiController here. An ApiController is a special type of controller all geared towards creating a REST service. The convention is to store these in an API folder. The same convention as with regular MVC applies so we have to create a controller named ProductsController.
image

The resulting code is quite simple but it shows us how to get started with an ASP.NET Web API controller.

   1: public class ProductsController : ApiController
   2: {
   3:     // GET /api/<controller>
   4:     public IEnumerable<string> Get()
   5:     {
   6:         return new string[] { "value1", "value2" };
   7:     }
   8:  
   9:     // GET /api/<controller>/5
  10:     public string Get(int id)
  11:     {
  12:         return "value";
  13:     }
  14:  
  15:     // POST /api/<controller>
  16:     public void Post(string value)
  17:     {
  18:     }
  19:  
  20:     // PUT /api/<controller>/5
  21:     public void Put(int id, string value)
  22:     {
  23:     }
  24:  
  25:     // DELETE /api/<controller>/5
  26:     public void Delete(int id)
  27:     {
  28:     }
  29: }

In fact if we run the application as is and navigate to the URL for this controller, in my case http://localhost:3438/api/products but your port number is going to be different, we can see it already returns some data.

image

So why does this URL work? Well out of the box an ASP.NET MVC4 project has 2 routes configured. One for the normal controller and the other for Web API controllers. You can find the relevant code in the global.asax.

   1: public static void RegisterRoutes(RouteCollection routes)
   2: {
   3:     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   4:  
   5:     routes.MapHttpRoute(
   6:         name: "DefaultApi",
   7:         routeTemplate: "api/{controller}/{id}",
   8:         defaults: new { id = RouteParameter.Optional }
   9:     );
  10:  
  11:     routes.MapRoute(
  12:         name: "Default",
  13:         url: "{controller}/{action}/{id}",
  14:         defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  15:     );
  16: }

Of course you are free to change the path but for now I am going to leave it as is as the default convention of putting Web API request in an API URL makes sense to me.

 

There are a couple of things to note in the code for the ProductsController. First of all there are no attributes used. WCF was all about attributes, MVC is all about conventions. So the the convention is if the function name starts with Get it will respond to an HTTP GET method, if it starts with Post it responds to an HTTP POST method and so on. You can change this with attributed but it sounds perfectly fine and good enough for me. What matters is the start of the function name. So changing it to GetProducts() will work just fine but using LoadProducts() will result in the following error:

The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.String Get(Int32)' in 'WebAPIDemo.Api.Controllers.ProductsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.

Not quite a clear an error message as I would have liked Sad smile But then it is only a beta so there is hope.


Returning some actual product data from our Web API service

Doing that is actually quite easy. All we need to do is redefine the Get() function to return an IEnumerable<Product>, instantiate a NorthwindEntities context and return the Products collection.

   1: public class ProductsController : ApiController
   2: {
   3:     private NorthwindEntities _db = new NorthwindEntities();
   4:  
   5:     // GET /api/<controller>
   6:     public IEnumerable<Product> Get()
   7:     {
   8:         return _db.Products.ToList();
   9:     }
  10:  
  11:     protected override void Dispose(bool disposing)
  12:     {
  13:         if (disposing && _db != null)
  14:         {
  15:             _db.Dispose();
  16:             _db = null;
  17:         }
  18:         base.Dispose(disposing);
  19:     }
  20: }

Refreshing the page in the browser now returns the products data as expected:

image

Returning the a single product is just as easy. Just implement the Get(int id) function to return the correct Product as follows.

   1: // GET /api/<controller>/5
   2: public Product Get(int id)
   3: {
   4:     return _db.Products.Single(p => p.ProductID == id);
   5: }

 

Not surprisingly just the single product is returned when we add a product id to the URL.

image


That is enough for a first post. Next time I am going to take a look at what it takes to add new or update existing product data using the ASP.NET Web API.

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | 1 comment(s)
Filed under: , , , , ,

In deze podcast spreekt Hassan Fadili Gert Drapers over zijn carrière bij Microsoft en zijn sessies data georiënteerde sessies tijdens de laatste TechDays. Gert vertelt onder meer hoe hij bij Microsoft begonnen is en hoe hij de eerste SQL server tools voor developers, ook wel Data-Dude genoemd ontwikkelt heeft.

Links:

http://www.dotned.nl/PodCasts.aspx?id=26

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under: , ,

The game is on. The competition is open. It's time for FrameRate Fest 2012. Internet Explorer 9 challenges you to play yourself to the front line of HTML5.
 
In this creative competition it's all about building an awesome HTML5 frame. In this year's edition there is an extra challenge: create a small but nice, awesome or freaky game component in your frame. Your ultimate chance to gain fame.
 
Cause we've got a worldwide scoop: a developers Kinect code in combination with your HTML5 game. And you'll be the first one to explore this technique. You like this WOW? You'd better start NOW. Subscribe yourself and let the Frames begin.

 

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under:

In deze, tijdens de TechDays opgenomen, podcast spreekt Maurice de Beijer met Steve Sanderson over de toekomst van web development met de moderne browsers. Ze spreken ondermeer over Knockout.js, een JavaScript library die MVVM stijl databinding mogelijk maakt binnen HTML/JavaScript applicaties.

Je kan de podcast hier beluisteren.

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments

Several people asked about getting the slides and samples from my HTML5 & REST talk at the TechDays 2012 conference in the Netherlands. You can download the slides and the sample if you like.

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under: , , , ,

Several people asked about getting the slides and samples from my HTML5 talk at the TechDays conference in the Netherlands. You can download the slides and the sample if you like.

 

Enjoy!

 

TheProblemSolver
DotNetEvents

imageIn the previous two blog posts about getting started with Knockout.js and controlling updates using Knockout.js I showed to to get started with the awesome Knockout.js library. In this post I am going to show how easy it is to load a collection of items from a REST service and data bind to the complete collection.

To data bind to collections of data Knockout supports the foreach data binding. This lets us point at a collection of data and create a new item for each object in the collection. In the example below I am using an html <table> to display a list of books. The <tbody> has the data binding attribute so its contents are going to be repeated for each item in the collection being used, books in this case.

<table border="1">
    <thead>
        <tr>
            <th>
                Title
            </th>
            <th>
                Author
            </th>
        </tr>
    </thead>
    <tbody data-bind="foreach: books">
        <tr>
            <td data-bind="text: title">
                This will be the title
            </td>
            <td data-bind="text: author">
                This will be the author
            </td>
        </tr>
    </tbody>
</table>

So this looks, and is, very much like a data template but a little different. Normally when using JavaScript templates the actual template is stored as a string somewhere, often in a script block, and you don’t get to see anything until you actually use it. However in this case it is just HTML and without Knockout.js will be rendered as regular HTML. So if we just render this as is we get the following output in the browser.

image

Nice as this makes debugging the data template layout a lot easier. Smile

 

Next we need to create a ViewModel and use Knockout to data bind it.

The basic ViewModel we need is really simple, all it needs to expose is a books array. To make sure the UI is updated with changes we don’t use a simple array but an observableArray as shown below. And if we call applyBindings() the data binding will be activated.

 
$(function () {
    var viewModel = {};
    viewModel.books = ko.observableArray();
    ko.applyBindings(viewModel);
});

With this data binding is functional but we don’t have any data to display yet. As expected this results in an empty array. Notice the data template row is gone now.

image

 

Adding some data is easy. I have included a WCF Web API REST service here and the jQuery.getJSON() function makes it rather easy to consume the REST service with a few lines of code. In this case I am using the jQuery.each() function to process each object returned and I turn them into objects with observable properties, not strictly required here, and push them into the books observable array. This last push will cause the UI to update itself because of the data binding. The complete JavaScript code looks like this:

$(function () {
    var viewModel = {};
    viewModel.books = ko.observableArray();
    ko.applyBindings(viewModel);
 
    $.getJSON("/services/books").then(function (books) {
        $.each(books, function () {
            viewModel.books.push({
                title: ko.observable(this.Title),
                author: ko.observable(this.Author)
            });
        });
    });
});

And the end result:

image

 

Sweet Smile

 

Enjoy!

 

TheProblemSolver
DotNetEvents

Posted by Maurice | with no comments
Filed under: , , ,
More Posts Next page »