Monday, July 25, 2011

Creating a track and session hierarchy

In this exercise, we want the user to be able to view/edit tracks for the events. Since each event can have multiple tracks, this exercise will show us how to deal with master-detail relationships.

First, the tutorial says that our default applications, DomainService only returns a list of Events and not the Entities which are related to the Event. We could get it to do a lazy fetch, but they suggest that we replicate the GetEvents() method and refactor it so that it returns the Tracks and Talks also.

I created a new method in EventManagerDomainServices.cs, which will return the Tracks and Talks for the events. This method is for the EntityFramework. BY adding this method we are enhancing the Entity Framework's functionality.

public IQueryable GetEventsWithTracksAndTalks()
this.ObjectContext.Events.Include("EventTracks.Talks");
}

We will make our Event DataGrid bind to this Query.

&<riaControls:DomainDataSource
    AutoLoad="True"
 &;nbsp;  d:DesignData="{d:DesignInstance my:Event, CreateList=true}"
    Height="0"
    LoadedData="eventDomainDataSource_LoadedData"
    name="eventDomainDataSource"
    QueryName="GetEventsWithTracksAndTalks"
    Width="0" Margin="0,0,320,480">
  <riaControls:DomainDataSource.DomainContext>
    <my1:EventManagerDomainContext />
  </riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>

However, this is not enough. We have enhanced the Entity Framework, but we also need to tell RIA services to include this data. By default RIA services is very restrictive, and will not include the data.

[Include]
EntityCollection EventTracks { get; set; }


Adding the include annotation to the EventTracks property will ensure that the data comes from RIA Services.

Now we need to select Event.EventTracks from data sources, and drop it on the view next to the Event details grid. In Silverlight when we select a dependant property, it will automatically be bound to the selected master record.

What this means is that we will only see related Event Tracks, depending on the Event which is selected.

Creating New Events in the Application

In this exercise, we will add the functionality to create new events in the application. I think we should be able to reuse a good amount of code we wrote to edit events.

First, we will add another button to the main page (Home.xaml) for creating new events.

I opened Home.xaml, selected a button from the Toolbox, and dropped it into the view for Home.xaml. Next, I repositioned the button, and changed a few properties, such as the text, name, etc.

Next, I created the click handler, in which I added code to create an event with some placeholders, and then navigate to the edit page to edit it with actual data. I do not like this way of doing things. What if the user does not put in actual data immediately. Then we will have an application with a bunch of phantom events. Why can we not straight away ask the user for details, and then save the event only when the use creates the details.

Anyways, got the application working till now. I am able to create new events. However, from a usability perspective, when we save an event, at the moment we do not get any notification. At least we should take the user back to the HomePage so they can view the updated list. Implemented this feature by invoking NavigationService.Navigate in the click handler of the 'Save' button.

The lab page for the assignment explains why we create a new domain context object instead of re-using the one we already have (similar to the the domainDataSource object we used in editEvent... though I do not know what scope this object is available in, and how/(if at all) it is shared among the views).


Silverlight Assembly related problems keep on recurring

I am again getting the assembly related errors. Specifically it seems that it cannot generate the client side code for the Silverlight application. The error I am getting is:

CreateRiaClientFilesTask task failed unexpectedly. The reason is that it could not load some file from the assembly. Or at least that is what I think it is, because I get a FileNotFoundException somewhere in the call stack. I am not quite sure what an assembly is. Is it a file, or a dll, or a bunch of files? A bit of reading also seems to suggest that the real problem could be something else, which is not being reported correctly.

Anyways, I think the first thing I should do is turn on FusionLogging (here's how), which logs assembly related errors.

I opened the VisualStudio SDK CMD prompt, and types fslogvw.exe, which opened up the 'Assembly Binding log viewer'. However, the log viewer does not show me any error messages, whereas VS2010 does have the same errors. Someone on StackOverflow mentioned that it might help if we setup a custom path for logging. Great... I s now have a custom path for logging. Setting a custom log location got it to work. Gosh this is really crazy. I had no idea Microsoft products were so buggy.

Now, very interestingly, once I had the logging working, and I rebuild the application (for the nth time today), it just started working. I seriously do not know what to make out of all this. I am trying hard not to curse :-)

I guess I will leave this issue as it is for now, and revisit it when it crops up again.

Wednesday, July 20, 2011

Editing Entities

I am now watching the 2nd video in module 2, which describes how to edit Entities. Completed watching the video, but I will not post the timeline or notes right now. I want to do the lab, and then re-watch the video (will post the timeline then).

