.NET, Silverlight, WCF RIA Services, WCF, RIA »

[14 Jul 2011 | 0 Comments]

Just a quick heads-up: in case you haven’t noticed, Silverlight Show started publishing e-books a few weeks ago.  These provide a convenient way to read up on some of their most popular article series, including source code, while you’re offline.

 

I’m glad to announce that two of my article series are now available as e-books:

 

 

Happy coding! :-)

.NET, Featured, Silverlight, Headline, WCF »

[18 Feb 2011 | 0 Comments]

cow_clipartAfter my previous post on how to use a Channel Factory in Silverlight, I received quite a few questions through Twitter, the main one being: “how do you pass in parameters to an operation?”  Next to that, someone also suggested to use a custom binding with binary encoding instead of the default basicHttpBinding.  So I decided to write a post explaining how to achieve those two things – welcome to part 2: binary cows & new-born calves! :)

 

First up: passing in parameters to the operation.  To keep in theme with the last solution, we’re going to allow the user to create a new-born calve on the client, and send that to the server.  For the sake of the demo, the only thing we’ll do on the server is fill out the correct ImageUri, and we’ll send the resulting Cow object back to the client. 

 

public Domain.Cow AddCow(Domain.Cow newBorn)
{
    newBorn.ImageUri = new Uri(http://localhost:5873/calve_clipart.png, 
UriKind.Absolute);
  
    return newBorn;
}

 

The part that confused some people was how to write the correct async signature to match the regular operation contract.  It’s actually quite simple: in the Begin method, you should add the parameter(s) you want to pass in before the IAsyncResult and state parameters:

 

[OperationContract(AsyncPattern = true)]
IAsyncResult BeginAddCow(Cow newBorn, AsyncCallback callback, Object state);

Cow EndAddCow(IAsyncResult result);

 

To call this method, you should write code like this:

 

private void AddCowExecution()
{
    Cow newBorn = new Cow() { Name = "New born" };

    // call CowService WCF service
    ICowService channel = GetCowServiceFactoryChannel();

    var y = channel.BeginAddCow(newBorn,
       (asyncResult) =>
       {
           // add Cow
           var returnVal = channel.EndAddCow(asyncResult);

           Deployment.Current.Dispatcher.BeginInvoke(() =>
           {
               // add to collection
               Cows.Add(returnVal);
           });
       }
       ,  null);
}

 

Now, how do you make sure you use binary encoded messages through a custom binding?  Two things should be done for this: when creating the Channel Factory on the client, you should create your custom binding and pass that in.  On the server, you need an endpoint that uses the same kind of custom binding.  That means you have to change two things: first, the client-side code: we create a custom binding and add the necessary binding elements (binary encoding over http transport):

 

CustomBinding customBinding = new CustomBinding();
customBinding.Elements.Add(new BinaryMessageEncodingBindingElement());
customBinding.Elements.Add(new HttpTransportBindingElement());

EndpointAddress endpointAddress = new EndpointAddress(CowServiceEndpointAddress);
CowServiceChannelFactory = new ChannelFactory<ICowService>
(customBinding, endpointAddress);

 

… and then the web.config to make sure it has a correct endpoint: define the custom binding, and add the binding & binding configuration elements to your endpoint:

 

<bindings>
    <customBinding>
        <binding name="ChannelFactoryWithCows.CustomBinaryBinding">
            <binaryMessageEncoding />
            <httpTransport />
        </binding>
    </customBinding>
</bindings>

 

and:

 

<service name="ChannelFactoryWithCows.Web.CowService">
    <endpoint address="" binding="customBinding" 
              bindingConfiguration="ChannelFactoryWithCows.CustomBinaryBinding" 
              contract="ChannelFactoryWithCows.Contracts.ICowService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>

 

So there we go – we now have a cow farm, compressing the cows before travel and allowing new calves to be born :-)  You can download the source code here.

.NET, Featured, Silverlight, WCF, Headline »

[7 Feb 2011 | 0 Comments]

cow_clipartFor a lot of application scenarios, adding a service reference to easily access a service from Silverlight is the way it’s done (note: I’m not going to get into a discussion on whether this is good or evil, I’m just stating a fact ;-)) – you don’t have to worry too much about proxy creation, for example, that’s done for you.  However, in quite a few scenarios, this approach isn’t feasible: if you’re writing a framework, you typically don’t want service references in your Silverlight class libraries.  If you want to make your app pluggable or extendable – for example: through a provider pattern – you might want to create channels conforming to a contract and call the methods as such.  Or you might just not like the generated code you get when adding a service reference.

 

