I am getting this error message when I try to run the PTTracker (c#) project:
System.Runtime.Serialization.SerializationException: Type is not resolved for member 'ProjectTracker.Library.Security.PTPrincipal,ProjectTracker.Library
I'm stuck. Any ideas?
Yes it is PTWeb, and yes, I tried to follow all the instructions. I had trouble registering EnterpriseServicesHostcs.dll (it said entry point not found). I tried using WebServicesHost as an alternative but always get the same error message regardless.
I may have built PTTracker before CSLA before I read the instructions - if this makes any difference.
Also, the website works if I browse http://localhost/PTWeb, but I am gettting the error message when I try to debug.
I really appreciate your help.
I too am trying to run the project tracker PTWeb example and am getting the following error message
I dont know how to get over this. Please advise
From: TerryHolland [mailto:cslanet@lhotka.net]
Sent: Friday, September 22, 2006 9:11 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Type is not resolved for member 'ProjectTracker.Library.Security.PTPrincipal,ProjectTracker.LibraryI too am trying to run the project tracker PTWeb example and am getting the following error message
Type is not resolved for member 'ProjectTracker.Library.Security.PTPrincipal,ProjectTracker.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
I dont know how to get over this. Please advise
thanks rocky - I hadn't set the Base URL. When I set it to HTTP://Loacalhost/PTWeb I get the follwoing error:
You are not authorized to view this page | |
You might not have permission to view this directory or page using the credentials you supplied. |
If I change it to HTTP://Loacalhost/PTWeb/Login.aspx then I get to the login page but it has no stylesheet. If I just open an instance of ie and type in the url then the page has its stylesheet.
When I try to login I get the following error:
An attempt to attach an auto-named database for file C:\VISUAL STUDIO PROJECTS\CSLA20\PROJECTTRACKER20VB\PTracker.MDF failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share
Ive placed the db files included in download in C:\VISUAL STUDIO PROJECTS\CSLA20\PROJECTTRACKER20VB\PTracker.MDF
From: TerryHolland [mailto:cslanet@lhotka.net]
Sent: Monday, September 25, 2006 4:51 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Type is not resolved for member 'ProjectTracker.Library.Security.PTPrincipal,ProjectTracker.Librarythanks rocky - I hadn't set the Base URL. When I set it to HTTP://Loacalhost/PTWeb I get the follwoing error:
You are not authorized to view this page
You might not have permission to view this directory or page using the credentials you supplied. If I change it to HTTP://Loacalhost/PTWeb/Login.aspx then I get to the login page but it has no stylesheet. If I just open an instance of ie and type in the url then the page has its stylesheet.
When I try to login I get the following error:
An attempt to attach an auto-named database for file C:\VISUAL STUDIO PROJECTS\CSLA20\PROJECTTRACKER20VB\PTracker.MDF failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share
Ive placed the db files included in download in C:\VISUAL STUDIO PROJECTS\CSLA20\PROJECTTRACKER20VB\PTracker.MDF
Thanks once again. I moved PTTracker and Security to App_Data and added default aspx as a default page.
When I run project, I now see the default page with formatting.
I try logging on using pm and pm and I successfully get logged in. I try clicking the Project List link and get the following error:
Unable to open the physical file "C:\Program Files\csla20vb\ProjectTracker20vb\www\PTWeb\App_Data\PTracker.MDF". Operating system error 5: "5(error not found)".
An attempt to attach an auto-named database for file C:\Program Files\csla20vb\ProjectTracker20vb\www\PTWeb\App_Data\PTracker.MDF failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.
Right-click on the web project and choose properties. You’ll
see a dialog where you can specify the startup configuration/location for the
site.
Rocky
From: sydneyos
[mailto:cslanet@lhotka.net]
Sent: Saturday, March 24, 2007 5:17 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Type is not resolved for member
'ProjectTracker.Library.Security.PTPrincipal,ProjectTracker.Library
Okay, so, for those of us who are apparently blind what is
the easy way to tell VS.Net to run in IIS?
Thanks.
I'm still having this problem with the error with PTWeb
Type is not resolved for member 'ProjectTracker.Library.Security.PTPrincipal,ProjectTracker.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
I have followed all of this forum and still can't seem to get through the browser for PTWeb. I have added the reference to EnterpriseServicesHostcs.dll the IIS virtual directory is set and is using the 2.0 framework. I've followed and re-followed the instructions in http://www.lhotka.net/files/csla20/BuildCsla.pdf thoroughly and am still lost.
please help
I am not sure what else to add.
When using a custom principal object you must run the web site in IIS. This is a limitation of the development web server, and affects any custom principal scenario.
PTWeb uses a custom principal, so you must run it in IIS, not in the development web server.
To do that
It is also the case that PTWeb needs to talk to the database. By default ASP.NET apps don't have security to talk to the database. So you have two options: configure the database to accept direct ASP.NET calls, or configure the data portal to use a remote host (remoting, enteprrise services, etc).
Of those two options, the simplest is typically to configure the data portal to use a remote host. In version 3.0 and higher the configuration defaults to using WCF and so it should just work. In 2.1 and earlier the download uses EnterpriseServices because that's easiest - only requiring that you register that one assembly with COM+.
But the exception you are getting is NOT a database access or dataportal access exception. So your problem is, almost certainly, that you don't have PTWeb running in IIS.
RockfordLhotka:I am not sure what else to add.
The biggest source of problems with any of the web-based
projects (PTWeb and any of the service-based interfaces and data portal hosts)
is that IIS and/or ASP.NET aren’t set up or configured correctly.
Rocky
Regardless of the problem – I want you to know personally that I
have read all 3 of the books and have learnt so much from you. Thank you!
Jeff
From: Rockford Lhotka
[mailto:cslanet@lhotka.net]
Sent: Sunday, August 31, 2008 8:59 PM
To: Jeffrey Rosenthal
Subject: RE: [CSLA .NET] RE: RE: Type is not resolved for member
'ProjectTracker.Library.Security.PTPrincipal,ProjectTracker.Library
The biggest source of problems with any of the web-based
projects (PTWeb and any of the service-based interfaces and data portal hosts)
is that IIS and/or ASP.NET aren’t set up or configured correctly.
Rocky
No virus
found in this incoming message.
Checked by AVG - http://www.avg.com
Version: 8.0.169 / Virus Database: 270.6.13/1642 - Release Date: 8/30/2008 5:18
PM
There is a workaround to this issue under the Visual Studio Development Server (Cassini).
The work around basically provides an alternate/custom serialization implementation, specifically around the CrossAppDomain serialization required by the Visual Studio Development Server (Cassini). It essentially "substitutes" the custom identity and principal objects with GenericIdentity and GenericPrincipal instances respectively. I strongly suggest using this under development environments only.
The Cassini web development server is able to serialize the GenericIdentity and GenericPrincipal instances sucessfully.
Workaround:
Add the following to your CustomIdentity class (and remember to add the ISerializable interface to the class declaration):
#region
ISerializable Members /// <summary> /// Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> with the data needed to serialize the target object. /// </summary> /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> to populate with data.</param> /// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext"></see>) for this serialization.</param> /// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception> public void GetObjectData( SerializationInfo info, StreamingContext context ){
// State will be CrossAppDomain for serialization induced by WebDev.WebServer if ( context.State == StreamingContextStates.CrossAppDomain ){
var generic = new GenericIdentity( Name, AuthenticationType );info.SetType( generic.GetType() );
var serializableMembers = FormatterServices.GetSerializableMembers( generic.GetType() ); var serializableValues = FormatterServices.GetObjectData( generic, serializableMembers ); for (int i = 0; i < serializableMembers.Length; i++)info.AddValue( serializableMembers.Name, serializableValues );
}
else{
// Perform 'real' serialization here if necessary throw new InvalidOperationException( "Serialization not supported" );}
}
#endregion
Add the following to your CustomPrincipal class (and remember to add the ISerializable interface to the class declaration):
#region
ISerializable Members /// <summary> /// Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> with the data needed to serialize the target object. /// </summary> /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> to populate with data.</param> /// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext"></see>) for this serialization.</param> /// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception> public void GetObjectData( SerializationInfo info, StreamingContext context ){
// State will be CrossAppDomain for serialization induced by WebDev.WebServer if ( context.State == StreamingContextStates.CrossAppDomain ){
var generic = new GenericPrincipal( Identity, ((CustomIdentity)Identity).GetRoles() );info.SetType( generic.GetType() );
var serializableMembers = FormatterServices.GetSerializableMembers( generic.GetType() ); var serializableValues = FormatterServices.GetObjectData( generic, serializableMembers ); for (var i = 0; i < serializableMembers.Length; i++)info.AddValue( serializableMembers.Name, serializableValues );
}
else{
// Perform 'real' serialization here if necessary throw new InvalidOperationException( "Serialization not supported" );}
}
#endregion
You'll notice in the constructor call to GenericPrincipal a call to provide the Roles for the identity. Your likely to need to expose such an instance method string[] GetRoles() on your CustomIdentity class.
I have recently started using CSLA 3.6 and also made use of Rocky's much simplified CslaIdentity abstract baseclass for my CustomIdentity objects and also the now built-in UnauthenticatedIdentity and UnauthenticatedPrincipal classes. Unfortunately, these built in principal and identity classes will suffer the same fate with the Visual Studio Development Server (Cassini) to the effect of "Type is not resolved for member UnauthenticatedPrincipal".
To fix this I have added (similar to the implementations shown above, but simpler) to our local copy of the Csla 3.6.0 source code through partial classes. Here follows the code:
using
System;using
System.Runtime.Serialization;using
System.Security.Principal;namespace
Csla.Security{
public sealed partial class UnauthenticatedIdentity : ISerializable{
#region
ISerializable Members /// <summary> /// Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> with the data needed to serialize the target object. /// </summary> /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> to populate with data.</param> /// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext"></see>) for this serialization.</param> /// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception> public void GetObjectData( SerializationInfo info, StreamingContext context ){
// State will be CrossAppDomain for serialization induced by WebDev.WebServer if ( context.State == StreamingContextStates.CrossAppDomain ){
var generic = new GenericIdentity( Name, AuthenticationType );info.SetType( generic.GetType() );
var serializableMembers = FormatterServices.GetSerializableMembers( generic.GetType() ); var serializableValues = FormatterServices.GetObjectData( generic, serializableMembers ); for (int i = 0; i < serializableMembers.Length; i++)info.AddValue( serializableMembers.Name, serializableValues );
}
else{
// Perform 'real' serialization here if necessary throw new InvalidOperationException( "Serialization not supported" );}
}
#endregion
}
}
And here's the UnauthenticatedPrincipal class' implementation:
using
System;using
System.Runtime.Serialization;using
System.Security.Principal;namespace
Csla.Security{
/// <summary> /// Implementation of a .NET principal object that represents /// an unauthenticated user. Contains an UnauthenticatedIdentity /// object. /// </summary> public sealed partial class UnauthenticatedPrincipal : ISerializable{
#region
ISerializable Members /// <summary> /// Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> with the data needed to serialize the target object. /// </summary> /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> to populate with data.</param> /// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext"></see>) for this serialization.</param> /// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception> public void GetObjectData( SerializationInfo info, StreamingContext context ){
// State will be CrossAppDomain for serialization induced by WebDev.WebServer if ( context.State == StreamingContextStates.CrossAppDomain ){
var generic = new GenericPrincipal( Identity, null );info.SetType( generic.GetType() );
var serializableMembers = FormatterServices.GetSerializableMembers( generic.GetType() ); var serializableValues = FormatterServices.GetObjectData( generic, serializableMembers ); for (var i = 0; i < serializableMembers.Length; i++)info.AddValue( serializableMembers.Name, serializableValues );
}
else{
// Perform 'real' serialization here if necessary throw new InvalidOperationException( "Serialization not supported" );}
}
#endregion
}
}
I've tried to implement this solution but still have the same error. I dont know if I'm putting in the correct values.
var generic = new GenericIdentity( Name, AuthenticationType );
- Is name ( _name from the class)?
- Is AuthenticationType = 'Csla'?
var generic = new GenericPrincipal( Identity, ((CustomIdentity)Identity).GetRoles() );
- I'm assuming that CustomIdentity is my identity object
- Does the GetRoles() really have to return all the roles? For the user or just all the roles in the database? How does this affect the IsInRole?
Thanks
The issue discussed in this thread stems from a limitation in Cassini. I've talked to people at Microsoft about this a couple times, and they show no signs of fixing the issue from their side - so I think we're stuck with workarounds.
This isn't a CSLA specific issue. Anyone using custom principals or custom membership provider implementations runs into the same problem.
One workaround is to put your business assembly in the GAC. This is kind of a pain, but if you use a post-build step in VS you can update the GAC on each build. This does require strong naming your business assembly, which might also be an extra step if you aren't already doing so.
Another solution, if you are using current versions of CSLA .NET, is to use a GenericPrincipal instead of a custom principal type. The limitation here is that you can't extend the principal or identity with extra properties, but the benefit is that the types are in .NET itself and so work with Cassini.
Two posts back there's a lot of code showing one way to work with GenericPrincipal. In current versions of CSLA you can use it directly, because the data portal no longer requires that your principal inherit from BusinessPrincipalBase. Any serializable principal object is acceptible.
GenericPrincipal and GenericIdentity are standard parts of .NET. They provide the most basic and simple implementations of IPrincipal and IIdentity possible. GenericPrincipal maintains an array of roles for the current user and has an IsInRole() method that checks that array. GenericIdentity maintains the username and authentication type. If the username is not null, then IsAuthenticated returns true.
To fit this into the CSLA model, you'll almost certainly create some object that is responsible for initial creation of the GenericPrincipal/GenericIdentity pair. I'd use a ReadOnlyBase object for this purpose. It would look something like this:
[Serializable]
public class Authenticator : ReadOnlyBase<Authenticator>
{
public IPrincipal Principal { get; set; }
public static void Login(string username, string password)
{
var obj = DataPortal.Fetch<Authenticator>(
new Csla.Security.UsernameCriteria(username, password));
Csla.ApplicationContext.User = obj.Principal;
}
private void DataPortal_Fetch(Csla.Security.UsernameCriteria criteria)
{
// validate the username/password data
// if valid, load a roles array with data
var roles = new string[] { };
Principal =
new GenericPrincipal(
new GenericIdentity(criteria.Username),
roles);
}
}
This way the HttpContext and/or thread are connected to a GenericPrincipal/GenericIdentity, not to any custom type, so Cassini should be happy. And in CSLA 3.5 or higher the data portal should also be happy.
So as long as you only need the most basic principal/identity behaviors, this is probably a decent overall solution. If you need more advanced or custom behaviors, you'll be stuck with the GAC if you must use Cassini.
Copyright (c) Marimer LLC