1: using System;
2: using System.Diagnostics;
3: using System.Diagnostics.CodeAnalysis;
4: using System.Web.UI;
5: using System.Web.UI.HtmlControls;
6: using System.Web.UI.WebControls;
7: using System.Web.UI.WebControls.Adapters;
8:
9: /// <summary>
10: /// Implements a custom control adapter for the ASP.NET <see cref="Login"/>
11: /// control that produces CSS-friendly HTML.
12: /// </summary>
13: public class LoginAdapter : WebControlAdapter {
14: private Control container;
15:
16: /// <summary>
17: /// Creates the child controls that will be used to render the
18: /// contents of the <see cref="Login"/> control.
19: /// </summary>
20: /// <param name="e">The event arguments.</param>
21: protected override void OnInit(EventArgs e) {
22: base.OnInit(e);
23:
24: Login login = Control as Login;
25: Debug.Assert(login != null, "login != null");
26:
27: login.LoginError += login_LoginError;
28:
29: ITemplate layoutTemplate = login.LayoutTemplate;
30: if (layoutTemplate == null) {
31: layoutTemplate = new DefaultLoginTemplate(login);
32: }
33:
34: container = new Control();
35: layoutTemplate.InstantiateIn(container);
36: login.Controls.Clear();
37: login.Controls.Add(container);
38: }
39:
40: /// <summary>
41: /// Sets the text and check box settings for the user name, password,
42: /// and remember me fields on the login form.
43: /// </summary>
44: /// <param name="e">The event arguments.</param>
45: protected override void OnLoad(EventArgs e) {
46: base.OnLoad(e);
47:
48: if (!Page.IsPostBack) {
49: Login login = Control as Login;
50: Debug.Assert(login != null, "login != null");
51:
52: ITextControl userName = container.FindControl("UserName") as
53: ITextControl;
54: Debug.Assert(userName != null, "userName != null");
55: userName.Text = login.UserName;
56:
57: ITextControl password = container.FindControl("Password") as
58: ITextControl;
59: Debug.Assert(password != null, "password != null");
60: password.Text = login.Password;
61:
62: ICheckBoxControl rememberMe = container.FindControl("RememberMe")
63: as ICheckBoxControl;
64: Debug.Assert(rememberMe != null, "rememberMe != null");
65: rememberMe.Checked = login.RememberMeSet;
66: }
67: }
68:
69: /// <summary>
70: /// Detaches the adapter from the <see cref="Login.LoginError"/> event.
71: /// </summary>
72: /// <param name="e">The event arguments.</param>
73: protected override void OnUnload(EventArgs e) {
74: Login login = Control as Login;
75: Debug.Assert(login != null, "login != null");
76: login.LoginError -= login_LoginError;
77:
78: base.OnUnload(e);
79: }
80:
81: /// <summary>
82: /// Renders the opening tag that encapsulates the <see cref="Login"/>
83: /// control's content.
84: /// </summary>
85: /// <param name="writer">
86: /// The <see cref="HtmlTextWriter"/> object to use to output the
87: /// opening tag for the control.
88: /// </param>
89: protected override void RenderBeginTag(HtmlTextWriter writer) {
90: Login login = Control as Login;
91: Debug.Assert(login != null, "login != null");
92:
93: writer.AddAttribute(HtmlTextWriterAttribute.Id, login.ClientID);
94:
95: if (!login.ControlStyle.IsEmpty) {
96: if (!String.IsNullOrEmpty(login.ControlStyle.CssClass)) {
97: writer.AddAttribute(HtmlTextWriterAttribute.Class,
98: login.ControlStyle.CssClass);
99: }
100:
101: foreach (string key in login.Style.Keys) {
102: writer.AddStyleAttribute(key, login.Style[key]);
103: }
104: }
105:
106: writer.RenderBeginTag(HtmlTextWriterTag.Div);
107: }
108:
109: /// <summary>
110: /// Renders the inner contents of the <see cref="Login"/> control.
111: /// </summary>
112: /// <param name="writer">
113: /// The <see cref="HtmlTextWriter"/> object to use to output the
114: /// control's contents.
115: /// </param>
116: protected override void RenderContents(HtmlTextWriter writer) {
117: container.RenderControl(writer);
118: }
119:
120: /// <summary>
121: /// Renders the closing outer tag for the <see cref="Login"/> control.
122: /// </summary>
123: /// <param name="writer">
124: /// The <see cref="HtmlTextWriter"/> object to use to output the
125: /// control's contents.
126: /// </param>
127: protected override void RenderEndTag(HtmlTextWriter writer) {
128: writer.RenderEndTag();
129: }
130:
131: /// <summary>
132: /// Displays the failure text in the <see cref="Login"/> control's
133: /// output if a login error occurred.
134: /// </summary>
135: /// <param name="sender">The <see cref="Login"/> control.</param>
136: /// <param name="e">The event arguments.</param>
137: private void login_LoginError(object sender, EventArgs e) {
138: Login login = Control as Login;
139: Debug.Assert(login != null, "login != null");
140:
141: ITextControl failureText = container.FindControl("FailureText") as
142: ITextControl;
143: Debug.Assert(failureText != null, "failureText != null");
144: failureText.Text = login.FailureText;
145:
146: Control parent = ((Control)failureText).Parent;
147: if (!parent.Visible) {
148: parent.Visible = true;
149: }
150: }
151:
152: /// <summary>
153: /// Implements the default template for the <see cref="Login"/> control.
154: /// </summary>
155: private class DefaultLoginTemplate : ITemplate {
156: /// <summary>
157: /// The <see cref="Login"/> control that the template is a template
158: /// for.
159: /// </summary>
160: private Login login;
161:
162: /// <summary>
163: /// Constructs a new <see cref="DefaultLoginTemplate"/> object.
164: /// </summary>
165: /// <param name="login">
166: /// The <see cref="Login"/> control that the template is a template
167: /// for.
168: /// </param>
169: public DefaultLoginTemplate(Login login) {
170: this.login = login;
171: }
172:
173: /// <summary>
174: /// Adds the standard <see cref="Login"/> controls to the template
175: /// container.
176: /// </summary>
177: /// <param name="container">
178: /// The parent container that the controls will be added to as
179: /// children.
180: /// </param>
181: public void InstantiateIn(Control container) {
182: CreateTitleControl(container);
183: CreateInstructionControl(container);
184: CreateFailureControl(container);
185: CreateUserInformationFieldSet(container);
186: CreateOptionsFieldSet(container);
187: CreateLoginButton(container);
188: CreateLinks(container);
189: }
190:
191: /// <summary>
192: /// Creates the controls used to render the link to create a new
193: /// user account.
194: /// </summary>
195: /// <param name="hasCreateUserIconUrl">
196: /// True if the icon should be rendered.
197: /// </param>
198: /// <param name="hasCreateUserText">
199: /// True if the link text should be rendered.
200: /// </param>
201: /// <returns>The link.</returns>
202: private Control CreateCreateUserLink(bool hasCreateUserIconUrl,
203: bool hasCreateUserText) {
204: var listItem = new HtmlGenericControl("LI") {
205: EnableViewState = false
206: };
207:
208: var link = new HyperLink() {
209: EnableViewState = false,
210: NavigateUrl = login.CreateUserUrl
211: };
212: link.MergeStyle(login.HyperLinkStyle);
213: listItem.Controls.Add(link);
214:
215: if (hasCreateUserIconUrl) {
216: var image = new Image() {
217: EnableViewState = false,
218: ImageUrl = login.CreateUserIconUrl
219: };
220: link.Controls.Add(image);
221: }
222: if (hasCreateUserText) {
223: var text = new Literal() {
224: Text = login.CreateUserText
225: };
226: link.Controls.Add(text);
227: }
228:
229: return listItem;
230: }
231:
232: /// <summary>
233: /// Creates the controls that are used to render the failure message
234: /// for the <see cref="Login"/> control.
235: /// </summary>
236: /// <param name="container">
237: /// The parent container <see cref="Control"/> that the new control
238: /// is to be added to.
239: /// </param>
240: private void CreateFailureControl(Control container) {
241: var failureTextDiv = new HtmlGenericControl("DIV") {
242: EnableViewState = false,
243: Visible = false
244: };
245: SetCssStyles(failureTextDiv, login.FailureTextStyle);
246: container.Controls.Add(failureTextDiv);
247:
248: var failureText = new Literal {
249: EnableViewState = false,
250: ID = "FailureText"
251: };
252: failureTextDiv.Controls.Add(failureText);
253: }
254:
255: /// <summary>
256: /// Creates the controls used to render the link to navigate to a
257: /// help page for the login form.
258: /// </summary>
259: /// <param name="hasCreateUserIconUrl">
260: /// True if the icon should be rendered.
261: /// </param>
262: /// <param name="hasCreateUserText">
263: /// True if the link text should be rendered.
264: /// </param>
265: /// <returns>The link.</returns>
266: private Control CreateHelpPageLink(bool hasHelpPageIconUrl,
267: bool hasHelpPageText) {
268: var lis