Well, you can avoid using service references by working with a Channel Factory.  Included with this post is a small application which calls a service method, using a Channel Factory, to populate a list of cows.  What?   Cows.

 

 

Disclaimer: I’m not exactly sure who’s blog it was that contained sample code with cow entities, but I kinda liked the idea (at least it’s a nice change from the typical AdventureWorks entities :)). 

 

By the way, did you know a cow only becomes a cow once it starts giving milk?  Which farmers make sure they do by impregnating them regularly (or, to be more precise: they let bulls take care of that part for them :))?  I actually thought that was quite cruel when I found out.  Anyway, enough of this bucolic intermezzo, on to the code ;-)

 

This is what the application looks like:

 

slchannelfactorywithcows

 

The service itself is pretty straightforward: a standard WCF service, using basicHttpBinding, implementing the ICowService interface, containing one operation: GetCow(), returning a Cow entity.

 

namespace ChannelFactoryWithCows.Contracts
{
    [ServiceContract(Name = "ICowService")]
    public interface ICowService
    {
        [OperationContract]
        Cow GetCow();
    }
}

 

Now, what do we need to create a channel?  We need to know the binding – check.  We need to know the endpoint address – check.  And we need to know the contract – and this is where the fun starts.  We can’t just create a channel of type ICowService, as this is a sync contract, and as you know: service calls in Silverlight are async.  What we need to do is create a client side contract with async methods matching the GetCow() method.  The contract thus looks as follows:

 

namespace ChannelFactoryWithCows.Contracts
{
    [ServiceContract(Name = "ICowService")]
    public interface ICowService
    {
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginGetCow(AsyncCallback callback, Object state);

        Cow EndGetCow(IAsyncResult result);
    }
}

 

BeginGetCow and EndGetCow are the matching async methods for GetCow(), and by providing the ServiceContract attribute with the name ICowService, we effectively match ICowServiceClient with ICowService: we can create a channel of type ICowServiceClient which matches a service implementing ICowService, and call the appropriate methods on it!

 

As we’re going to use a Channel Factory, there’s no automatic proxy generation, so we need to have a Cow class in the Silverlight application.  The important thing to notice about this class is that it must match the Cow class on the server side – this is necessary, as .NET doesn’t know how to cast a “MyApp.Web.Cow” object to a “MyApp.Cow” object.  There are various ways to solve this: one way would be to write code to allow implicit casting, another way would be to create the class on both client and server and have them reside in the same namespace.  In this example, I took another approach: I created a Silverlight class library containing the Cow class, which is referenced by both the Silverlight app and the Web app – this immediately shows off a SL4/.NET 4 feature: you can reference SL assemblies in projects using the full .NET framework.

 

What’s left is effectively creating the channel and calling the service method in an async way.  This is not different than regular async programming, as you can see below:

 

private ICowService GetCowServiceFactoryChannel()
{
    // create ChannelFactory?
    if ((CowServiceChannelFactory == null)
        || (CowServiceChannelFactory.State == CommunicationState.Faulted))
    {
        BasicHttpBinding basicHttpBinding = new BasicHttpBinding();

        EndpointAddress endpointAddress = 
new EndpointAddress(CowServiceEndpointAddress); CowServiceChannelFactory =
new ChannelFactory<ICowService>(basicHttpBinding, endpointAddress); } // create channel? if (CowServiceFactoryChannel == null) { CowServiceFactoryChannel = CowServiceChannelFactory.CreateChannel(); } return CowServiceFactoryChannel; }
private void GetCowExecution()
{
    // call CowService WCF service
    ICowService channel = GetCowServiceFactoryChannel();

    var y = channel.BeginGetCow(
       (asyncResult) =>
       {
           // get Cow
           var returnVal = channel.EndGetCow(asyncResult);

           Deployment.Current.Dispatcher.BeginInvoke(() =>
               {
                   // add to collection
                   Cows.Add(returnVal);
               });
       }
       , null);
}

 

Just one more thing: as you can see, I’m calling Dispatcher.BeginInvoke in the callback method.  This is necessary because we’re accessing the UI thread; omitting this will result in an invalid cross thread access exception.

 

And with that’, we’re done! Using this method, you can write highly reusable code: just pass in a matching endpoint, and your code will work.  Next to that, any service implementing your contract can be used, so you could easily create, for example, a mocking service.  Happy coding! :)

