SerializationException with serialized CustomPrincipal

SerializationException with serialized CustomPrincipal

Old forum URL: forums.lhotka.net/forums/t/9521.aspx


c_manboy posted on Friday, September 10, 2010

I'm using CSLA 4 and Bxf.  My MainWindow is throwing a SerializationException inside VS2010.  The problem seems centered around my CustomPrincipal object.  I dont fully understand the authentication "stuff" so I'm sure I'm doing something wrong.  I'm trying to use the users AD credentials and populate the Roles they belong to with the AD Groups they are a member of.

Here's my code.  Note: If I remove <Serializable()> from the CustomPrincipal class then I do not recieve the error in the designer...but I do not know the impact that will have during deployment. 

Namespace Security

    <Serializable()>

    Public Class CustomPrincipal

        Inherits CslaPrincipal

 

        Private Sub New(ByVal identity As IIdentity)

            MyBase.New(identity)

        End Sub

 

        Public Shared Sub LoginCurrentUser()

            Dim identity = CustomIdentity.GetCurrentUserIdentity()

            Csla.ApplicationContext.User = New CustomPrincipal(identity)

        End Sub

 

        Public Shared Sub Logout()

            Dim identity = New Csla.Security.UnauthenticatedIdentity

            Csla.ApplicationContext.User = New CustomPrincipal(identity)

        End Sub

 

    End Class

End Namespace

I left out CustomIdentity.  But it takes the users login name and then loads the Roles with the groups the user belongs to by using the System.DirectoryServices namespace.

In my MainWindowPresenter constructor I have this code (I also tried placing this code in my MenuViewModel constructor and it has the same effect):

AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal)

Library.Security.CustomPrincipal.LoginCurrentUser()

My app.config contains:

<appSettings>

    <add key="CslaAuthentication" value="Windows"/>

    <add key="CslaPropertyChangedMode" value="Xaml"/>

 </appSettings>

The xaml error is:

System.Runtime.Serialization.SerializationException

Type is not resolved for member 'CustomReports.Library.Security.CustomPrincipal,CustomReports.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

   at MS.Internal.Host.Isolation.Protocols.ITextModel.ReportErrors(IEnumerable`1 errors, Int64 sourceVersion)   at MS.Internal.Host.Isolation.Adapters.ToTextModel.ReportErrors(IEnumerable`1 errors, Int64 sourceVersion)   at MS.Internal.Host.PersistenceSubsystem.ReportException(Exception ex, TextModel model, Int64 sourceVersion)   at MS.Internal.Host.PersistenceSubsystem.Load()   at MS.Internal.Host.Designer.Load()   at MS.Internal.Designer.VSDesigner.Load()   at MS.Internal.Designer.VSIsolatedDesigner.VSIsolatedView.Load()   at MS.Internal.Designer.VSIsolatedDesigner.VSIsolatedDesignerFactory.Load(IsolatedView view)   at MS.Internal.Host.Isolation.IsolatedDesigner.BootstrapProxy.LoadDesigner(IsolatedDesignerFactory factory, IsolatedView view)   at MS.Internal.Host.Isolation.IsolatedDesigner.BootstrapProxy.LoadDesigner(IsolatedDesignerFactory factory, IsolatedView view)   at MS.Internal.Host.Isolation.IsolatedDesigner.Load()   at MS.Internal.Designer.DesignerPane.LoadDesignerView()

Thanks in advance.

RockfordLhotka replied on Friday, September 10, 2010

The thing with the WPF/SL designer in VS10 is that it may actually run your code while at design time. In fact that's often the default, depending on how you set up your DataContext objects.

If you use the designer you'll end up with a CollectionViewSource, and it will have a d: attribute indicating that an instance of your viewmodel should be created to provide design-time data. That may or may not actually work - but it will run your code.

So think about what's in your viewmodel constructor. Probably a call to DoRefresh or BeginRefresh. And that invokes a factory method, which invokes the data portal, etc. All at design time when you load your view into VS10.

To prevent this, you can use code like this:

      if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
      {

The only trick is that "this" needs to be a DependencyObject. Since most of my viewmodel objects do subclass DependencyObject (and this includes ViewModelBase and ViewModel in Csla.Xaml) you can just use this code in the viewmodel's constructor:

    public ItemListViewModel()
    {
      if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
        BeginRefresh(ItemList.GetList);
    }

Copyright (c) Marimer LLC