Moving on to the lab:
First we need to create an EditEvent page. Created the EditEvent.xaml page using the Silverlight Page template. This template also created EditEvent.xaml.cs, a C# file (which I suppose is the client code referred to in the video).

Next, I opened the Data Source window, selected Event (selected 'Details' from the drop down in front of 'Event'), and dragged the control onto the EditEvent page.

Next, I created an 'Edit' button, which we will click to edit the selected Event. The Button got created in the center of the screen under the datagrid control. I am unable to move it by dragging and dropping... I know there has to be a way to do this. Plan 2 is to try to re-position it by specifying location parameters for the button in the XAML file. I think I am unable to move the button because it is in a StackPanel. If it were in a Grid, then I would have been able to move it. However, the DataGrid control (IIRC) needs to be in a Panel container, so we may have to add a Grid to the Stack Panel and then add the Button inside the Grid.

I then added a click handler to the button, so we can Navigate to the EditEvent page. This page is given a query string which has EventID=id, where id is the id of the selected Event.

The application runs, but I realized that whichever button I click, the EditEvent page shows the same event for editing. This is because the EditEvent page still does not do anything with the EventID we passed it. We need to implement the method 'OnNavigatedTo'. In this method we will get the EventID from the url and then create a filter which will determine which record to show.

// Executes when the user navigates to this page.


protected override void OnNavigatedTo(NavigationEventArgs e)
{
string eventId = NavigationContext.QueryString["EventID"];
eventDomainDataSource.FilterDescriptors.Add(
new FilterDescriptor
{
PropertyPath = "EventID",
Operator = FilterOperator.IsEqualTo,
Value = eventId
});
}



I got the edit screens, and then added a Save button. The Save button's event handler calls submitChanges on the DomainDataService



eventDomainDataSource.SubmitChanges();



This is very interesting. I read that the client part of the domain data service, keeps track of which properties on all the Entities have changed. When we call the above method, it will save all changed Entities. So RIA services manages all the batching. I guess this batch might be run in a transaction, or perhaps we can configure it to run either way...


Got the basic infrastructure in place. I am able to select an Event, click on the Edit button, and the Edit Event page shows up. However, when I edit the Event details, and click on 'Save' the Event does not get saved.