Silverlight, .NET, WCF RIA Services, RIA, WCF »

[24 Jul 2009 | 0 Comments]

When working with RIA Services, a lot of your code is generated automatically, but you'll still need to write quite a lot of custom methods and you'd typically write them in your DomainService-class.  But what if you add an Entity to your datastore?  What if you want to add some CUD-operations next to the read-operation that's been generated?  Either you'd have to write the Entity-classes and methods manually (a lot of work for something that could be generated), or you'd have to delete your DomainService and re-add it (so the newly added Entities/Queries get generated), but then you'd lose all the custom methods you've written in your DomainService...

 

Bummer, huh?  Well, luckily, there's a nice workaround for this!  Imagine you've written a DomainService filled with custom queries, ServiceOperations, ..., working on an Entity Framework domain model.  All of a sudden, a table has to be added to your domain model, so you need to regenerate your DomainService: delete and re-add, thereby losing your custom methods.  It would be nice if you could just put your custom methods in a seperate file, so deleting the DomainService wouldn't delete those methods.  And you can!  The magic word here?  Partial classes!

 

As an example, I've changed my demo-app around a bit: it now only shows the customers beginning with a certain string.  To get this behaviour, I've added a new query method, GetCustomersByFirstLetters, which accepts a string.  I'm passing this as a query to my LoadOperation when loading the items for my DataGrid:

 

   1: LoadOperation<Customer> loCustomer = CDC.Load(CDC.GetCustomersByFirstLettersQuery("a"));


 

But, instead of adding this custom method to the CustomerDomainService.cs-file, I've created a new file, and named it CustomerDomainService.partial.cs.  In this file, I define a class like this, and add my new method to it:

 



   1: public partial class CustomerDomainService : LinqToEntitiesDomainService<AdventureWorksLTEntities>


   2: {


   3:     public IQueryable<Customer> GetCustomersByFirstLetters(string firstLetters)


   4:     {


   5:         return this.Context.Customer.Where(c => c.CompanyName.StartsWith(firstLetters));


   6:     }


   7: }


 

Notice the "partial" keyword? Now, in my original CustomerDomainService.cs-file, I've also changed the class signature to include the "partial" keyword.

 



   1: [EnableClientAccess()]


   2:     public partial class CustomerDomainService : LinqToEntitiesDomainService<AdventureWorksLTEntities>


 

When you build and run this, you'll see the app behaves just as you'd expect it to - but thanks to the fact that the custom method is now in a separate file, you'll no longer lose it in case you have to recreate your DomainService.  All you have to remember is to add the "partial" keyword to the class definition of your generated DomainService, and you're done! :-)

 

What has happened here?  Well, the "partial" keyword actually tells .NET that your class has been split over multiple class definitions/files.  When you build your app, the compiler will combine all the "partial"-classes with the same signature into one class, just as if they were defined in the same file.

 

I'm pretty sure the need for deleting & recreating your DomainService will be fixed in one of the next drops (after all, the "Update from Database"-option didn't exist in the first versions of the Entity Framework either), but until then, this should be quite a handy tip.  Enjoy! :-)

 

Adjusted sourcecode has been posted here if you'd want it.

Silverlight, .NET, WCF RIA Services, RIA, WCF »

[23 Jul 2009 | 1 Comments]

Since the previous part in this series, the final version of Silverlight 3 has been released, and a new version of RIA Services has been released: the July 2009 drop.  This release includes quite a few changes, so I had to change my demo source code around quite a bit to make it work with the new release.  This post details the changes that have been made - and a new sourcecode download is included as well! :-)

 

First of all, in the previous drop, you'd often bind to completed and/or submtted-handlers on your DomainContext.  This behaviour has been changed, together with the way loading is done.  Now, we'd typically use a LoadOperation<type> for this.  Eg, instead doing something like this:

   1: // init domaincontext, load customers


   2: context = new DomainService1();


   3: myDataGrid.ItemsSource = context.Customers;


   4: context.LoadCustomer();



