Account.Login does not contain a definition for 'FailureText'

1.5k Views Asked by At

I create an asp.net application in visual studio using it's create website. It created a login screen for me and I'm trying to implement a auto reset of the lockout period.

I found this post that shows me how to implement it.

This is what I have so far:

Login.aspx

<%@ Page Title="Log In" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Login.aspx.cs" Inherits="Test.Account.Login" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Log In
    </h2>
    <p>
        Please enter your username and password.
        <asp:HyperLink ID="RegisterHyperLink" runat="server" EnableViewState="false">Register</asp:HyperLink> if you don't have an account.
    </p>
    <asp:Login ID="LoginUser" runat="server" EnableViewState="false" RenderOuterTable="false" OnLoggingIn="uxLogin_LoggingIn">
       <LayoutTemplate>
            <span class="failureNotification">
                <asp:Literal ID="FailureText" runat="server"></asp:Literal>
            </span>
            <asp:ValidationSummary ID="LoginUserValidationSummary" runat="server" CssClass="failureNotification" 
                 ValidationGroup="LoginUserValidationGroup"/>
            <div class="accountInfo">
                <fieldset class="login">
                    <legend>Account Information</legend>
                    <p>
                        <asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserName">Username:</asp:Label>
                        <asp:TextBox ID="UserName" runat="server" CssClass="textEntry"></asp:TextBox>
                        <asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="UserName" 
                             CssClass="failureNotification" ErrorMessage="User Name is required." ToolTip="User Name is required." 
                             ValidationGroup="LoginUserValidationGroup">*</asp:RequiredFieldValidator>
                    </p>
                    <p>
                        <asp:Label ID="PasswordLabel" runat="server" AssociatedControlID="Password">Password:</asp:Label>
                        <asp:TextBox ID="Password" runat="server" CssClass="passwordEntry" TextMode="Password"></asp:TextBox>
                        <asp:RequiredFieldValidator ID="PasswordRequired" runat="server" ControlToValidate="Password" 
                             CssClass="failureNotification" ErrorMessage="Password is required." ToolTip="Password is required." 
                             ValidationGroup="LoginUserValidationGroup">*</asp:RequiredFieldValidator>
                    </p>
                    <p>
                        <asp:CheckBox ID="RememberMe" runat="server"/>
                        <asp:Label ID="RememberMeLabel" runat="server" AssociatedControlID="RememberMe" CssClass="inline">Keep me logged in</asp:Label>
                    </p>
                </fieldset>
                <p class="submitButton">
                    <asp:Button ID="LoginButton" runat="server" CommandName="Login" Text="Log In" ValidationGroup="LoginUserValidationGroup"/>
                </p>
            </div>
        </LayoutTemplate>
    </asp:Login>
</asp:Content>

Login.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Test.Account
{
  public partial class Login : Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      RegisterHyperLink.NavigateUrl = "Register.aspx?ReturnUrl=" + HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
    }

    protected void uxLogin_LoggingIn(object sender, LoginCancelEventArgs e)
    {
      var login = (Login) sender;

      // unlock if appropriate
      MembershipUser _user = Membership.GetUser(login.LoginUser);
      if (_user != null && _user.IsLockedOut)
      {
        int _minutesToLockout = (int) Application["PasswordLockoutMinutes"];

        if (_minutesToLockout > -1)
        {
          int _remainingLockMinutes =
            Convert.ToInt32(
              Math.Floor(_user.LastLockoutDate.AddMinutes(_minutesToLockout).Subtract(DateTime.Now).TotalMinutes));
          if (_remainingLockMinutes > 0)
          {
            FailureText.Text =
              String.Format(
                "You have been temporarily locked out due to too many faulty passwords. You will be unlocked automatically in {0} minutes.",
                _remainingLockMinutes);
          }
          else
          {
            _user.UnlockUser();
          }
        }
        else
        {
          FailureText.Text =
            "You have been locked out due to too many faulty passwords. Please use the contact the administrator to unlock your account.";
        }
      }

    }

  }
}

It is finding the FailureText, it's issuing this message:

\Account\Login.aspx.cs(45,24): error CS1061: 'Test.Account.Login' does not contain a definition for 'FailureText' and no extension method 'FailureText' accepting a first argument of type 'Test.Account.Login' could be found (are you missing a using directive or an assembly reference?)

I have the reference in my Login.aspx so I'm not sure why it does not see it:

    <span class="failureNotification">
        <asp:Literal ID="FailureText" runat="server"></asp:Literal>
    </span>

Any help would be appreciated!

5

There are 5 best solutions below

3
On

You need to set the Text of your Literal, i.e. login.FailureText.Text =

0
On

It appears that Visual Studio will not generate the proper code-behind properties in the designer file that is used to reference the control. The issue only occurs when the controls are placed within the LayoutTemplate, so if you are able to move the Literal outside the control it would work.

Why this happens I do not know, but I found these similar questions where the same issue is raised: question 1 question 2.

You may not be able to do this for layout-related reasons, so instead you could create your own property to access the control. This is not type-safe in the same way (that is, if you rename the literal in the .aspx file, you must update the following code too) but it will let you access the field using the FailureText property as usual.

Try adding this property to Login.aspx.cs as a replacement for the (missing) auto-generated one:

protected Literal FailureText
{
    get { return LoginUser.FindControl("FailureText") as Literal; }
}
0
On

It might be because the Login control already has a property called "FailureText", and you are colliding with it. See http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.login.failuretext(v=vs.110).aspx.

You could try the following similar workaround (from stackoverflow):

Set failuretext on custom login layout template

1
On

Hello i think you need first to search the literal and then retrieve it to another literal. in this case lit1 is your FailureText, use "lit1.text" instead of "FailureText.Text". Feel free to ask anything.

Best regards, LightWalker.

  Literal lit1 = (Literal)LoginUser.FindControl("FailureText");
            lit1.Text = "fail";
0
On

I think that the Literal element in the generated HTML is hidden by the "failureNotification" class of the span, and for this reason the code in the server can't find it. Try this: replace the span element by a div.

<div class="failureNotification">
   <asp:Literal ID="FailureText" runat="server"></asp:Literal>
</div>