1: using System;
2: using System.Diagnostics;
3: using System.Diagnostics.CodeAnalysis;
4: using System.Web.Security;
5: using System.Web.UI;
6: using System.Web.UI.HtmlControls;
7: using System.Web.UI.WebControls;
8: using System.Web.UI.WebControls.Adapters;
9:
10: /// <summary>
11: /// Implements a custom control adapter for the ASP.NET <see cref="Login"/>
12: /// control that produces CSS-friendly HTML.
13: /// </summary>
14: public class LoginAdapter : WebControlAdapter {
15: /// <summary>
16: /// The container <see cref="Control"/> that contains the
17: /// <see cref="Login"/> control's template.
18: /// </summary>
19: private Control container;
20:
21: /// <summary>
22: /// The value entered into the password text box.
23: /// </summary>
24: private string passwordValue;
25:
26: /// <summary>
27: /// The value of the remember me check box.
28: /// </summary>
29: private bool rememberMeValue;
30:
31: /// <summary>
32: /// The value entered into the user name text box.
33: /// </summary>
34: private string userNameValue;
35:
36: /// <summary>
37: /// Creates the child controls for the <see cref="Login"/> control.
38: /// </summary>
39: protected override void CreateChildControls() {
40: base.CreateChildControls();
41:
42: Login login = Control as Login;
43: Debug.Assert(login != null, "login != null");
44:
45: ITemplate layoutTemplate = login.LayoutTemplate;
46: if (layoutTemplate == null) {
47: layoutTemplate = new DefaultLoginTemplate(login);
48: }
49:
50: container = new Control();
51: layoutTemplate.InstantiateIn(container);
52: login.Controls.Clear();
53: login.Controls.Add(container);
54:
55: IEditableTextControl userName = container.FindControl("UserName") as
56: IEditableTextControl;
57: Debug.Assert(userName != null, "userName != null");
58: userName.TextChanged += UserName_TextChanged;
59:
60: IEditableTextControl password = container.FindControl("Password") as
61: IEditableTextControl;
62: Debug.Assert(password != null, "password != null");
63: password.TextChanged += Password_TextChanged;
64:
65: ICheckBoxControl rememberMe = container.FindControl("RememberMe") as
66: ICheckBoxControl;
67: Debug.Assert(rememberMe != null, "rememberMe != null");
68: rememberMe.CheckedChanged += RememberMe_CheckedChanged;
69: }
70:
71: /// <summary>
72: /// Creates the child controls that will be used to render the
73: /// contents of the <see cref="Login"/> control.
74: /// </summary>
75: /// <param name="e">The event arguments.</param>
76: protected override void OnInit(EventArgs e) {
77: base.OnInit(e);
78:
79: Login login = Control as Login;
80: Debug.Assert(login != null, "login != null");
81: login.Authenticate += login_Authenticate;
82: login.LoginError += login_LoginError;
83: }
84:
85: /// <summary>
86: /// Sets the text and check box settings for the user name, password,
87: /// and remember me fields on the login form.
88: /// </summary>
89: /// <param name="e">The event arguments.</param>
90: protected override void OnLoad(EventArgs e) {
91: base.OnLoad(e);
92:
93: if (!Page.IsPostBack) {
94: Login login = Control as Login;
95: Debug.Assert(login != null, "login != null");
96:
97: userNameValue = login.UserName;
98: passwordValue = "";
99: rememberMeValue = login.RememberMeSet;
100: }
101: }
102:
103: /// <summary>
104: /// Sets the value of the user name text box and the remember me
105: /// checkbox before the control is rendered.
106: /// </summary>
107: /// <param name="e"></param>
108: protected override void OnPreRender(EventArgs e) {
109: IEditableTextControl userName = container.FindControl("UserName") as
110: IEditableTextControl;
111: Debug.Assert(userName != null, "userName != null");
112: userName.Text = userNameValue;
113:
114: IEditableTextControl password = container.FindControl("Password") as
115: IEditableTextControl;
116: Debug.Assert(password != null, "password != null");
117: password.Text = "";
118:
119: ICheckBoxControl rememberMe = container.FindControl("RememberMe") as
120: ICheckBoxControl;
121: Debug.Assert(rememberMe != null, "rememberMe != null");
122: rememberMe.Checked = rememberMeValue;
123: }
124:
125: /// <summary>
126: /// Detaches the adapter from the <see cref="Login.LoginError"/> event.
127: /// </summary>
128: /// <param name="e">The event arguments.</param>
129: protected override void OnUnload(EventArgs e) {
130: Login login = Control as Login;
131: Debug.Assert(login != null, "login != null");
132: login.Authenticate -= login_Authenticate;
133: login.LoginError -= login_LoginError;
134:
135: IEditableTextControl userName = container.FindControl("UserName") as
136: IEditableTextControl;
137: Debug.Assert(userName != null, "userName != null");
138: userName.TextChanged -= UserName_TextChanged;
139:
140: IEditableTextControl password = container.FindControl("Password") as
141: IEditableTextControl;
142: Debug.Assert(password != null, "password != null");
143: password.TextChanged -= Password_TextChanged;
144:
145: ICheckBoxControl rememberMe = container.FindControl("RememberMe") as
146: ICheckBoxControl;
147: Debug.Assert(rememberMe != null, "rememberMe != null");
148: rememberMe.CheckedChanged -= RememberMe_CheckedChanged;
149:
150: base.OnUnload(e);
151: }
152:
153: /// <summary>
154: /// Prevents the login control from rendering if the user is
155: /// authenticated and the <see cref="Login.VisibleWhenLoggedIn"/>
156: /// property is set to false.
157: /// </summary>
158: /// <param name="writer">
159: /// The <see cref="HtmlTextWriter"/> object to use to render the
160: /// <see cref="Login"/> control.
161: /// </param>
162: protected override void Render(HtmlTextWriter writer) {
163: Login login = Control as Login;
164: Debug.Assert(login != null, "login != null");
165:
166: if (!Page.Request.IsAuthenticated || login.VisibleWhenLoggedIn) {
167: base.Render(writer);
168: }
169: }
170:
171: /// <summary>
172: /// Renders the opening tag that encapsulates the <see cref="Login"/>
173: /// control's content.
174: /// </summary>
175: /// <param name="writer">
176: /// The <see cref="HtmlTextWriter"/> object to use to output the
177: /// opening tag for the control.
178: /// </param>
179: protected override void RenderBeginTag(HtmlTextWriter writer) {
180: Login login = Control as Login;
181: Debug.Assert(login != null, "login != null");
182:
183: writer.AddAttribute(HtmlTextWriterAttribute.Id, login.ClientID);
184:
185: if (!login.ControlStyle.IsEmpty) {
186: if (!String.IsNullOrEmpty(login.ControlStyle.CssClass)) {
187: writer.AddAttribute(HtmlTextWriterAttribute.Class,
188: login.ControlStyle.CssClass);
189: }
190:
191: foreach (string key in login.Style.Keys) {
192: writer.AddStyleAttribute(key, login.Style[key]);
193: }
194: }
195:
196: writer.RenderBeginTag(HtmlTextWriterTag.Div);
197: }
198:
199: /// <summary>
200: /// Renders the inner contents of the <see cref="Login"/> control.
201: /// </summary>
202: /// <param name="writer">
203: /// The <see cref="HtmlTextWriter"/> object to use to output the
204: /// control's contents.
205: /// </param>
206: protected override void RenderContents(HtmlTextWriter writer) {
207: container.RenderControl(writer);
208: }
209:
210: /// <summary>
211: /// Renders the closing outer tag for the <see cref="Login"/> control.
212: /// </summary>
213: /// <param name="writer">
214: /// The <see cref="HtmlTextWriter"/> object to use to output the
215: /// control's contents.
216: /// </param>
217: protected override void RenderEndTag(HtmlTextWriter writer) {
218: writer.RenderEndTag();
219: }
220:
221: /// <summary>
222: /// Authenticates the user using the ASP.NET membership provider.
223: /// </summary>
224: /// <param name="sender">The <see cref="Login"/> control.</param>
225: /// <param name="e">The event arguments.</param>
226: private void login_Authenticate(object sender, AuthenticateEventArgs e) {
227: Login login = sender as Login;
228: Debug.Assert(login != null, "login != null");
229:
230: MembershipProvider provider;
231: string providerName = login.MembershipProvider;
232: if (!String.IsNullOrEmpty(providerName)) {
233: provider = Membership.Providers[providerName];
234: } else {
235: provider = Membership.Provider;
236: }
237:
238: e.Authenticated = provider.ValidateUser(userNameValue,
239: passwordValue);
240: }
241:
242: /// <summary>
243: /// Displays the failure text in the <see cref="Login"/> control's
244: /// output if a login error occurred.
245: /// </summary>
246: /// <param name="sender">The <see cref="Login"/> control.</param>
247: /// <param name="e">The event arguments.</param>
248: private void login_LoginError(object sender, EventArgs e) {
249: Login login = Control as Login;
250: Debug.Assert(login != null, "login != null");
251:
252: ITextControl failureText = container.FindControl("FailureText") as
253: ITextControl;
254: Debug.Assert(failureText != null, "failureText != null");
255: failureText.Text = login.FailureText;
256:
257: Control parent = ((Control)failureText).Parent;
258: if (!parent.Visible) {
259: parent.Visible = true;
260: }
261: }
262:
263: /// <summary>
264: /// Called when the value in the password text box has been changed.
265: /// </summary>
266: /// <param name="sender">
267: /// The <see cref="IEditableTextControl"/> object.
268: /// </param>
269: /// <param name="e">The event arguments.</param>
270: private void Password_TextChanged(object sender, EventArgs e) {
271: IEditableTextControl password = sender as IEditableTextControl;
272: Debug.Assert(password != null, "password != null");
273: passwordValue = password.Text;
274: }
275:
276: /// <summary>
277: /// Called when the check box status for the remember me check box
278: /// has been changed.
279: /// </summary>
280: /// <param name="sender">
281: /// The <see cref="ICheckBoxControl"/> object.
282: /// </param>
283: /// <param name="e">The event arguments.</param>
284: private void RememberMe_CheckedChanged(object sender, EventArgs e) {
285: ICheckBoxControl rememberMe = sender as ICheckBoxControl;
286: Debug.Assert(rememberMe != null, "rememberMe != null");
287: rememberMeValue = rememberMe.Checked;
288:
289: Login login = Control as Login;
290: Debug.Assert(login != null, "login != null");
291: login.RememberMeSet = rememberMeValue;
292: }
293:
294: /// <summary>
295: /// Called when the value in the user name text box has been changed.
296: /// </summary>
297: /// <param name="sender">
298: /// The <see cref="IEditableTextControl"/> object.
299: /// </param>
300: /// <param name="e">The event arguments.</param>