I put a breakpoint in the Event handler code to find out what is happening, and it seems that an Exception is being thrown. (sidenote: Since the compiler did not force me to catch the exception, C# either does not have checked exceptions, or this particular Exception is a runtime Exception). This happened because I had not checked the 'enable editing' checkbox while creating the ADO Data Model. This problem can be resolved by creating placeholder methods in the domain service class for basic CRUD operations.

However, since I wanted to practice doing the project again, I deleted the project and recreated it, this time being careful to select the 'enable editing' checkbox.

Everything is working fine, however I keep running into the 'code generation' errors. Not quite sure why...


Tuesday, July 19, 2011

Add data bindings and domain context

Opened the 'data sources' view, and selected 'Event', and dragged it into the main view area of Home.xaml .

I opened the data sources view, selected 'Event' and dragged it into the main area of Home.xaml . Then I resized the control to make it larger, and tried to test it by right clicking the project from the solution view, and selecting 'view in web browser'.

This did bring up the browser, and started initializing the Silverlight plugin, but stalled at 100%. Then I tried doing a CTRL-F5 on the project, and that worked just fine.

I am not sure why the former option did not work. Asked on the course forum.

Now I am able to view event data in the browser from the application.

Creating domain services

Now that we have the Silverlight application, the database, and the Entity Data Model, we will now create the Domain Service class for the Entitites. I am not totally sure what the Domain Service will do, but I think it provides classes and API's which the application can call from the client side Silverlight control.

I right clicked on the 'Services' tree node, and selected, 'Add new'. Then I selected the 'Domain Service' class template, gave it a name, and selected the Entities we want to expose in the Domain Service.

Some noteworthy points and questions:
  1. What exactly is a domain service class?
  2. The domain service class extends the class 'LinqToEntitiesDomainService'
  3. The domain service class has the [EnableClientAccess()] annotation. Is this really an annotation, or is it something else. The () seem to suggest that it is invoking some method, so this might be a special syntax to specify that some internal method needs to be invoked at some time. Is this at build time, runtime ? Not quite sure.
  4. The entire namespace is enclosed in {}
  5. A file called EventManagerDomainService.metadata.cs was also created. This file has a bunch of partial classes. Need to find out what partial classes are.

Monday, July 18, 2011

Database woes

Now that the project is created, I need to connect it with a database. The tutorial template comes with an mdb file, which I can use to create the database.

I selected app->data and tried to create a database by selecting the mdb file which came with the tutorial. However, I was not able to create the database. I got an error message which said that SQL Server 2005 Express or 2008 Express should be installed. I thought that VisualStudio 2010 came with SQL Server 2008 Express... oh well...

I downloaded SQLServer 2008 Express with Tools and
tried to install it. The installation exited with an error message because .NET 3.5 SP2 was not installed. I think I must have uninstalled it when I removed all instances of SQL Server from my system.

Installing .NET 4.0 now... installed.
Ran the SQL Server installer again, but I get the same error. Looks like it either works only with .NET 3.5 or maybe .NET 4.0 does not have something which .NET 3.5 has. A Google search revealed this post, which suggests that the .NET 4.0 client profile may not be good enough... we might need to install the whole deal (whatever that is...)

I am a bit irritated with this whole dependen
cy nonsense... MS you really need to get your act together.

I am now installing .NET 3.5 with SP1. I hope it does not conflict with the .NET 4.0 I already have installed on my system. Hopefully, I will be able to install SQL Server after .NET 3.5 .

Now, I have .NET 2.0, 3.5 SP1, and 4.0 all installed on my machine. SQL Server dost thou needest anything more ?

Running SQL Server 2008 express installer again. This time I ran into an application error related to landingpage.exe which is described very well on this page. As suggested, I deleted the Microsoft_Corporation folder.

This time the installation failed because Windows Power Shell was not installed, and apparently it is a pre-requisite for SQL Server 2008 Express. Oh well and on we go... trying to get Windows Power Shell.

Installed Windows Power Shell 1.0 ... re-running the SQLServer rules

At some point in the installation (server configuration) I got an error message which said that the credentials I have provided are not valid. I have not provided any credentials. Some Googling suggested that there is a drop down list in the username section. We should select any item and make sure there is no password. Did that and it worked. Account names are as follows:

SQL Server Database Engine : NT AUTHORITY\SYSTEM
SQL Server Browser NT AUTHORITY\LOCAL SERVICE

Selecting mixed mode for authentication (SQL Server Authentication and Windows Authentication)

Finally SQL Server is installed. I CANNOT BELIEVE THIS!

Next, I went back to the project, right clicked on 'App_Data', and selected the mdf file for this lab from the downloaded tutorial labs. It seemed to have accepted the mdf and looks like things are moving ahead.

Just to verify, I double clicked on the database, which opened the database viewer. The database shows several Event Application related tables, as shown in the image below.



Create The Entity Data Model:
Since we want to be able to access the server side Entities in the Silverlight client, we need to create the Entity Data Model. I right clicked on the Eventer2.Web node in the Solution Explorer. Then I selected C#->Data and selected 'ADO.NET Entity Data Model'. I set the name to 'EventManagerDBModel', and then in a later wizard screen, specified that the model needs to be created from an existing database (SEventManager.mdf). Clicking on Finish, finally showed me the data model for the application.

Next, I rebuild the project, because without that the EDM we just created would not be available to RIA services link.


Thursday, July 14, 2011

Creating the first project

I watched the first video in module 2, which discussed RIA Services and Data Binding.

Here is the timeline (as relevant to me)

[00:00] Introduction
[01:13] The WCF RIA Services link (what will this do?)
[03:24] RIA Domain Service
[06:11] Data Binding
[06:45] Creating New Project
[08:46] The login and registration pages
[09:18] Adding data to the application (along with the Entity Data Model and Domain Service)
[12:40] Adding a data grid
[13:57] Launch the application in the browser

My Notes:

We do not need to write DTO by hand, no dealing with concurrency, RIA also does pagination and change tracking

DomainServices provides methods which can be accessed on the client. It usually consists of methods which will provide us with basic CRUD services (auto generated which can be refactored by us)... The Entity class can be implemented by one of many technologies... the client gets the domain context through which it can call methods of the domain service.

RIA Services also give us automated data binding

The client.bin folder contains the build output which is the xap file.

We do not necassarily have to use the Entity framework

RIA services provides observable collections which will observe the data in the actual database tables

RIA services automates a lot of things which we would have to otherwise write by hand


Creating the project: working on Activity 1

The first thing I need to do is create a new Silverlight Business Applications Project. I opened Visual Studio 2010, and selected "new project", then selected "Visual C#". On the right hand side, I should have seen an option to create a Silverlight Business Application, but I see only an option to create a Silverlight Application. Perhaps, I need to install Silverlight Tools for Visual Studio 2010.

I downloaded Silverlight 4.0 tools for Visual Studio 2010. With Silverlight 4.0 tools, I can create a Silverlight Business Application.