C# Visual Studio 2012使用csla和实体框架进行测试

C# Visual Studio 2012使用csla和实体框架进行测试,c#,mstest,visual-studio-2012,entity-framework-4.3,csla,C#,Mstest,Visual Studio 2012,Entity Framework 4.3,Csla,在VS2010中,我的MSTest运行得很好 在VS2012中运行时,我遇到一个错误。该测试使用自定义业务主体设置Csla.ApplicationContext.User。当EntityFramework被要求提供新的ObjectContext时,我收到一个SerializationException,表示找不到我的自定义业务主体类型 当通过VS2012的测试运行程序或Resharper7的测试运行程序运行时,所有使用EntityFramework的测试都会失败。我试过NCrunch的试跑者,他

在VS2010中,我的MSTest运行得很好

在VS2012中运行时,我遇到一个错误。该测试使用自定义业务主体设置Csla.ApplicationContext.User。当EntityFramework被要求提供新的ObjectContext时,我收到一个SerializationException,表示找不到我的自定义业务主体类型

当通过VS2012的测试运行程序或Resharper7的测试运行程序运行时,所有使用EntityFramework的测试都会失败。我试过NCrunch的试跑者,他们都通过了


如何解决此问题?

您还应注意.net 4.5索赔主体方法。 Im在VS2012 targeting.net4.5 target.net4.5上使用EF5.0 测试
WindowsIdentity.GetCurrent().Name之间的差异
Thread.CurrentPrincipal

我在FORMS auth下使用了这样一个小例程。 这样Windows Auth和Forms Auth就可以一起玩了

不完全相同的情况,但它确实突出了重要的差异,而这一差异在一切正常时都被忽略了。
值得一读

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Security.Claims;
使用System.Security.Principal;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Web;
命名空间BosIdentityManager
{
公共课校长
{
/// 
///在窗体身份验证期间设置了当前主体。如果正在使用WINDOWS身份验证模式,则WINDOWS会设置它。
/// 
///Thread.CurrentPrincipal.Identity.Name中的名称,除非配置了备用委托
公共静态字符串GetCurrentUserName()
{
//   http://msdn.microsoft.com/en-us/library/system.security.claims.claimsprincipal.current   
//集成forms auth和windows后,将设置ClaimsPrincipal.Current。
var prin=ClaimsPrincipal.Current;//通常这会恢复为Thread.CurrentPrincipal,但可以更改!
返回prin.Identity.Name;
}
公共静态字符串GetCurrentWindowsUserName()
{
返回WindowsIdentity.GetCurrent().Name;
}
公共静态void SetPrincipal(BosMasterModel.memb)
{
var claims=new List(){new claims(ClaimTypes.Name,memb.SystemUser.UserName),
新声明(ClaimTypes.NameIdentifier,memb.UserId.ToString()),
新声明(ClaimTypes.Role,“SystemUser”)};
var ClaimsId=新的索赔实体(索赔,“表格”);
var prin=新的索赔(索赔SID);
Thread.CurrentPrincipal=prin;
}
}
}

我发现了真正的问题。VS2012在单独的AppDomain中运行测试,我们的数据访问层通过反射加载。仍然不确定为什么EF需要了解主体,但我们的解决方案是在访问EF之前将主体重置为GenericPrincipal,然后放回原始主体。我仍在苦苦思索,也许一个国际奥委会集装箱可以缓解这个问题。我找到了真正的问题所在。VS2012在单独的AppDomain中运行测试,我们的数据访问层通过反射加载。仍然不确定为什么EF需要了解主体,但我们的解决方案是在访问EF之前将主体重置为GenericPrincipal,然后放回原始主体。我仍在苦苦思索,也许一个国际奥委会的容器会缓解这个问题。你能把你的发现作为一个答案,如果它解决了这个问题,你能把它们标记为接受吗?实际上我不认为英孚想具体了解你的校长,但它可能会看看它,当它试图将对象从原始appdomain缓冲到这个新appdomain时,它失败了(因为它找不到主体在其中定义的程序集)。
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;

   }
}
}