which would automatically execute the GetCustomer method (and eventually bind a handler to the submitted-event), you'd now do something like this:




   1: CustomerDomainContext CDC = new CustomerDomainContext();


   2:  


   3: public MainPage()


   4: {


   5:     InitializeComponent();


   6:  


   7:     LoadOperation<Customer> loCustomer = CDC.Load(CDC.GetCustomerQuery());


   8:  


   9:     EventHandler handler = null;


  10:     handler = (send, args) =>


  11:         {


  12:             // do stuff after entities have been loaded


  13:             myDataGrid.ItemsSource = loCustomer.Entities;


  14:             loCustomer.Completed -= handler;


  15:         };


  16:     loCustomer.Completed += handler;


  17: }



(first thing you'll notice: I've used names that make sense now ;-))


What happens here is that the LoadOperation will now take care of executing a query (the one you pass in, an EntityQuery - these are automatically generated from your server side query methods) and thus filling its EntityCollection.  If you need to subscribe to said events, you can find 'em on the LoadOperation.  So: the LoadCustomer-method is no longer generated on your client.  Instead, a GetCustomerQuery-method is generated, which you now pass to a LoadOperation to make sure it gets executed.  This is actually quite a nice model to work with - for one, you can now check for each LoadOperations's completed event, instead of just checking the completed event on your full context!


Next to that, the demo solution also had a means of submitting changesets.  This, too, has been changed around.  Previously, submitting changes would call context.SubmitChanges().  Now, submitting changes on your context can return a SubmitOperation.  In this SubmitOperation, you can check if any errors have occurred, and you can execute some code you want to be executed after submit:




   1: private void btnSubmitChangeSet_Click(object sender, RoutedEventArgs e)


   2: {


   3:       if (!CDC.IsSubmitting)


   4:       {


   5:           if (CDC.HasChanges)


   6:           {


   7:               CDC.SubmitChanges(OnSubmitCompleted, null);


   8:           }


   9:       }


  10: }


  11:  


  12: private void OnSubmitCompleted(SubmitOperation so)


  13: {


  14:       EntityChangeSet currentChanges = CDC.Entities.GetChanges();


  15:       grdChanges.DataContext = currentChanges;


  16:  


  17:       if (so.HasError)


  18:       {


  19:           MessageBox.Show(so.Error.Message);


  20:       }


  21: }



As you can see, checking for changes is still possible by getting the EntityChangeSet from the context's GetChanges()-method.


New sourcecode has been uploaded, feel free to check it out. 

Silverlight, .NET, WCF RIA Services, RIA, WCF »

[4 Jul 2009 | 1 Comments]

In the first part of this series, I talked about some general concepts, and went into reading, updating, adding, deleting data using RIA Services.  If you haven't read it yet, you might want to read up on that, and maybe read up on the introductory post as well.

 

In this part, I'll talk about an interesting option you have when updating your data: the change set.

 

As some people asked for it, I've uploaded the sourcecode of my demo project.  This code will be updated with every new part in the series.  To use the demo code, you'll need to change the connection string for the Entity Model to your own local copy of the AdventureWorks SL database - once that's done, you're ready to go! :-)

 

As mentioned in the previous part, persisting your changes to the underlying datastore boils down to calling SubmitChanges() on your (clientside) DomainContext.  This will automatically make sure the correct server side methods (in the demo: InsertCustomer, UpdateCustomer or DeleteCustomer) are called for each of your entities. 

 

Then what is a change set?  A change set should be seen as a complete collection of all the changes you've made on your context, before having them submitted and thus persisted to your datastore.  This principle makes sure server-side methods don't have to be called every time you make a change to your data: the changes will be tracked client-side, and will be submitted once you explicitly call SubmitChanges() to persist your change set.

 

To visualize this, I've added a few things to the demo application.  To the right side of the datagrid, there's a grid which will track the changes.  This grid contains some textblocks, bound to the number of modified, added, removed entities, and it contains a reject & submit button:

 

image

 

Now, to track the changes, I need to get the changeset from my DomainContext.  I will do this in my datagrid's RowEditEnded-event (which gets fired right after I've edited a row), and this change set will be the datacontext of the grid used to track the changes:

 

image

 

