需要帮助理解这个代码(Need Help understanding this code)

2019-09-16 16:10发布

我努力学习单元测试。 我试图单元测试一些东西Memembership我在asp.net mvc的1.0决策。 我一直在关注一书中对MVC和我感到困惑的一些东西,希望有人能收拾我。

我使用NUnit和起订量为我的框架。

问题1:

  public AuthenticationController(IFormsAuthentication formsAuth, MembershipProvider provider)
        {
            FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
            Provider = provider ?? Membership.Provider;
        }

我有点困惑是什么“?” 确实我从来没有真正见过它。 就像我甚至不知道什么在这里发生的一切真的。 就像他们经过的接口,然后“??” 标记发生,使一个新的FormsAuthenticationWraper制成?

问题2。

 public AuthenticationController(): this(null, null)
        {
        }

我知道这是默认的构造函数,但我不知道为什么“:这个(NULL,NULL)”在做什么。

喜欢的是它实现? 而这是什么太为参照。 而在它的上面,为什么不能说就那么丢了呢? 而只是坚持默认的构造函数,因为它是。

问题3。

在这本书中(asp.net的MVC 1.0快)它谈论怎么会是相当多的工作来实现Memembership提供商将是大量的工作。 于是,他们用起订量样机框架,使生活更轻松。

现在的问题是他们不使用的起订量的“FormsAuthentication”。 相反,他们将界面

   public interface IFormsAuthentication
        {
            void SetAuthCookie(string userName, bool createPersistentCookie);
            void SignOut();


        }

然后进行包装

公共类FormsAuthenticationWrapper:IFormsAuthentication {公共无效SetAuthCookie(用户名字符串,布尔createPersistentCookie){FormsAuthentication.SetAuthCookie(用户名,createPersistentCookie); } public void SignOut() { FormsAuthentication.SignOut(); }公共无效SignOut(){FormsAuthentication.SignOut(); } }

}

后来终于属性

   public IFormsAuthentication FormsAuth
        {
            get;
            private set;
        }

凡与他们只有会员

公共静态的MembershipProvider提供商{获得; 私人集; }

我不知道什么,虽然改变的东西太多。 什么样的事情我会改变这行吗?

FormsAuth = formsAuth ?? 新FormsAuthenticationWrapper();

我也尝试添加另一种方法到FormsAuthentication接口和包装。

公共无效RedirectFromLoginPage(用户名字符串,布尔createPersistentCookie){FormsAuthentication.RedirectFromLoginPage(用户名,createPersistentCookie); } }

