The Elephant and the Silverlight

Thoughts and analysis of Silverlight for business applications

Page List

    RIA Services Enterprise Business Application Attempt Part One

    A question that has come up a few times on the forums is how the Silverlight Business Application template can be modified to make it more enterprise friendly. This means moving the Authentication DomainService into a separate WCF RIA Services Class Library and removing the RIA Link from the main application. Attached is my first attempt at doing this. What I have done is create a new WCF RIA Services class library named AppServices. At this point, there is no change in any functionality and other then some namespace differences everything should work exactly like the original template did.

    I have several additional changes that I am planning to make. My planned steps:

    1. Refactor the Business Application Template to use a class library (complete)
    2. Build in the MEF links from Brad's example here
    3. Convert the sample project into a Visual Studio template and add to RIA Services Contrib
    4. Prove the template my re-implementing Brad's PDC demo using the new template

    EnterpriseBusinessApplication08.zip (2.11 mb) C# VS 2008 Version

    BusinessApplicationTemplate.zip (2.19 mb) C# VS 2010 Version

    The part I am most worried about is step 3, converting something this complex into a Visual Studio template is not something I have done before and I am not sure what the best method is to accomplish this. If anyone has any tips or blog urls that I should take a look at please let me know. Also, if you disagree with any design decisions I am making let me know. For example, I am not sure about the AppServices name I picked for the project. 

    Thanks to Max Paulousky who wrote an article on CodeProject that solved a problem I was having with getting the WebContext to find the AuthenticationDomainContext.

    Update: There is now a VS2008 version and I improved on Max's original fix by casting to WebAuthenticationService instead of FormsAuthentication so that the code no longer needs to be changed to switch to WindowsAuthentication. That change was made to both versions. Some people are having trouble with errors saying that a DLL isn't trusted. Brad has a blog entry explaining the problem


    Categories: RIA Services
    Permalink | Comments (32) | Post RSSRSS comment feed

    Comments

    Eric Polerecky United States

    Monday, December 07, 2009 10:25 PM

    Eric Polerecky

    Colin, Is this for SL4 only?

    ColinBlair United States

    Monday, December 07, 2009 10:37 PM

    ColinBlair

    Yes, the version uploaded at the moment is VS2010 only. I will update the post tomorrow with a VS2008 version but I probably will not continue with a VS2008 version when I start using MEF. I will also look at creating a VB version once I figure out how to generate templates correctly.

    Alex Y United States

    Tuesday, December 08, 2009 9:34 AM

    Alex Y

    Thanks Colin,

    It is important to continue with VS2008. Not every company is moving to VS2010 version yet.

    Hombianer Switzerland

    Wednesday, December 09, 2009 12:45 PM

    Hombianer

    Thanks Colin,

    That's great - that's similar the solution we discussed in forums.silverlight.net/forums/p/149128/332409.aspx

    I propose to use the following namespaces in the solution:
    Solution:
    - BusinessApplication.AppServices.Server (DomainService - server part of the WCF RIA Services)
    - BusinessApplication.AppServices.Silverlight (DomainContext - client part of the WCF RIA Services

    - BusinessApplication.MyAppLogic.Server
    - BusinessApplication.MyAppLogic.Silverlight

    - BusinessApplication.Silverlight (XAML-Pages)
    - BusinessApplication.Web (Silverlight Host and other ASPX-pages)

    Use for each WCF RIA Services Class project the Server- and Silverlight part (AppServices.Server, AppServices.Silverlight). May be it's better to use Client instead of Silverlight (AppServices.Server, AppServices.Client).
    To identify the silverlight project use BusinessApplication.Silverlight. In this way it's also better to distinguish from other client devices like WPF, Mobile, ...
    It's a good idea to separate application services (AppServices) from other main application logic (Ex.: MyAppLogic).

    ColinBlair United States

    Wednesday, December 09, 2009 12:57 PM

    ColinBlair

    @Hombianer I actually use the Server syntax on my own application and I call the Silverlight side of the library Domain. That gives me:
    BusinessApplication.AppServices.Server
    BusinessApplication.AppServices.Domain
    BusinessApplication

    If I need to sort out the Silverlight client form other clients then I put it up higher in the namespace (i.e. Silverlight.BusinessApplication). The reason I stuck with the current naming for this example is that it matches both the RIA Services namespaces themselves (The Silverlight DLLs using the Windows namespace and the server DLLs) and what the built in template for creating a WCF RIA Services Class Library uses.

    Due to the namespace naming, I have a guess that eventually the same RIA Services Class Library could be used for both Silverlight and WPF so not putting Silverlight in the name is also a strategic decision for me.

    Bhaskarkiran India

    Wednesday, December 16, 2009 3:46 AM

    Bhaskarkiran

    Hi Colin,

    Thankyou so much for your nice Project.  I was Trying to implement the same technique in my project with SL 4 and VS2010 b2 and i was struggling a lot to implement this.  i have even requested for this solution in SL Blogs http://forums.silverlight.net/forums/t/149311.aspx but i didnt got any response.

    Can you please provide me the Walkthrough for creating this solution.
    Thanks
    Bhaskar

    ColinBlair United States

    Wednesday, December 16, 2009 7:25 AM

    ColinBlair

    @Bhaskarkiran, the article I have linked above from Max Paulousky does have step by step instructions. It isn't exactly the same way I did it but if you want to do it yourself you can follow his steps. It is probably just easier to use my project as is, just go thorugh and change the namespaces and file names to your own project name and take it from there. I do plan to convert this into an actual template file as soon as I can figure out how.

    Bhaskarkiran India

    Wednesday, December 16, 2009 9:23 AM

    Bhaskarkiran

    Thanks Colin,

    I have created it by my self. But when i try to build the project i am getting "The type 'PMT.AppSvc.User' already contains a definition for 'DisplayName'" this error.
    Can you suggest me what could be the possible way to over come this error.

    Thanks

    Bhaskarkiran India

    Wednesday, December 16, 2009 10:32 AM

    Bhaskarkiran

    Colin,

    The error is generating from User.Shared.cs file.

    ColinBlair United States

    Wednesday, December 16, 2009 10:34 AM

    ColinBlair

    First, make sure you do a Clean Solution. When restructuring the template I found that some files got stuck and doing a clean would clear that problem. The DisplayName should only be defined in the shared file in your AppService.web. Make sure you didn't accidentally copy it into your Silverlight project. I just read back through Max's article and he didn't do quite as much as I did. The tricky part for me were getting the resx files shared correctly. I ended up manually editing the project file and copying the resx sections in from the original template's project file. The other piece that I had to change is I changed the ActualPassword field in UserRegistrationService from internal to public. I am putting together a video (no sound, sorry) showing how to setup my template from scratch. Will post later today.

    Bhaskarkiran India

    Wednesday, December 16, 2009 10:54 AM

    Bhaskarkiran

    Colin,

    I did Clean Solution and the previous error has gone, but came up with 2 new errors

    1) 'System.Windows.Ria.WebContextBase.User' is inaccessible due to its protection level in LoginStatus.xaml.cs
    2) The property or indexer 'System.Windows.Ria.WebContextBase.User' cannot be used in this context because the get accessor is inaccessible in LoginStatus.xaml.cs

    and even i am also facing problem in creating Resources as links.  The Resource.Designer.cs files are displaying Separately insted of being in the Hierarchy

    Bhaskarkiran India

    Wednesday, December 16, 2009 11:49 AM

    Bhaskarkiran

    Colin,

    can you please let me know how you have managed the tricky part of Sharing the Resoruces correctly.

    ColinBlair United States

    Wednesday, December 16, 2009 12:10 PM

    ColinBlair

    Here is part 1 of the video I am putting together. The last section is me getting the resources setup:
    http://www.screencast.com/t/NGNiZjg3ZjY

    ColinBlair United States

    Wednesday, December 16, 2009 1:19 PM

    ColinBlair

    The full video is now up including a correction for part 1.

    Jose Luis Latorre Spain

    Wednesday, December 23, 2009 8:36 AM

    Jose Luis Latorre

    Hi Colin,

    Thanks for the great sample!! instructive and clear Smile
    Anyway - how else - I am having a small issue with getting the WebContext .. let's be clear I am trying to go "more far away" integrating RIA Services with PRISM, so on the Silverlight module which is a client of the DomainService website I do not have that WebContext.
    I also can't access it on the module's inicialization routine...
    I have tried to get it on the "Shell", the main application of the PRISM application, which is the main application loaded, there I add a reference to System.Windows.Ria, and the idea was to get the WebContext and initialize the modules with its value.. and then launch an event into the modules.

    Anyway, WebContextBase.Current; (being WebContext from the namespace/assembly System.Windows.Ria) does throw an error to me:
    {System.InvalidOperationException: No contexts have been added to the Application's lifetime objects. For WebContextBase.Current to resolve correctly, add a single context to the lifetime objects.
       at System.Windows.Ria.WebContextBase.get_Current()}  System.SystemException {System.InvalidOperationException}

    So its unclear how should I get this webcontext and pass it to the service for it to work properly...

    Any clues on this?

    Thanks so much Smile

    ColinBlair United States

    Wednesday, December 23, 2009 10:14 AM

    ColinBlair

    @Jose

    You have to have the WebContext in the ApplicationLifetimeObjects for WebContextBase.Current to work. Personally, I have the WebContext in a shared library in my own Prism application and I have it wired up the way that the business application has it. I will probably revisit it later when I have more time to think about it but I am using Windows Authentication on an intranet application so modularizing the WebContext and AuthenticationService is pretty low on my todo list.

    Jose Luis Latorre Spain

    Wednesday, December 23, 2009 10:51 AM

    Jose Luis Latorre

    Grand!

    First, thanks so much for your so quick reply Smile
    It worked!!  - at least half of it...

    I have added the WebContext declaration to the Shell application's App.xaml:

        <Application.ApplicationLifetimeObjects>
            <appServices:WebContext>
                <appServices:WebContext.Authentication>
                    <appsvc:WindowsAuthentication/>
                </appServices:WebContext.Authentication>
            </appServices:WebContext>
        </Application.ApplicationLifetimeObjects>

    Being the namespaces:
      xmlns:appsvc="clr-namespace:System.Windows.Ria.ApplicationServices;assembly=System.Windows.Ria"
      xmlns:riaservices="clr-namespace:System.Windows.Ria;assembly=System.Windows.Ria"
      xmlns:appServices="clr-namespace:MyApp.DomainService;assembly=MyApp.Seguiment.DomainService"

    Then, on one of the modules, I have the following code on the InitModule.cs:
    Application.Current.Resources.Add("WebContext", WebContext.Current);
                ((WebAuthenticationService)WebContext.Current.Authentication).DomainContext =
                    new AuthenticationContext();
    WebContext.Current.Authentication.LoadUser(this.Application_UserLoaded, null);

    Which is basically the same code you have. This all works.

    Except I don't get the user loaded...   WebContext.Current.User;  gets me a null...

    And yes, I am under a AD domain, I have <authentication mode="Windows"/> and I have tested it from a custom ASP.NET application that I get the user correctly.

    Any clue on what might I have missed?

    ColinBlair United States

    Wednesday, December 23, 2009 10:55 AM

    ColinBlair

    When are you checking WebContext.Current.User? Was it in Application_UserLoaded?

    Jose Luis Latorre Spain

    Wednesday, December 23, 2009 11:33 AM

    Jose Luis Latorre

    Yes, it is in Application_UserLoaded.

    And it gets called well, and also does get the Application_UserLoaded callback function. But just after finishing the callback function I get the exception:
    Error  {System.Windows.Ria.DomainOperationException: Load operation failed for query 'GetUser'. A profile property does not exist for FriendlyName.
       in System.Windows.Ria.ApplicationServices.WebAuthenticationService.EndLoadUser(IAsyncResult asyncResult)
       in System.Windows.Ria.ApplicationServices.LoadUserOperation.EndCore(IAsyncResult asyncResult)
       in System.Windows.Ria.ApplicationServices.AuthenticationOperation.End(IAsyncResult result)}  System.Exception {System.Windows.Ria.DomainOperationException}


    I can say that the domainservice link works as I can get data from it..

    Mmmm.. have checked your application and it works well and can't tell any implementation difference on the user definition... have all the related classes on my "AppServices.Web" app, the user and user.shared.cs..

    so really don't know where to look for.

    Thanks again Smile

    ben United States

    Wednesday, December 30, 2009 1:24 AM

    ben

    I have the same issue with the Contoso Store sample but when adding a ria user control that uses the LoginStatus.xaml to a Page ( its ok if the page contains it .) then the visual designer dies with the same no context error

    ColinBlair United States

    Wednesday, December 30, 2009 2:37 PM

    ColinBlair

    Sorry for the delay answering you guys. FriendlyName is set in the web.config of the main application. Look for the <profile> tag.

    Jurie Smit United States

    Monday, January 11, 2010 9:32 AM

    Jurie Smit

    Hello Colin, I am busy pulling my hair out. In the project I am currently working on I am also using RIA combined with Prism. I wasnt satisfied with the Business Application Template and started my project with a clean Silverlight Application and several class libraries. Afterwards I decided that I would like to include certain parts of the business application template, but instead of modifying the business application solution I am just copying in certain parts of code as I need them. I have got the authentication and everything else I needed to work, and decided that I would like to include the shared resx files. And it is here that I ran into a problem. I added a resx file to my Web project (public), and then proceeded by adding the resx file through ---> add existing item ---> add as link, to my client project. I then proceeded by adding the following to my .csproj file: <Compile Include="..\BedBureau.Web\Resources\RegistrationDataResources.Designer.cs"> <Link>Web\Resources\RegistrationDataResources.Designer.cs</Link> <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> <DependentUpon>RegistrationDataResources.resx</DependentUpon> </Compile> <EmbeddedResource Include="..\EnterpriseBusinessApplication08.AppServices.Web\Resources\RegistrationDataResources.resx"> <Link>Web\Resources\RegistrationDataResources.resx</Link> <Generator>PublicResXFileCodeGenerator</Generator> <LastGenOutput>RegistrationDataResources.Designer.cs</LastGenOutput> </EmbeddedResource> And the link shows up in my client project, the project compiles and runs as expected. HOWEVER, when the login window is loaded, and I access the resource with [Display(Name = "UserNameLabel", ResourceType = typeof(BedBureau.Web.Resources.RegistrationDataResources))] I get the following error: Code: 4004 Category: ManagedRuntimeError Message: System.Resources.MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "BedBureau.Web.Resources.RegistrationDataResources.resources" was correctly embedded or linked into assembly "Shell" at compile time, or that all the satellite assemblies required are loadable and fully signed. Well, for the moment I have just circumvented the problem by creating a seperate resx file on the Client, but it really irritates me that I can't get the linking to work. Any suggestions? Thx a mill!

    Coin Blair United States

    Monday, January 11, 2010 9:38 AM

    Coin Blair

    @Jurie I don't have a good answer for you, I don't use resource files much myself so to get this template I pretty much just used trial and error. Did you watch the video where I was linking the resource files including the text under the video where I detail the mistake I made?

    Salvador Vidal Spain

    Tuesday, February 09, 2010 8:56 AM

    Salvador Vidal

    Well, if now i agree a new silverlight project with a new RiaservicesClass
      Is there a new webcontex2?
      is the same?

    Dhinesh Kumar India

    Tuesday, February 09, 2010 12:53 PM

    Dhinesh Kumar

    Hello Colin

    Do you have a VB.NET 2010 Version for this SL4 Business template? I tried implementing using VB.NET there are lot of namespace conflicts. If you have this, it will be of great help.

    R
    Dhinesh Kumar

    Mcad010 Norway

    Tuesday, May 04, 2010 7:26 AM

    Mcad010

    Do you have a VB.NET 2010 version of this, it would have been great? I have tried implementing this in VB but i find it really hard Smile (VS2010, SL4, PRISM(CAL),MVVM)

    rus_b United Kingdom

    Thursday, May 06, 2010 11:22 AM

    rus_b

    Hi Colin, I have been looking for some answers on custom authentication services and your BusinessApplicationTemplate really helped. I noticed that the current link targets a old version of RIA. I took the liberty of addressing the issues I spotted and tweaked the WebContext implementation. I'd be happy to send you the altered solution if it would be useful (also interested if I made any mistakes).
    Regards
    Russell

    Mcad010 Norway

    Friday, May 07, 2010 2:50 AM

    Mcad010

    Russel,
    I'm really interested to see your solution, I'm trying to use Colin's example but I'm having trouble getting it up and running for the current version of RIA. I'm almost there but getting some namespace error in the generated code in the AppService. Could you please post or blog your solution? Smile

    Colin, any chance you will upgrade the project to work with the current RIA/SL or create a VB.NET version?

    Kent Canada

    Wednesday, May 19, 2010 9:41 AM

    Kent

    Hi Colin,

    I try to move autentication service to ria class library with the latest WCF Ria Services following your movies 1,2,3 based on the Silverlight Business application template. It's fine to pass compile, but when to run the app, I got error said:
    The DomainContextType is null or invalid and there are no contexts generated from AuthenticationBase<T>.

    The error happened at app.xaml.cs:
    WebContext webContext = new MyRIAServices.WebContext();
    when it try to create instance, it create error said:
    Unable to cast object of type 'DefaultPrincipal' to type 'MyRIAServices.Web.User'

    I downloaded your template for VS2010 and modified it for latest WCF Ria Services(basically adding right assemblies and modify using for right one too), it passed compiliation, when running the app, aslo got simialar error as above.

    How to reslove this problem?

    Thank,

    Kent



    Jose Luis Latorre Spain

    Tuesday, June 08, 2010 10:15 AM

    Jose Luis Latorre

    Hi Colin,

    I have the same issue as Kent, Getting the 'unable to cast object of type 'DefaultPrincipal' to type 'XXX.Web.User'... any help or indication on that would be most useful..

    Thanks!!

    Jose Luis Latorre Spain

    Wednesday, June 09, 2010 10:21 AM

    Jose Luis Latorre

    Hi,

    I have added more detail and submitted the issue in the forums here: forums.silverlight.net/.../426236.aspx#426236

    Basically, on the Silverlight App constructor, we have the following code, to create the application web context, assign the authentication mode and

    then add the webcontext to the applicationLifetimeObjects:

                WebContext webContext = new WebContext();

                webContext.Authentication = new WindowsAuthentication();

                this.ApplicationLifetimeObjects.Add(webContext);


    The first sentence executes well…  gets the context, the second seems to work... providing the Authentication property but the user property is not valid..  it can’t get it… and this generates the error “'webContext.User' threw

    an exception of type 'System.NullReferenceException'”...

    The Stack Trace is as follows:

       “System.ServiceModel.DomainServices.Client.ApplicationServices.WebAuthenticationService.CreateDefaultUser()\r\n  

    System.ServiceModel.DomainServices.Client.ApplicationServices.AuthenticationService.get_User()"


    I have followed the migration guidelines and reviewed more than three times all the migration details: configuration settings, assemblies

    and namespace changes… I have also compared the project to other projects generated directly in SL4 that are working well… with no

    success.

    Any guess on what might have been wrong? Should I start anew and copy everything to the new  project?  Any guidance or suggestion would be more than appreciated Smile

    Best!

    Shawn Anderson United States

    Tuesday, June 22, 2010 3:28 PM

    Shawn Anderson

    Are you planning on updating this to the latest version of RIA?

    Add comment


    (Will show your Gravatar icon)

      Country flag

    Click to change captcha
    biuquote
    • Comment
    • Preview
    Loading