Fix bugs in sizing TableLayoutPanel (Xamarin bug 18638)
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / Html / InputExtensions.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc.Html {\r
14     using System;\r
15     using System.Collections.Generic;\r
16     using System.Data.Linq;\r
17     using System.Diagnostics.CodeAnalysis;\r
18     using System.Globalization;\r
19     using System.Linq.Expressions;\r
20     using System.Text;\r
21     using System.Web.Mvc.Resources;\r
22     using System.Web.Routing;\r
23 \r
24     public static class InputExtensions {\r
25         // CheckBox\r
26 \r
27         public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name) {\r
28             return CheckBox(htmlHelper, name, (object)null /* htmlAttributes */);\r
29         }\r
30 \r
31         public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked) {\r
32             return CheckBox(htmlHelper, name, isChecked, (object)null /* htmlAttributes */);\r
33         }\r
34 \r
35         public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, object htmlAttributes) {\r
36             return CheckBox(htmlHelper, name, isChecked, new RouteValueDictionary(htmlAttributes));\r
37         }\r
38 \r
39         public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, object htmlAttributes) {\r
40             return CheckBox(htmlHelper, name, new RouteValueDictionary(htmlAttributes));\r
41         }\r
42 \r
43         public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes) {\r
44             return CheckBoxHelper(htmlHelper, name, null /* isChecked */, htmlAttributes);\r
45         }\r
46 \r
47         public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, IDictionary<string, object> htmlAttributes) {\r
48             return CheckBoxHelper(htmlHelper, name, isChecked, htmlAttributes);\r
49         }\r
50 \r
51         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
52         public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression) {\r
53             return CheckBoxFor(htmlHelper, expression, null /* htmlAttributes */);\r
54         }\r
55 \r
56         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
57         public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes) {\r
58             return CheckBoxFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes));\r
59         }\r
60 \r
61         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
62         public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, IDictionary<string, object> htmlAttributes) {\r
63             if (expression == null) {\r
64                 throw new ArgumentNullException("expression");\r
65             }\r
66 \r
67             ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);\r
68             bool? isChecked = null;\r
69             if (metadata.Model != null) {\r
70                 bool modelChecked;\r
71                 if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked)) {\r
72                     isChecked = modelChecked;\r
73                 }\r
74             }\r
75 \r
76             return CheckBoxHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), isChecked, htmlAttributes);\r
77         }\r
78 \r
79         private static MvcHtmlString CheckBoxHelper(HtmlHelper htmlHelper, string name, bool? isChecked, IDictionary<string, object> htmlAttributes) {\r
80             RouteValueDictionary attributes =\r
81                 htmlAttributes == null ? new RouteValueDictionary()\r
82                                        : new RouteValueDictionary(htmlAttributes);\r
83 \r
84             bool explicitValue = isChecked.HasValue;\r
85             if (explicitValue) {\r
86                 attributes.Remove("checked");    // Explicit value must override dictionary\r
87             }\r
88 \r
89             return InputHelper(htmlHelper, InputType.CheckBox, name, "true", !explicitValue /* useViewData */, isChecked ?? false, true /* setId */, false /* isExplicitValue */, attributes);\r
90         }\r
91 \r
92         // Hidden\r
93 \r
94         public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name) {\r
95             return Hidden(htmlHelper, name, null /* value */, null /* htmlAttributes */);\r
96         }\r
97 \r
98         public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value) {\r
99             return Hidden(htmlHelper, name, value, null /* hmtlAttributes */);\r
100         }\r
101 \r
102         public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {\r
103             return Hidden(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));\r
104         }\r
105 \r
106         public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {\r
107             return HiddenHelper(htmlHelper,\r
108                                 value,\r
109                                 value == null /* useViewData */,\r
110                                 name,\r
111                                 htmlAttributes);\r
112         }\r
113 \r
114         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
115         public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {\r
116             return HiddenFor(htmlHelper, expression, (IDictionary<string, object>)null);\r
117         }\r
118 \r
119         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
120         public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {\r
121             return HiddenFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes));\r
122         }\r
123 \r
124         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
125         public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {\r
126             return HiddenHelper(htmlHelper,\r
127                                 ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model,\r
128                                 false,\r
129                                 ExpressionHelper.GetExpressionText(expression),\r
130                                 htmlAttributes);\r
131         }\r
132 \r
133         private static MvcHtmlString HiddenHelper(HtmlHelper htmlHelper, object value, bool useViewData, string expression, IDictionary<string, object> htmlAttributes) {\r
134             Binary binaryValue = value as Binary;\r
135             if (binaryValue != null) {\r
136                 value = binaryValue.ToArray();\r
137             }\r
138 \r
139             byte[] byteArrayValue = value as byte[];\r
140             if (byteArrayValue != null) {\r
141                 value = Convert.ToBase64String(byteArrayValue);\r
142             }\r
143 \r
144             return InputHelper(htmlHelper, InputType.Hidden, expression, value, useViewData, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);\r
145         }\r
146 \r
147         // Password\r
148 \r
149         public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name) {\r
150             return Password(htmlHelper, name, null /* value */);\r
151         }\r
152 \r
153         public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value) {\r
154             return Password(htmlHelper, name, value, null /* htmlAttributes */);\r
155         }\r
156 \r
157         public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {\r
158             return Password(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));\r
159         }\r
160 \r
161         public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {\r
162             return PasswordHelper(htmlHelper, name, value, htmlAttributes);\r
163         }\r
164 \r
165         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
166         public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {\r
167             return PasswordFor(htmlHelper, expression, null /* htmlAttributes */);\r
168         }\r
169 \r
170         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
171         public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {\r
172             return PasswordFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes));\r
173         }\r
174 \r
175         [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]\r
176         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
177         public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {\r
178             if (expression == null) {\r
179                 throw new ArgumentNullException("expression");\r
180             }\r
181 \r
182             return PasswordHelper(htmlHelper,\r
183                                   ExpressionHelper.GetExpressionText(expression),\r
184                                   null /* value */,\r
185                                   htmlAttributes);\r
186         }\r
187 \r
188         private static MvcHtmlString PasswordHelper(HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {\r
189             return InputHelper(htmlHelper, InputType.Password, name, value, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);\r
190         }\r
191 \r
192         // RadioButton\r
193 \r
194         public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value) {\r
195             return RadioButton(htmlHelper, name, value, (object)null /* htmlAttributes */);\r
196         }\r
197 \r
198         public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {\r
199             return RadioButton(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));\r
200         }\r
201 \r
202         public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {\r
203             // Determine whether or not to render the checked attribute based on the contents of ViewData.\r
204             string valueString = Convert.ToString(value, CultureInfo.CurrentCulture);\r
205             bool isChecked = (!String.IsNullOrEmpty(name)) && (String.Equals(htmlHelper.EvalString(name), valueString, StringComparison.OrdinalIgnoreCase));\r
206             // checked attributes is implicit, so we need to ensure that the dictionary takes precedence.\r
207             RouteValueDictionary attributes = htmlAttributes == null ? new RouteValueDictionary() : new RouteValueDictionary(htmlAttributes);\r
208             if (attributes.ContainsKey("checked")) {\r
209                 return InputHelper(htmlHelper, InputType.Radio, name, value, false, false, true, true /* isExplicitValue */, attributes);\r
210             }\r
211 \r
212             return RadioButton(htmlHelper, name, value, isChecked, htmlAttributes);\r
213         }\r
214 \r
215         public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked) {\r
216             return RadioButton(htmlHelper, name, value, isChecked, (object)null /* htmlAttributes */);\r
217         }\r
218 \r
219         public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, object htmlAttributes) {\r
220             return RadioButton(htmlHelper, name, value, isChecked, new RouteValueDictionary(htmlAttributes));\r
221         }\r
222 \r
223         public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, IDictionary<string, object> htmlAttributes) {\r
224             if (value == null) {\r
225                 throw new ArgumentNullException("value");\r
226             }\r
227             // checked attribute is an explicit parameter so it takes precedence.\r
228             RouteValueDictionary attributes = htmlAttributes == null ? new RouteValueDictionary() : new RouteValueDictionary(htmlAttributes);\r
229             attributes.Remove("checked");\r
230             return InputHelper(htmlHelper, InputType.Radio, name, value, false, isChecked, true, true /* isExplicitValue */, attributes);\r
231         }\r
232 \r
233         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
234         public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value) {\r
235             return RadioButtonFor(htmlHelper, expression, value, null /* htmlAttributes */);\r
236         }\r
237 \r
238         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
239         public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, object htmlAttributes) {\r
240             return RadioButtonFor(htmlHelper, expression, value, new RouteValueDictionary(htmlAttributes));\r
241         }\r
242 \r
243         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
244         public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, IDictionary<string, object> htmlAttributes) {\r
245             return RadioButtonHelper(htmlHelper,\r
246                                      ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model,\r
247                                      ExpressionHelper.GetExpressionText(expression),\r
248                                      value,\r
249                                      null /* isChecked */,\r
250                                      htmlAttributes);\r
251         }\r
252 \r
253         private static MvcHtmlString RadioButtonHelper(HtmlHelper htmlHelper, object model, string name, object value, bool? isChecked, IDictionary<string, object> htmlAttributes) {\r
254             if (value == null) {\r
255                 throw new ArgumentNullException("value");\r
256             }\r
257 \r
258             RouteValueDictionary attributes =\r
259                 htmlAttributes == null ? new RouteValueDictionary()\r
260                                        : new RouteValueDictionary(htmlAttributes);\r
261 \r
262             bool explicitValue = isChecked.HasValue;\r
263             if (explicitValue) {\r
264                 attributes.Remove("checked");    // Explicit value must override dictionary\r
265             }\r
266             else {\r
267                 string valueString = Convert.ToString(value, CultureInfo.CurrentCulture);\r
268                 isChecked = model != null &&\r
269                             !String.IsNullOrEmpty(name) &&\r
270                             String.Equals(model.ToString(), valueString, StringComparison.OrdinalIgnoreCase);\r
271             }\r
272 \r
273             return InputHelper(htmlHelper, InputType.Radio, name, value, false /* useViewData */, isChecked ?? false, true /* setId */, true /* isExplicitValue */, attributes);\r
274         }\r
275 \r
276         // TextBox\r
277 \r
278         public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name) {\r
279             return TextBox(htmlHelper, name, null /* value */);\r
280         }\r
281 \r
282         public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value) {\r
283             return TextBox(htmlHelper, name, value, (object)null /* htmlAttributes */);\r
284         }\r
285 \r
286         public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {\r
287             return TextBox(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));\r
288         }\r
289 \r
290         public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {\r
291             return InputHelper(htmlHelper, InputType.Text, name, value, (value == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);\r
292         }\r
293 \r
294         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
295         public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {\r
296             return htmlHelper.TextBoxFor(expression, (IDictionary<string, object>)null);\r
297         }\r
298 \r
299         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
300         public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {\r
301             return htmlHelper.TextBoxFor(expression, new RouteValueDictionary(htmlAttributes));\r
302         }\r
303 \r
304         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]\r
305         public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {\r
306             return TextBoxHelper(htmlHelper,\r
307                                  ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model,\r
308                                  ExpressionHelper.GetExpressionText(expression),\r
309                                  htmlAttributes);\r
310         }\r
311 \r
312         private static MvcHtmlString TextBoxHelper(this HtmlHelper htmlHelper, object model, string expression, IDictionary<string, object> htmlAttributes) {\r
313             return InputHelper(htmlHelper, InputType.Text, expression, model, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);\r
314         }\r
315 \r
316         // Helper methods\r
317 \r
318         private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, IDictionary<string, object> htmlAttributes) {\r
319             name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);\r
320             if (String.IsNullOrEmpty(name)) {\r
321                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");\r
322             }\r
323 \r
324             TagBuilder tagBuilder = new TagBuilder("input");\r
325             tagBuilder.MergeAttributes(htmlAttributes);\r
326             tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));\r
327             tagBuilder.MergeAttribute("name", name, true);\r
328 \r
329             string valueParameter = Convert.ToString(value, CultureInfo.CurrentCulture);\r
330             bool usedModelState = false;\r
331 \r
332             switch (inputType) {\r
333                 case InputType.CheckBox:\r
334                     bool? modelStateWasChecked = htmlHelper.GetModelStateValue(name, typeof(bool)) as bool?;\r
335                     if (modelStateWasChecked.HasValue) {\r
336                         isChecked = modelStateWasChecked.Value;\r
337                         usedModelState = true;\r
338                     }\r
339                     goto case InputType.Radio;\r
340                 case InputType.Radio:\r
341                     if (!usedModelState) {\r
342                         string modelStateValue = htmlHelper.GetModelStateValue(name, typeof(string)) as string;\r
343                         if (modelStateValue != null) {\r
344                             isChecked = String.Equals(modelStateValue, valueParameter, StringComparison.Ordinal);\r
345                             usedModelState = true;\r
346                         }\r
347                     }\r
348                     if (!usedModelState && useViewData) {\r
349                         isChecked = htmlHelper.EvalBoolean(name);\r
350                     }\r
351                     if (isChecked) {\r
352                         tagBuilder.MergeAttribute("checked", "checked");\r
353                     }\r
354                     tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);\r
355                     break;\r
356                 case InputType.Password:\r
357                     if (value != null) {\r
358                         tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);\r
359                     }\r
360                     break;\r
361                 default:\r
362                     string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));\r
363                     tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue);\r
364                     break;\r
365             }\r
366 \r
367             if (setId) {\r
368                 tagBuilder.GenerateId(name);\r
369             }\r
370 \r
371             // If there are any errors for a named field, we add the css attribute.\r
372             ModelState modelState;\r
373             if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState)) {\r
374                 if (modelState.Errors.Count > 0) {\r
375                     tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);\r
376                 }\r
377             }\r
378 \r
379             if (inputType == InputType.CheckBox) {\r
380                 // Render an additional <input type="hidden".../> for checkboxes. This\r
381                 // addresses scenarios where unchecked checkboxes are not sent in the request.\r
382                 // Sending a hidden input makes it possible to know that the checkbox was present\r
383                 // on the page when the request was submitted.\r
384                 StringBuilder inputItemBuilder = new StringBuilder();\r
385                 inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));\r
386 \r
387                 TagBuilder hiddenInput = new TagBuilder("input");\r
388                 hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));\r
389                 hiddenInput.MergeAttribute("name", name);\r
390                 hiddenInput.MergeAttribute("value", "false");\r
391                 inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));\r
392                 return MvcHtmlString.Create(inputItemBuilder.ToString());\r
393             }\r
394 \r
395             return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);\r
396         }\r
397     }\r
398 }\r