Wednesday, August 3, 2011

Introducing MVVM and customizing the UI by role

First we will add a View-Model layer behind the home page, and customize the UI based on the role of the logged in user.

Authentication data is provided by several ASP.NET tables.

The Web.config file in the project contains various configuration parameters, two if which are:
  • roleManager
  • authentication
Added details for membership, roles, and authentication to Web.config file. Had to change all names which referred to SLEventManager, to Eveneter. Not sure if this was really needed.

Adding a property for the dbName and connection string to Web.config

Done adding everything. Now when I run the application, I get an error message:

--------------------------------------------------------------
Error 1 The "CreateRiaClientFilesTask" task failed unexpectedly.
System.Web.HttpException (0x80004005): Sections must only appear once per config file. See the help topic for exceptions. (C:\Documents and Settings\pshah\my documents\visual studio 2010\Projects\Eventer\Eventer.Web\web.config line 53) ---> System.Configuration.ConfigurationErrorsException: Sections must only appear once per config file. See the help topic for exceptions. (C:\Documents and Settings\pshah\my documents\visual studio 2010\Projects\Eventer\Eventer.Web\web.config line 53)
at System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags, PolicyLevel policyLevel, Exception appDomainCreationException)
at System.Web.Compilation.ClientBuildManager.EnsureHostCreated()
at System.Web.Compilation.ClientBuildManager.CreateObject(Type type, Boolean failIfExists)
at Microsoft.ServiceModel.DomainServices.Tools.CreateRiaClientFilesTask.CreateSharedTypeService(ClientBuildManager clientBuildManager, IEnumerable`1 serverAssemblies, ILogger logger)
at Microsoft.ServiceModel.DomainServices.Tools.CreateRiaClientFilesTask.GenerateClientProxies()
at Microsoft.ServiceModel.DomainServices.Tools.CreateRiaClientFilesTask.ExecuteInternal()
at Microsoft.ServiceModel.DomainServices.Tools.RiaClientFilesTask.Execute()
at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean& taskResult) Eventer

--------------------------------------------------------------

This does not make any sense. The said configuration element is not even present in my file, and there is definitely nothing like this at line 53.

Going to try doing a Google search. Looks like this problem was happening because the 'profile' element was specified multiple times. Nothing in the error message said that. Bad ... very bad.

Fixed that error and running the test. I am able to load the login form, but cannot login with credentials specified in the tutorial. Since I do not get a connection error, I am assuming that there is no problem with the database connection. Perhaps the data does not exist? I opened the data table from the database configuration view, but that shows me the schema, and not the data.

Since I cannot login with the provided credentials, I will register a new user. I was able to do that successfully, and could also login with that user. I will use this account for the time being.

Create the Register For Event Functionality:
I added the StackPanel (containing the Register for Event functionality) after the current StackPanel as suggested in the tutorial. But I get some compilation errors. Instead of using that code, I added a StackPanel, within which I added GridPanel, and within that I added two buttons - one for registration and one for deregistration.

The tutorial says, that now we need to add a new class for the View Model, called ViewModelBase. However, it does not say which folder this class should be put in. Also the suggested shortcut SHIFT-ALT-C, does not add a new class in VisualStudio2010, with Silverlight 4.0.

We need to create the base class ViewModelBase, because when an attribute changes in the ViewModel, the UI will have to be updated, This is usually done by implementing INotifyPropertyChanged. We provide a default implementation for this interface in the ViewModel base class.

I created ViewModelBase and also put the code specified in the tutorial in that class. However, I totally o not understand the code. A lot of questions come to mind, perhaps some of them will be answered as I move ahead in the tutorial.

Next I created the ViewModel folder which will contain specific ViewModel classes. Specific ViewModel classes are created in correspondence to specific view XAML files. I am not sure why we did not create ViewModelBase in the ViewModel folder.

Created a class called HomeViewModel.cs in ViewModels folder,a nd made it extend ViewModelBase.cs

THERE ARE WAY TOO MANY THINGS THAT DO NOT WORK AS EXPECTED IN THIS COURSE, WHICH IS A FIT INFURIATING FOR A BEGINNER. I AM GOING TO CREATE ANOTHER COURSE WHICH WILL HOPEFULLY HAVE MORE THINGS WORKING AS THEY SHOULD.





Introducing the View Model

So far we have used data forms provided by WCF RIA services to talk to the data. This is fine for small applications or for certain data objects, but once the application grows, the state we want to show the user may not be in 1 - 1 correspondence with the database tables.

We also do not want to show all the data views to all users, we would like to control the access of what a user does in the system.

Putting all our data access code in the XAML code behind, is not good from the perspective of testability.

For all the above reasons, we usually add a layer between the View (XAML and it's code behind), and the model (domain service classes), to perform all the the above tasks. This layer is the View-Model layer.