As you can see, context.Entities.GetChanges() returns an EntityChangeSet.  This object contains a list of changes, divided into different lists for AddedEntities, ModifiedEntities, ...  (I've also added a way to delete items from the datagrid, have a look at the source code for that.) 

 

So, now we've got a list of changes, and thanks to some databinding, these changes are automatically reflected in our UI.  Now, we need to submit or reject this change set.

 

Rejecting changes is easy: just execute RejectChanges() on your context, and every change you've made that hasn't been submitted yet will be undone.  To submit your changes, call the SubmitChanges()-method on your context:

 

image

 

There is, of course, more to it than just that.  When you submit your changes, a few things will happen.  This is what will be done on your DomainService after you've called that command (copy/paste from the RIA Services documentation):

1. Submit – the service entry point that receives the changeset and begins the changeset processing pipeline
2. AuthorizeChangeSet – Verifies Permission/Authorization for each operation. If any operations are not permitted, processing stops and an error is returned to the client
3. ValidateChangeSet – Validation for all operations in the changeset is run. If any operations fail validation, processing stops and errors are returned to the client
4. ExecuteChangeSet – The corresponding method for each operation in the changeset is invoked. This is the point in time when your business logic is run. If any operations failed, processing stops and errors are returned to the client
5. PersistChangeSet – At this point all the domain operations have been executed, and this method is called to finalize the changes.
6. ResolveChangeSet – If there were any optimistic concurrency errors, this method is called to resolve them.

 

All these methods are virtual, so they can be overridden as needed!  As you can see, a few things can go wrong (eg, something isn't valid, the necessary permissions aren't available, ...), so it's important to include error handling.  To do this, add an event handler to your context's Submitted-event:

image

 

By the way, this is not enough for correct, complete error handling.  For example, in this demo it's quite easy to change the ID of a customer to something that's not valid anymore - best way to solve this is, of course, make sure it's not editable (an internal ID is NOT something you'd want to be editable), or not visible.  But this does show that not all errors are caught: it isn't exactly a Conflict (used for concurrency) and it isn't exactly a a ValidationError (no validation exists on that field) either.  So while this specific example isn't something that would occur in real-life situations, it does show that it's important to put validation on your data where needed AND to include some more general error handling in your code.

 

But as far as change sets are concerned: you're done!  This is what change sets can mean for you - using them carefully will make sure you don't have unnecessary client-server-communication, and thanks to some databinding, you can easily track the changes in your UI. 

 

Stay tuned for the next update, in a few days! :-)

 

Sourcode download.

Silverlight, .NET, WCF RIA Services, RIA, WCF »

[18 Jun 2009 | 2 Comments]

Welcome to the first in a series of RIA Services How-To's.  Unless mentioned otherwise, all these tidbits will use the latest drop of RIA Services (at the moment, this is the May 2009 drop).  When new drops arrive, changes may have to be made, inherent to beta software. 

 

But, first things first: how do you start using RIA Services?

 

Step 1:  getting started

 

Start a new Silverlight-project.  Assuming you've installed everything correctly (I'm using the May drop of RIA Services, SL3 beta, VS2008 SP1), you'll notice a new checkbox, "Link to ASP .NET server project".

 

image

 

If you check this checkbox, RIA Services will be enabled.  You'll end up with 2 projects as usual: your Silverlight-app, and a webapp hosting this Silverlight-app.  You'll notice extra references added to your project to enable RIA Services. 

 

Tip: you can enable or disable this ability later on, by looking at the project properties of your SL app: you'll notice a combobox, ASP .NET Server Project Link.  Here, you can select the webproject you'll want to link to to use RIA Services.  This effectively means you can enable RIA Services on existing applications, simply by selecting a webproject from your solution.

 

Step 2: your datastore

 

You'll need to add some kind of datastore to your webapp.  It doesn't really matter what kind of store this is: it can be an Entity Framework model, but might as well be some simple POCO classes with dummy data.  The client (your SL-app) doesn't need to know what kind of datastore you have - it's totally unaware of this.  I've installed the Lite version of the AdventureWorks-DB, and will use a few tables from it.  So, I right-click my webapp and choose to add a new ADO .NET Entity Model, and select the Customer and CustomerAddress tables from AdventureWorksLT.  I end up with something looking like this:

 

