Monday, January 13, 2014

Getting you started with Knockout.js

I produced this video to help you get started with Knockout.js. Expect an explanation what knockout is, the pattern it uses and examples to get you on the way.
It's nearly 10 minutes. Enjoy.


Monday, June 11, 2012

Uploading a file with a MVC single page web application

A single page web application is a great user experience. There is just one page in the browser window and everything is handled via Ajax requests in the background.

But what if you want to upload a file? Due to security reasons, file upload is only possible with a <Input type=”file”/>. This element is typically present in a html form with a submit button. But that’s no option for us. Submitting a form the regular way will require the controller to redirect and this will cause a page refresh.

There are several solutions available. If you want to do it without external libraries, you can post to a hidden IFrame. But this is a crude way to do it anyway, because there is no feedback to the user about what’s going on.

You can also use the excellent library PlUpload which supports different plugins/systems such as Flash, Silverlight and HTML5 and falls back to them according to configuration.

Or, you could use the XMLHttpRequest object in javascript. You’ll need version 2 which is available in all latest browsers (except IE9, but it will be in IE10). Together with this object there is the FormData object. This encapsulates well.. form data :-) You can assign any data to it which is normally part of a form, including a file. Then use the XMLHttpRequest object to post it to the server.

We just need this HTML (don’t need a form):

<input type="file" id="fileUpload" name="fileUpload" />
<
progress max="100" value="0">0%</progress>
And now for the javascript:
upload: function (uploadElement) {
var file = uploadElement.files[0];
if (file) {
var formData = new window.FormData();
formData.append(file.name, file);
formData.append("id",someId);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) //done
{
var response = $.parseJSON(xhr.responseText);
if (response.message) {
$('#uploadMessage').text(response.message);
}
if (response.success) {
$('#uploadMessage').text("");
}
}
};
xhr.open('POST', SomeController/FileUpload, true);

// Listen to the upload progress.
var progressBar = document.querySelector('progress');
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
}
};

xhr.send(formData);
}
}

The function accepts an uploadElement, which is the <input type=”file”>. Just select it with jQuery or regular javascript and send it as a parameter to this function.


You can see the FormData object being created and the values assigned to it. “someId” could be an ID for an entity this document will be saved with or whatever.


I’ll come to the onreadystatechange event later on. Supply the url to your controller method with the open call to the XMLHttpRequest object. You can also see XMLHttpRequest also supports upload progress with an convenient event.


Now, for the server side:


 

[HttpPost]
public ActionResult FileUpload(Guid id)
{
var file = Request.Files[0];
try
{
if (file != null && file.ContentLength > 0)
{
var user = SessionStore.GetUser();
if (user.DocumentUploadLimitMb < file.ContentLength / 1024 / 1024)
return Json(new { success = false, message = "Upload limit exceeded" });
var entity= repository.GetOne(id);
entity.DocumentFileName = file.FileName;
var fileData = new byte[file.ContentLength];
file.InputStream.Read(fileData, 0, file.ContentLength);
entity.Document = fileData;
repository.Update();
}
}
catch (Exception)
{
return Json(new {success = false});
}

return Json(new {success = true});
}

You’ll see I’m using a JsonResult to send back a JSON object indicating success or failure and optionally a message. Now look back to the Javascript function. I’m parsing the Json to an object and use the data to give the user feedback.


In this case I’m storing the document to a database. I’m using EF code first here and the Document property of entity is a byte[].

Thursday, February 9, 2012

Getting started with ASP.NET MVC in VB.Net

Yesterday I talked about MVC at a VB.Net usergroup called VBCentral here in The Netherlands.

If your game is VB and you want to get started with MVC, you’ll maybe find the attached zipfile helpful. It contains a few sample projects and Powerpoint slides. They’re in Dutch, but if you can’t read Dutch, the sample projects should get you started.

Hope you’ll have as much fun with MVC as I have.

Click here to download the zip file.

Friday, November 4, 2011

Entity Framework code first: cannot serialize ICollection

If you’re creating something that serializes your entities to XML (such as WebAPI), you’ll get an exception if you try to serialize an entity with an ICollection in it, something like “cannot serialize an interface”. ICollection is used in EF code first to create navigation properties to linked entities.

Solution: just use something that implements that interface. Easiest for me is a generic List.

Wednesday, November 2, 2011

Knockoutjs and ASP.NET MVC: a winning team

Knockoutjs is a Javascript library that enables you to do the MVVM pattern on the client side, in the browser. Having done projects using the MMVM with Silverlight, I absolutely love the concept. The biggest pro for me is that the pattern enables complete separation between view and code. And that results in cleaner, more maintainable code. Controls in the view are data bound to properties in the viewmodel and the viewmodel takes care of loading and saving data.

Knockoutjs lets you do that in Javascript. So you define a viewmodel in Javascript and that gets bound to the view, the HTML. For me, the biggest advantage of this compared to Silverlight, is that this runs on every platform.

The role of MVC is to provide the view and to make CRUD operations available for the viewmodel. You can also choose to let a WCF Restful service cover the CRUD operations.

