Thursday, February 18, 2016

IEnumerable missing from platform 5.4 class lib

I was converting some code to use the new project templates for .net platform 5.4.  I love how it is setup for sharing by default by producing nuget packages.  I'll have to setup a private nuget server for my sharing code and I'll be sure to write about that when I get there.

Interestingly, the first couple projects I created had no minimal problems and I was able to produce nuget packages quite easily.  Yay.

This time around, however, I was refactoring out some models and interfaces for my web application and I ran in an interesting error...

The type 'IEnumerable<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

So, I'm thinking it must be some other error in the project, surely IEnumerable is in there somewhere, right?  WRONG!

Googling around found minimal information that was complete so I figured I'd put together the pieces.  This post got me in the right direction.

 Before:

 "frameworks": {
    "net451": {
      "dependencies": {
        "System.ComponentModel.Annotations": "4.0.0"
      }
    },
    "dotnet5.4": {
      "dependencies": {
        "Microsoft.CSharp": "4.0.1-beta-23516",
        "System.Collections": "4.0.11-beta-23516",
        "System.ComponentModel.Annotations": "4.0.11-beta-23516",
        "System.Linq": "4.0.1-beta-23516",
        "System.Runtime": "4.0.21-beta-23516",
        "System.Threading": "4.0.11-beta-23516"
      }
    }
  }

After:

  "frameworks": {
    "net451": {
      "dependencies": {
        "System.ComponentModel.Annotations": "4.0.0"
      },
      "frameworkAssemblies": {
        "System.Runtime": "4.0.10.0"
      }
    },
    "dotnet5.4": {
      "dependencies": {
        "Microsoft.CSharp": "4.0.1-beta-23516",
        "System.Collections": "4.0.11-beta-23516",
        "System.ComponentModel.Annotations": "4.0.11-beta-23516",
        "System.Linq": "4.0.1-beta-23516",
        "System.Runtime": "4.0.21-beta-23516",
        "System.Threading": "4.0.11-beta-23516"
      }
    }
  }

Saturday, February 13, 2016

Creating a Derived Knockout Binding

public class Person
{
    [DataType(DataType.Date)]
    [Column(TypeName = "Date")]
    public DateTime DateOfBirth {get;set;}
}
When returning a Person object from a WebAPI, the JSON looks like:
{
  DateOfBirth: "1990-01-01T00:00:00"
}
When trying to bind this to a date input type using Knockout.js
  <input data-bind="value: DateOfBirth" type="date" />
you will notice that the rendering of the control is the one used when the value is not set and is not initialized properly.

I figured I could update the view model that does the fetching to replace all date string before loading model types or create a binding that handled the possibility of this date format.

I decided to try the latter and create a binding that works similar to the value binding except that it first checks the format of the date input string and updates it to one that works with the date input type.
ko.bindingHandlers.dateValue = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        if (/^\d\d\d\d-\d\d-\d\d(T\d\d:\d\d:\d\dZ?)?/.test(valueAccessor()())) {
            valueAccessor()((valueAccessor()() || "").substr(0, 10));
        }

        ko.bindingHandlers.value.init(element, valueAccessor, allBindings, viewModel, bindingContext);
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.bindingHandlers.value.update(element, valueAccessor, allBindings, viewModel, bindingContext);
    }
}
In the above example, I assume that the binding will be applied to date input types and that the model property is an observable containing the date.  In the init function, I simply get the value from the value accessor and test it's format.  If it matches, I convert to the format required by date input types by simply taking a sub string.   Then I call the value binding's init function, passing along all the parameters.  In the update, I simply call the value binding's update function, passing along all the parameters.

In the knockout documentation, they describe a way to register a preprocessor function on existing bindings, but this method effectively creates a derived binding, similar to how a derived class would be created.  This could also be considered a wrapper around the existing value binding.

This was simpler than I thought it would be!

Tuesday, February 2, 2016

Typing data returned from a WebAPI

I'm a huge fan of where modern web development is headed.  My current technology stack is ASP.NET MVC 5 & WebAPI 2 using ASP.NET Identity to provide social integration.  On the client, I really like Knockout.js because it handles just model binding.  Currently, I also use jQuery for it's promises and ajax, but I think there is probably a better (more light-weight) solution for just that and I will be looking to replace it.