image

Step 3: expose your data

 

Here's where the magic begins! ;-) You need to expose your data to your SL-app.  To do this, you need to create a DomainService.  This is a new class, with which RIA Services will take care of sharing your data/methods across tiers.  To add one, right-click your webapp -> add new item -> Domain Service Class.  Give it a name, and you'll see a screen looking like this:

 

image

 

Of course, you need to check "Enable client access".  :-)  Next, select the datacontext you wish to expose.  In this example, it's the AdventureWorksLT-model I created in the previous step.  Now, you can select which enitities you want to add to your Domain Service.  For each entity you select, methods will automatically be generated to read data from your datastore, and if you check "Enable editing", subsequent insert, update and delete-methods will be generated. 

 

Tip: if you don't see your datacontext in the dropdownlist, build your application before adding the domain service class.

 

Last but not least, you can also check "Generate associated classes for metadata".  When this is checked, a metadata-class will be generated, allowing you to do stuff like validation accross tiers, define how your data should look when using a dataform, ...  I always check this option (do you know a lot of apps that don't require validation or don't require the need do define how your data should look? ;-)), but I'll go into detail on that in a future post.

 

Now, click "OK", and... magic! Visual Studio will start generating lots of code.  On your webapp-side, you'll see your DomainService-class.  It contains all the necessary CRUD-methods (GetCustomer, InsertCustomer, ...).  You can add methods to this class, or change the existing methods as needed: this is the place where you'd put your application logic:

 

image

 

Now, build your solution.  If you check "click all files" on your Silverlight-app, you'll notice a new folder, called, "GeneratedCode".  This is essentially the client-side, generated code that corresponds with the server-side methods.  It contains client-side versions of the classes (entities) you've exposed through your DomainService-class. It also contains a DomainContext, which is the client-side representation of your server-side DomainService.  Through this context, you can access all the functionality of your domain service.  You'll also notice the DomainContext containing Load-methods for your entity-lists.

 

image

Tip: the names of these methods are automatically generated - by default, an entity "Customer" will have a "GetCustomer"-method server-side, and a "LoadCustomer"-method client-side.  If you want to choose what name the generated client-side method must have, you can use the [Query]-attribute.  Check my previous post for more info on that.

 

Step 4: accessing your data from your SL-app

 

All necessary code has been generated, so now you need to access this data from your Silverlight-application.  As I explained, on your client, Load-methods have been generated (methods like this will be generated for every method you write in your server-side domain service class which returns an IQueryable list).  First, you need to instantiate your client-side generated DomainContext.  You'll notice that that instance contains the generated Load-Methods, and also collections of your entities (eg: the Customers-property is actually an EntityList of Customer):

 

image

 

Now, you want to call the client-side LoadCustomer-method to load the customers.  When this statement is executed, the GetCustomer-method on your server-side DomainService will be executed.

 

image

 

To display the data you've got in your app, bind it to, for example, a datagrid.  You'll end up with something looking like this:

 

image

 

And you're done! ;-) As you'll notice, you've also got events on your DomainContext like Loaded / Loading / PropertyChanged: you can add Event Handlers to these as needed.

 

Step 5: adding, deleting, updating your data

 

Next steps are of course deleting, adding, updating, ... your data.  This is actually quite simple: what you need to do is manipulate the EntityLists you've got in the DomainContext on your client side: Customers, for example.  Add elements, update elements or delete elements from that list.  Now, your DomainContext instance has a method called SubmitChanges & RejectChanges.  As you might have guessed by now, executing the SubmitChanges-method will persist the changes you've made on the collections to your database (it will call the corresponding server-side methods for this automatically).  RejectChanges, well, rejects your changes ;-)  There is, of course, much & much more to this - you can work with transactions, changesets, check for changes, et cetera - more on that in one of the next articles. 

 

That's it! This article should've covered the basics of working with RIA Services.  I hope this helps some of you out - check back regularly for more! ;-)

 

A word of advice: RIA Services is beta-software, and lots of code gets generated automatically.  In most scenario's, you'd want to split your Domain Services into another namespace (or even assembly).  However: this doesn't really work as you'd expect at the moment of writing.  You'll notice code generation going bonkers when trying this, so for now: just keep everything in the same namespace.  I assume (hope ;)) this will be fixed in future drops.