然而,我不知道发生了什么,但我的单元测试总是失败不要紧,我尝试做修复它。

     public ActionResult Login(string returnUrl, FormCollection form, bool rememberMe)
            {
                LoginValidation loginValidation = new LoginValidation();
                try
                {
                    UpdateModel(loginValidation, form.ToValueProvider());

                }
                catch
                {

                    return View("Login");
                }

                if (ModelState.IsValid == true)
                {

                    bool valid = authenticate.VerifyUser(loginValidation.UserName, loginValidation.Password);

                    if (valid == false)
                    {
                        ModelState.AddModelError("frm_Login", "Either the Password or UserName is invalid");

                    }
                    else if (string.IsNullOrEmpty(returnUrl) == false)
                    {
                        /* if the user has been sent away from a page that requires them to login and they do 
                         * login then redirect them back to this area*/
                        return Redirect(returnUrl);
                    }
                    else
                    {

                       FormsAuth.RedirectFromLoginPage(loginValidation.UserName, rememberMe);
                    }

                }


                return View("Login");


Here is my test

[测试]公共无效Test_If_User_Is_Redirected_Back_To_Page_They_Came_From_After_Login(){System.Diagnostics.Debugger.Break();

       var formsAuthenticationMock =  new Mock<AuthenticationController.IFormsAuthentication>();

       var membershipMock = new Mock<MembershipProvider>();

       membershipMock.Setup(m => m.ValidateUser("chobo2", "1234567")).Returns(true);


       // Setup controller
       AuthenticationController target = new AuthenticationController(formsAuthenticationMock.Object, membershipMock.Object);


       // Execute
       FormCollection form = new FormCollection();
       form.Add("Username", "chobo2");
       form.Add("password", "1234567");

       ViewResult actual = target.Login(null, form, false) as ViewResult;

       Assert.That(actual.View, Is.EqualTo("home"));
       formsAuthenticationMock.Verify();

   }

实际总是回来空。 我试过的ViewResult,RedirectResult和RedirectToRouteResult但每个人都回来了空。 所以,我不知道为什么发生这种情况,因为我觉得很奇怪:第一,

                       FormsAuth.RedirectFromLoginPage(loginValidation.UserName, rememberMe);

不停车查看,并开始重定向。 我开始还以为一旦碰到这条线它就像一个return语句和那它没有其他的代码会被执行,但htis似乎并没有这样的情况,所以我不知道这可能是问题。

谢谢

Answer 1:

问题1

?? 被称为空合并运算符 ,并且是C#2.0起一个非常有用的功能。

根据你的情况,

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

简单地是指“分配formsAuthFormsAuth除非它为空,在这种情况下分配new FormsAuthenticationWrapper() ”。 它基本上是防止你的代码空引用的方法。 你也可以把它作为下列条件表达式的快捷方式:

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

问题2

使用this(null, null)被称为构造函数链 。 所有这意味着,在相同的类的构造函数(因此this ,相对于base的父类),它有两个参数,应执行构造的主体之前调用。

重载构造函数是一种常见的做法,使其更容易为开发者创建新的对象时,他们只是想用默认属性/设置。

问题3

正如其他人所说,这确实属于作为一个单独的问题。 不同于前两次,这是更具体的上下文/你的代码,而不是C#语言功能。

更新

好吧,我现在所做的就是这里实际上改写了两个构造函数,因为我认为他们将在另一个(实际上等于)的形式可能会有点更清晰,可能是更好的设计实践过。 空合并运营商是没有必要在这里。

public AuthenticationController()
    : this(new FormsAuthenticationWrapper(), Membership.Provider)
{
}

public AuthenticationController(IFormsAuthentication formsAuth,
    MembershipProvider provider)
{
    this.FormsAuth = formsAuth;
    this.Provider = provider;
}

在这种形式下,它应该是显而易见的,仅仅需要两个参数的构造分配类变量的参数值。 参数构造函数(通常称为默认构造)简单地创建使用默认的一个新对象FormsAuthProvider对象,这些对象通过构造链接指定。



Answer 2:

问题1:?? 是空合并运算符 。 该?? 操作者检查是否设置在表达的左侧的值为空,并且如果是这样,它返回由表达式的右侧表示的替代值。

在您的情况,它会检查是否formsAuth为空,并返回一个新FormsAuthenticationWrapper(),如果它是空的。



Answer 3:

该?? 操作员说:“用这个,除非它是空,这这种情况下,使用该其他东西”。

所以,这行代码:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

是相同的:

if ( formsAuth != null ) FormsAuth = formsAuth
else FormsAuth = new FormsAuthenticationWrapper();


Answer 4:

在回答Q2

这是超载的构造。

如果是指主叫

Foo() 

是与调用

Foo(null, null)


Answer 5:

问1: ?? 操作人员只需说“采取一切是在我的左边,如果它不为空 - 如果是,采取一切是我的权利。” 所以,你的代码:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

相当于

if (formsAuth != null) {
    FormsAuth = formsAuth;
} else {
    FormsAuth 0 new FormsAuthenticationWrapper();
}

问2: :this(null, null)语法是“构造继承”(我命名...)的简写。 您的代码

public AuthenticationController(): this(null, null)
    {
    }
public AuthenticationController(IFormsAuthentication formsAuth, MembershipProvider  provider)
    {
        FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
        Provider = provider ?? Membership.Provider;
    }

相当于

public AuthenticationController()
    {
        FormsAuth = new FormsAuthenticationWrapper();
        Provider = Membership.Provider;
    }
public AuthenticationController(IFormsAuthentication formsAuth, MembershipProvider provider)
    {
        FormsAuth = formsAuth;
        Provider = provider;
    }


Answer 6:

问题2

public AuthenticationController(): this(null, null)
{
}

对于AuthenticationController无参数构造函数将调用了使用IFormsAuthentication和的MembershipProvider构造,传递两个空值(这是在无PARAM构造函数代码块中的任何代码之前完成执行)。 由于这两个参数的构造采用了空聚结(??)操作者指定的变量和传递的参数为空,一个新的MembershipProvider与Membership.Provider对象一起使用。

尚未明确定义这个构造函数,默认无PARAM构造函数将被使用。 如果一个新的AuthenticationController创建这可能会导致意外的行为(不传递任何参数构造函数),因为成员变量不会被初始化。



Answer 7:

问题1:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
Provider = provider ?? Membership.Provider;

是等于:

FormsAuth = (formsAuth == null ? new FormsAuthenticationWrapper() : formsAuth);
Provider = (provider == null ? Membership.Provider : provider);

问题2:

它只是传递null既formsAuth和提供构造函数参数。 这不是好的做法恕我直言。 不带参数的另一个构造将是一个更好的选择。

编辑 :这是没有意义的。 很抱歉,我很着急,并没有真正意识到这是一个构造函数调用另一个构造函数。

我没有时间,现在来回答问题3,我会得到以后...



文章来源: Need Help understanding this code