While I have been interviewing, I have noticed that Angular often comes up while talking about ASP.NET MVC and that drives me crazy, crazy.  Firstly, if you are going Angular, why are you using ASP.NET MVC with IIS?  I like having ASP.NET handling my routing, security, data validations, ... and let knockout handle just the model binding on the front end.  If you are using Angular just for model binding, I would image you are pulling in way more than needed.  Similar to my using jQuery for just the ajax / promises :)

With that out of the way, I can focus on the real task at hand....

How to handle data returned from a WebAPI

Ok, so that's a broad topic.  Let's narrow it down to a few categories:

Display Only Data

This type of data is only used to display something to the user.  They are not going to manipulate this data.

In this case, I have seen examples of folks generating interfaces for the data and using that where needed.  An example would look like:

C#
public class MyListItem
  {
    public int Id { get; set; }
    public string Title { get; set; }
  }
TypeScript
 interface IMyListItem {
    Id: number;
    Title: string;
  }
However, I prefer to use types instead.
 type MyListItemInfo = {
    Id: number;
    Title: string;
  };
This seems to be a more appropriate indication of the expectation of the data.

If I were to call some ApiController method that returned a list of these, it may look something like this:


[HttpGet]
[Route("")]
public async Task<MyListItem[]> GetItems()
{
        return await this.Request.GetOwinContext().Get<ApplicationDbContext>().Items.ToArrayAsync();
}

//[{Id:1, Title:"Red Hat"}]
GetItems() : JQueryPromise<MyListItem[]> {
    return $.getJSON("http://mysite.com/api/items/");
}

At this point, my javascript code has to hope for the best.  It is being handed JSON from some external source which may not be under our control.  Indicating that it is some type which the designated shape better defines the data.  If we were to return it as an interface, that may indicate that we have ensured the created javascript code actually implements the interface.

The following would be an appropriate use of interfaces:

class MyListItem implements IMyListItem {
 Id: number;
 Title: string;
 // prefer to accept the type when loaded from external
 constructor(initial?:IMyListItem/*MyListItemInfo*/){
   this.Id = initial && initial.Id;
   this.Title = initial && initial.Title; 
 } 
}; 

class ItemManagementViewModel{ 
 private urlBase: string; 
 constructor(urlBase: string){ 
   this.urlBase = urlBase; 
 } 

 // actually implements IMyListItem
 GetItems() : JQueryPromise<IMyListItem[]>{
   return $.getJSON(this.urlBase)
           .then(result => $.map(result, r => new MyListItem(r)));
 }
}


Read / Write Data

This type of data is meant to be downloaded and presented to the user for possible manipulation. In this case, I'd like to have a editable version of the object.

class MyListItemEdit {
    // cannot edit Id; it's an identifier for what we have just edited
    Id: number;
    Title: KnockoutObservable<string>;
    constructor(initial?: MyListItemInfo){
        this.Id = initial && initial.Id;
        this.Title = ko.observable(initial && initial.Title);
    }
}


[HttpPost]

[Route("save")]
public async Task<int> SaveItem([FromBody]MyListItem toSave) {
  var item = await 
  this.Request
      .GetOwinContext()
      .Get<ApplicationDbContext>()
      .Items
      .FirstOrDefaultAsync(x => x.Id == toSave.Id);
   if( null == item ){ throw new ArgumentException(); }
   item.Title = toSave.Title;
   return await this.Request
      .GetOwinContext()
      .Get<ApplicationDbContext>().SaveChangesAsync();
}

// notice that we have to project into the edit type
// this is why I prefer the edit type to take a type
// and not an interface
GetItemsForEdit() : JQueryPromise<MyListItemEdit[]>{
   return $.getJSON(this.urlBase)
           .then(result => $.map(result, r => new MyListItemEdit(r)));
 }

SaveItem(toSave: MyListItemEdit) : JQueryPromise<number>{
   return $.ajax({
      url: this.urlBase + 'save',
      method: 'POST',
      contentType: 'application/json',
      dataType: 'json',
      data: JSON.stringify(ko.toJS(toSave))
   });
 }



To this end, I was about to create a tool to generate these typescript files from C# types, but I stumbled across this article regarding generating these files using TypeLite.  I like that it was built on top of T4 templates and will be giving this a shot.  I am going to try an manipulate the template to generate types instead of interfaces and to create edit types that take the type as constructor argument.