First, include knockoutjs in your page:

<script src="@Url.Content("~/Scripts/knockout-1.2.1.js")" type="text/javascript"></script>

So: let’s setup a viewmodel:

var contactsViewModel = { contactName: ko.observable('Bert') };

I strongly recommend putting the viewmodel in a separate js file, which you also include in your page.

This simple model has a variable declared as a Knockout observable. Observables enable you to bind to the view (the HTML) in a two-way manner. That means if the viewmodel changes, the view changes and vv. The way to assign a value to an observable, is calling it as a function and then give the new value as a parameter.In the view, you can databind to this model in the following manner:

<span data-bind="text: contactName"></span>

Now, when ever the contactName observable changes, the text in the span will change. Note the special knockout attribute data-bind. You can bind to a out of the box set of attributes, or create your own binding.

To enable the binding you have to call

ko.applyBindings(contactsViewModel);

to create and enable all the bindings in your view. Do this after the page has rendered. You can just add a little script section on the bottom of your page or create a callback like this:

$(function () { // Document is ready ko.applyBindings(contactsViewModel); });

Don’t make the mistake to do this call every time the viewmodel data changes. It’s just a one time call per page.

Now, why is MVC so great to use in combination with Knockout? You can use all the greatness of MVC like partial views, sections, layout pages to create your views. Then, apply bindings in the view like I showed you. Furthermore, you’ll probably come to a point where you want to fill your view with data. MVC’s controllers are very handy with supplying this data in a way that Javascript natively understands: Json format. You can just call these controller methods from your Javascript in an easy way, with Ajax if you want.

This method delivers a real smooth user experience and really clean, structured, maintainable Javascript code. I always dislike writing Javascript, because it tends to turn into spaghetti real easy. One you get the hang of MVVM with Knockout, you’re in for a treat!

Please watch this space for a new episode, where I will setup the server side with MVC and get some data asynchronously.

Tuesday, October 18, 2011

Windows 8 brings a new option for us developers

Yes, I was in Anaheim. And yes, I got the nice tablet with Windows 8 developer preview!

win8tab-g

Windows 8 brings a new option for us developers: The “Metro Style App”. Metro style apps are well.. metro style. They support live tiles (the big, new touch oriented icons on the new Windows 8 desktop), which convey actual information about the app tFive-Charms-Windows-8hey represent. Also, the app itself is touch oriented and uses the new standardized ways to access the menu and to share information with other apps using “charms”.

Most importantly, these apps access the Windows API directly, using WinRT. WinRT is not COM, it’s a new way for programmers to access Windows. It exposes itself to various platforms: as a assembly for .Net for example. But also to Javascript and C++.

For .Net developers that means that you can use WinRT in the same way as you use any assembly. The .Net framework is available too. (Some types that doesn’t make sense anymore with WinRT are left out.)

It’s possible to write one part of your app in .Net and another in Javascript or C++. I think this is great, because each of these environments have their own advantages. .Net is great because of the rich framework, Javascript has some great libraries with stuff .Net is not very good at (think geo location for example) and C++ is great for apps that demand the very best in performance.

WinRT is only available on Windows 8. For the first time in a while we can develop an application that isn’t compatible with an earlier version of Windows.

I think WinRT will be a great new way to develop apps for a specific platform. It will take at least a couple of years before the most part of us will use Windows 8, but that doesn’t mean Metro Style apps shouldn’t be on your radar.

A major opportunity is the app store that is going to be introduced in Windows 8. Right now it’s empty and we are in the front row to fill it. And make money in the long run.

What if you have to develop an application that doesn’t fit into Metro style, such as an app that needs a lot of text entry?
Or if you want the app to run on a broader range of platforms? Your customer needs an application yesterday and obviously doesn’t want to wait until Windows 8 is out.
Then just keep on doing what you’re doing right now. Silverlight, WPF, ASP.NET, MVC are all here to stay.

Thursday, October 13, 2011

Dependency injection and Entity Framework: creating an interface for your datacontext class using a custom T4 template

If you, like me love dependency injection, maybe you have asked yourself why the custom template of EF doesn’t generate and interface for the datacontext class.

Well, the good news is, you can easily do that by creating a custom T4 template. EF generates code using a T4 template. If you don’t specify one, it just uses the default built-in template.

Matt Hidinger writes about the steps to take in  his blog.

An additional note I struggled with at first: When you click “Add code generation item”, a T4 template (with the tt suffix) is created. The default template is initially copied. Also, EF configures your model to use that template, instead of the default one. It does so by setting the “Code generation strategy” property to None. The generated code will not be in a file called {modelname}.designer.cs (or vb), but in a file called {templatename}.cs/vb.

I recommend that you do not name your interface IDatabase, but give it a significant name. For example {projectname}DataContext .

And an additional tip: It’s great to add at lease SaveChanges() to the interface. Be careful not to put it in the foreach. So the interface looks like this:

public partial interface IDatabase
{
<#
        foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>())
        {
#>
            IObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> <#=code.Escape(set)#> { get; }
<#
        }
#>
            int SaveChanges();
}