2012-08-22 6 views
13

In VS2010 meine MSTest Test läuft gut.Visual Studio 2012 testet mit csla und Entity-Framework

Wenn in VS2012 ausgeführt wird, erhalte ich einen Fehler. Der Test legt den Csla.ApplicationContext.User mit einem benutzerdefinierten Business Principal fest. Wenn das EntityFramework aufgefordert wird, einen neuen ObjectContext bereitzustellen, erhalte ich eine SerializationException, die besagt, dass mein Custom Business Principal-Typ nicht gefunden werden kann.

Alle Tests, bei denen das EntityFramework verwendet wird, schlagen fehl, wenn Sie den Test Runner von VS2012 oder den Test Runner von Resharper7 durchlaufen. Ich habe NCrunchs Testläufer ausprobiert und alle bestanden.

Wie kann ich dieses Problem beheben?

+2

Ich habe mein echtes Problem gefunden. VS2012 führt die Tests in einer separaten AppDomain aus, und unsere Datenzugriffsebene wird über Reflection geladen. Immer noch nicht sicher, warum EF Kenntnisse des Prinzipals erfordert, aber unsere Lösung bestand darin, unseren Principal vor dem Zugriff auf EF auf ein GenericPrincipal zurückzusetzen und dann das Original zurückzugeben. Ich ringe immer noch mit dem Gedanken, dass ein IoC-Container dieses Problem möglicherweise lindern könnte. –

+0

Können Sie Ihre Ergebnisse als eine Antwort hinzufügen und sie als akzeptiert markieren, wenn es das Problem gelöst hat? –

Antwort

2

ich mein eigentliches Problem gefunden. VS2012 führt die Tests in einer separaten AppDomain aus, und unsere Datenzugriffsebene wird über Reflection geladen. Immer noch nicht sicher, warum EF Kenntnisse des Prinzipals erfordert, aber unsere Lösung bestand darin, unseren Principal vor dem Zugriff auf EF auf ein GenericPrincipal zurückzusetzen und dann das Original zurückzugeben. Ich ringe immer noch mit dem Gedanken, dass vielleicht ein IoC-Container dieses Problem lindern könnte.

+0

Eigentlich glaube ich nicht, dass EF speziell von Ihrem Princip erfahren möchte, aber es kann es betrachten, und wenn es versucht, das Objekt von der ursprünglichen appdomain zu diesem neuen zu marshen, scheitert es (wie es das nicht finden kann Assembly Ihr Prinzipal ist definiert in. – Andy

0

Sie sollten auch den Prinzipalansatz für .net 4.5-Ansprüche beachten. Im mit EF5.0 auf VS2012 Targeting .net4.5 Ziel .net4.5 Test der Unterschied zwischen WindowsIdentity.GetCurrent().Name;
und Thread.CurrentPrincipal

ich ein wenig Routine wie diese unter Verwendung der formular Auth. So Windows Auth und Forms Auth können zusammen spielen.

Nicht die exakt gleiche Situation, aber es hebt den wichtigen Unterschied hervor, der übersehen wird, wenn alles einfach funktioniert.
Verdient ein schnelle lesen ... http://msdn.microsoft.com/en-us/library/system.security.claims.claimsprincipal.current

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Security.Claims; 
using System.Security.Principal; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Web; 


namespace BosIdentityManager 
{ 
public class BosPrincipal 
{ 
    /// <summary> 
    /// The current principal is set during FORMS authentication. If WINDOWS auth mode is in use, Windows sets it. 
    /// </summary> 
    /// <returns> The Name from Thread.CurrentPrincipal.Identity.Name unless alternate delegate is configured</returns> 
    public static string GetCurrentUserName() 
    { 
    // http://msdn.microsoft.com/en-us/library/system.security.claims.claimsprincipal.current 
    // with forms auth and windows integrated,ClaimsPrincipal.Current will be set. 

     var prin = ClaimsPrincipal.Current; //normally this reverts to Thread.CurrentPrincipal, but can chnage ! 
     return prin.Identity.Name; 

    } 

    public static string GetCurrentWindowsUserName() 
    { 
     return WindowsIdentity.GetCurrent().Name; 
    } 

    public static void SetPrincipal(BosMasterModel.Membership memb) 
    { 
     var claims = new List<Claim>(){ new Claim(ClaimTypes.Name, memb.SystemUser.UserName), 
             new Claim(ClaimTypes.NameIdentifier,memb.UserId.ToString()), 
             new Claim(ClaimTypes.Role, "SystemUser") }; 

     var ClaimsId = new ClaimsIdentity(claims,"Forms"); 

     var prin = new ClaimsPrincipal(ClaimsId); 
     Thread.CurrentPrincipal = prin; 

    } 
} 
}