GetHtml(HttpContext httpContext, XcstWriter output) { IAntiforgery antiforgery = GetAntiforgeryService(httpContext); AntiforgeryTokenSet tokenSet = antiforgery.GetAndStoreTokens(httpContext); output.WriteStartElement("input"); output.WriteAttributeString("type", "hidden"); output.WriteAttributeString("name", tokenSet.FormFieldName); output.WriteAttributeString("value", tokenSet.RequestToken); output.WriteEndElement(); }
public static void WriteBoolean(string key, bool value, XcstWriter output) { if (value) { output.WriteAttributeString(key, key); } }
public static void WriteClass(string?cssClass, IDictionary <string, object>?htmlAttributes, XcstWriter output) { // NOTE: For backcompat, the dictionary class must be a non-null string to be joined // with the library class, otherwise it's ignored. If there's no library class, // the dictionary class can be null, resulting in an empty attribute. // // The library class must not be null or empty, which allows you to call this method // without having to make that check. // // See also HtmlAttributeDictionary.SetAttributes bool cssClassHasValue = !String.IsNullOrEmpty(cssClass); object?dictClass = null; bool dictHasClass = htmlAttributes != null && htmlAttributes.TryGetValue("class", out dictClass); if (cssClassHasValue || dictHasClass) { string joinedClass = (cssClassHasValue && dictClass is string s) ? s + " " + cssClass : (cssClassHasValue) ? cssClass ! : output.SimpleContent.Convert(dictClass); output.WriteAttributeString("class", joinedClass); } }
internal static void WriteId(string name, XcstWriter output) { string?sanitizedId = TagBuilder.CreateSanitizedId(name); if (!String.IsNullOrEmpty(sanitizedId)) { output.WriteAttributeString("id", sanitizedId); } }
internal static void TextAreaHelper( HtmlHelper htmlHelper, XcstWriter output, ModelMetadata metadata, string name, IDictionary <string, object> rowsAndColumns, HtmlAttribs?htmlAttributes, string?innerHtmlPrefix = null) { string fullName = htmlHelper.ViewData.TemplateInfo.GetFullHtmlFieldName(name); if (String.IsNullOrEmpty(fullName)) { throw new ArgumentNullException(nameof(name)); } output.WriteStartElement("textarea"); HtmlAttributeHelper.WriteId(fullName, output); output.WriteAttributeString("name", fullName); HtmlAttributeHelper.WriteAttributes(rowsAndColumns, output); bool explicitRowsAndCols = rowsAndColumns != implicitRowsAndColumns; // If there are any errors for a named field, we add the css attribute. string?cssClass = (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out ModelState modelState) && modelState.Errors.Count > 0) ? HtmlHelper.ValidationInputCssClassName : null; HtmlAttributeHelper.WriteClass(cssClass, htmlAttributes, output); HtmlAttributeHelper.WriteAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata), output); // name cannnot be overridden, and class was already written // explicit rows and cols cannot be overridden HtmlAttributeHelper.WriteAttributes( htmlAttributes, output, excludeFn: n => n == "name" || n == "class" || (explicitRowsAndCols && (n == "rows" || n == "cols"))); string?value; if (modelState?.Value != null) { value = modelState.Value.AttemptedValue; } else if (metadata.Model != null) { value = Convert.ToString(metadata.Model, CultureInfo.CurrentCulture); } else { value = String.Empty; } // The first newline is always trimmed when a TextArea is rendered, so we add an extra one // in case the value being rendered is something like "\r\nHello". output.WriteString((innerHtmlPrefix ?? Environment.NewLine) + value); output.WriteEndElement(); }
static void CheckBoxHelper( HtmlHelper htmlHelper, IXcstPackage package, ISequenceWriter <XElement> output, ModelMetadata?metadata, string name, bool?isChecked, HtmlAttribs?htmlAttributes) { XcstWriter inputWriter = DocumentWriter.CastElement(package, output); XcstWriter hiddenWriter = DocumentWriter.CastElement(package, output); bool explicitChecked = isChecked.HasValue; if (explicitChecked && htmlAttributes != null && htmlAttributes.ContainsKey("checked")) { htmlAttributes = htmlAttributes.Clone(); htmlAttributes.Remove("checked"); // Explicit value must override dictionary } InputHelper( htmlHelper, inputWriter, InputType.CheckBox, metadata, name, value: "true", useViewData: !explicitChecked, isChecked: isChecked ?? false, setId: true, isExplicitValue: false, format: null, htmlAttributes: htmlAttributes); string fullName = Name(htmlHelper, name); // Render an additional <input type="hidden".../> for checkboxes. This // addresses scenarios where unchecked checkboxes are not sent in the request. // Sending a hidden input makes it possible to know that the checkbox was present // on the page when the request was submitted. hiddenWriter.WriteStartElement("input"); hiddenWriter.WriteAttributeString("type", HtmlHelper.GetInputTypeString(InputType.Hidden)); hiddenWriter.WriteAttributeString("name", fullName); hiddenWriter.WriteAttributeString("value", "false"); hiddenWriter.WriteEndElement(); }
public static void UrlTemplate(HtmlHelper html, IXcstPackage package, ISequenceWriter <object> seqOutput) { XcstWriter output = DocumentWriter.CastElement(package, seqOutput); ViewDataDictionary viewData = html.ViewData; output.WriteStartElement("a"); output.WriteAttributeString("href", Convert.ToString(viewData.Model, CultureInfo.InvariantCulture)); output.WriteString(output.SimpleContent.Convert(viewData.TemplateInfo.FormattedModelValue)); output.WriteEndElement(); }
public static void ImageUrlTemplate(HtmlHelper html, IXcstPackage package, ISequenceWriter <object> seqOutput) { ViewDataDictionary viewData = html.ViewData; if (viewData.Model != null) { XcstWriter output = DocumentWriter.CastElement(package, seqOutput); output.WriteStartElement("img"); output.WriteAttributeString("src", Convert.ToString(viewData.Model, CultureInfo.InvariantCulture)); output.WriteEndElement(); } }
internal static void WriteOption(SelectListItem item, XcstWriter output) { output.WriteStartElement("option"); if (item.Value != null) { output.WriteAttributeString("value", item.Value); } HtmlAttributeHelper.WriteBoolean("selected", item.Selected, output); HtmlAttributeHelper.WriteBoolean("disabled", item.Disabled, output); output.WriteString(item.Text); output.WriteEndElement(); }
static void WriteOptions(string?optionLabel, IEnumerable <SelectListItem> selectList, XcstWriter output) { // Make optionLabel the first item that gets rendered. if (optionLabel != null) { WriteOption(new SelectListItem { Text = optionLabel, Value = String.Empty, Selected = false }, output); } // Group items in the SelectList if requested. // Treat each item with Group == null as a member of a unique group // so they are added according to the original order. var groupedSelectList = selectList.GroupBy <SelectListItem, int>( i => (i.Group is null) ? i.GetHashCode() : i.Group.GetHashCode()); foreach (var group in groupedSelectList) { SelectListGroup?optGroup = group.First().Group; if (optGroup != null) { output.WriteStartElement("optgroup"); if (optGroup.Name != null) { output.WriteAttributeString("label", optGroup.Name); } HtmlAttributeHelper.WriteBoolean("disabled", optGroup.Disabled, output); } foreach (SelectListItem item in group) { WriteOption(item, output); } if (optGroup != null) { output.WriteEndElement(); // </optgroup> } } }
public static void BooleanTemplate(HtmlHelper html, IXcstPackage package, ISequenceWriter <object> seqOutput) { XcstWriter output = DocumentWriter.CastElement(package, seqOutput); ViewDataDictionary viewData = html.ViewData; bool?value = null; if (viewData.Model != null) { value = Convert.ToBoolean(viewData.Model, CultureInfo.InvariantCulture); } if (viewData.ModelMetadata.IsNullableValueType) { output.WriteStartElement("select"); string?className = DefaultEditorTemplates.GetEditorCssClass(new EditorInfo("Boolean", "select"), "list-box tri-state"); HtmlAttributeHelper.WriteClass(className, null, output); HtmlAttributeHelper.WriteBoolean("disabled", true, output); foreach (SelectListItem item in DefaultEditorTemplates.TriStateValues(value)) { SelectInstructions.WriteOption(item, output); } output.WriteEndElement(); } else { output.WriteStartElement("input"); output.WriteAttributeString("type", "checkbox"); string?className = DefaultEditorTemplates.GetEditorCssClass(new EditorInfo("Boolean", "input", InputType.CheckBox), "check-box"); HtmlAttributeHelper.WriteClass(className, null, output); HtmlAttributeHelper.WriteBoolean("disabled", true, output); HtmlAttributeHelper.WriteBoolean("checked", value.GetValueOrDefault(), output); output.WriteEndElement(); } }
internal static void LabelHelper( HtmlHelper html, XcstWriter output, ModelMetadata metadata, string expression, string?labelText = null, HtmlAttribs?htmlAttributes = null) { string htmlFieldName = expression; string resolvedLabelText = labelText ?? metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); if (String.IsNullOrEmpty(resolvedLabelText)) { return; } string fullFieldName = html.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName); output.WriteStartElement("label"); output.WriteAttributeString("for", TagBuilder.CreateSanitizedId(fullFieldName)); HtmlAttributeHelper.WriteAttributes(htmlAttributes, output); output.WriteString(resolvedLabelText); output.WriteEndElement(); }
internal static void ObjectTemplate(HtmlHelper html, IXcstPackage package, ISequenceWriter <object> seqOutput, TemplateHelpers.TemplateHelperDelegate templateHelper) { ViewDataDictionary viewData = html.ViewData; ModelMetadata modelMetadata = viewData.ModelMetadata; if (modelMetadata.Model is null || viewData.TemplateInfo.TemplateDepth > 1) { MetadataInstructions.DisplayTextHelper(html, seqOutput, modelMetadata); return; } var filteredProperties = DisplayInstructions.DisplayProperties(html); var groupedProperties = filteredProperties.GroupBy(p => p.GroupName()); bool createFieldset = groupedProperties.Any(g => g.Key != null); foreach (var group in groupedProperties) { XcstWriter?fieldsetWriter = null; if (createFieldset) { fieldsetWriter = DocumentWriter.CastElement(package, seqOutput); fieldsetWriter.WriteStartElement("fieldset"); fieldsetWriter.WriteStartElement("legend"); fieldsetWriter.WriteString(group.Key); fieldsetWriter.WriteEndElement(); } foreach (ModelMetadata propertyMeta in group) { XcstWriter?fieldWriter = null; if (!propertyMeta.HideSurroundingHtml) { XcstDelegate <object>?memberTemplate = DisplayInstructions.MemberTemplate(html, propertyMeta); if (memberTemplate != null) { memberTemplate(null !/* argument is not used */, fieldsetWriter ?? seqOutput); continue; } XcstWriter labelWriter = fieldsetWriter ?? DocumentWriter.CastElement(package, seqOutput); labelWriter.WriteStartElement("div"); labelWriter.WriteAttributeString("class", "display-label"); labelWriter.WriteString(propertyMeta.GetDisplayName() ?? String.Empty); labelWriter.WriteEndElement(); fieldWriter = fieldsetWriter ?? DocumentWriter.CastElement(package, seqOutput); fieldWriter.WriteStartElement("div"); fieldWriter.WriteAttributeString("class", "display-field"); } templateHelper( html, package, fieldWriter ?? fieldsetWriter ?? seqOutput, propertyMeta, htmlFieldName: propertyMeta.PropertyName, templateName: null, membersNames: null, DataBoundControlMode.ReadOnly, additionalViewData: null ); if (!propertyMeta.HideSurroundingHtml) { fieldWriter !.WriteEndElement(); // </div> } } if (createFieldset) { fieldsetWriter !.WriteEndElement(); // </fieldset> } } }
internal static void ValidationMessageHelper( HtmlHelper htmlHelper, XcstWriter output, ModelMetadata modelMetadata, string expression, string?validationMessage, HtmlAttribs?htmlAttributes, string?tag) { ViewDataDictionary viewData = htmlHelper.ViewData; string modelName = viewData.TemplateInfo.GetFullHtmlFieldName(expression); FormContext?formContext = htmlHelper.ViewContext.GetFormContextForClientValidation(); if (!viewData.ModelState.ContainsKey(modelName) && formContext is null) { return; } ModelState? modelState = viewData.ModelState[modelName]; ModelErrorCollection?modelErrors = modelState?.Errors; ModelError?modelError = (modelErrors is null || modelErrors.Count == 0) ? null : (modelErrors.FirstOrDefault(m => !String.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0]); if (modelError is null && formContext is null) { return; } if (String.IsNullOrEmpty(tag)) { tag = htmlHelper.ViewContext.ValidationMessageElement; } string validationClass = (modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName; output.WriteStartElement(tag !); HtmlAttributeHelper.WriteClass(validationClass, htmlAttributes, output); if (formContext != null) { bool replaceValidationMessageContents = String.IsNullOrEmpty(validationMessage); if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled) { output.WriteAttributeString("data-valmsg-for", modelName); output.WriteAttributeString("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant()); } } // class was already written HtmlAttributeHelper.WriteAttributes(htmlAttributes, output, excludeFn: n => n == "class"); if (!String.IsNullOrEmpty(validationMessage)) { output.WriteString(validationMessage); } else if (modelError != null) { output.WriteString(GetUserErrorMessageOrDefault(modelError, modelState)); } output.WriteEndElement(); }
static void SelectInternal( HtmlHelper htmlHelper, XcstWriter output, ModelMetadata?metadata, string?optionLabel, string name, IEnumerable <SelectListItem>?selectList, bool allowMultiple, HtmlAttribs?htmlAttributes) { ViewDataDictionary viewData = htmlHelper.ViewData; string fullName = viewData.TemplateInfo.GetFullHtmlFieldName(name); if (String.IsNullOrEmpty(fullName)) { throw new ArgumentNullException(nameof(name)); } bool usedViewData = false; // If we got a null selectList, try to use ViewData to get the list of items. if (selectList is null) { selectList = GetSelectData(htmlHelper, name); usedViewData = true; } object?defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string)); // If we haven't already used ViewData to get the entire list of items then we need to // use the ViewData-supplied value before using the parameter-supplied value. if (defaultValue is null) { if (metadata is null) { if (!usedViewData && !String.IsNullOrEmpty(name)) { defaultValue = viewData.Eval(name); } } else { defaultValue = metadata.Model; } } if (defaultValue != null) { selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple); } output.WriteStartElement("select"); HtmlAttributeHelper.WriteId(fullName, output); output.WriteAttributeString("name", fullName); HtmlAttributeHelper.WriteBoolean("multiple", allowMultiple, output); // If there are any errors for a named field, we add the css attribute. string?cssClass = (viewData.ModelState.TryGetValue(fullName, out ModelState modelState) && modelState.Errors.Count > 0) ? HtmlHelper.ValidationInputCssClassName : null; var validationAttribs = htmlHelper.GetUnobtrusiveValidationAttributes( name, metadata #if !ASPNETMVC , excludeMinMaxLength: !allowMultiple #endif ); HtmlAttributeHelper.WriteClass(cssClass, htmlAttributes, output); HtmlAttributeHelper.WriteAttributes(validationAttribs, output); // name cannnot be overridden, and class was already written HtmlAttributeHelper.WriteAttributes(htmlAttributes, output, excludeFn: n => n == "name" || n == "class"); WriteOptions(optionLabel, selectList, output); output.WriteEndElement(); // </select> }
public static void WriteAttribute(string key, object?value, XcstWriter output) => output.WriteAttributeString(key, output.SimpleContent.Convert(value));
public static void ValidationSummary( HtmlHelper htmlHelper, XcstWriter output, bool includePropertyErrors = false, string?message = null, HtmlAttribs?htmlAttributes = null, string?headingTag = null) { if (htmlHelper is null) { throw new ArgumentNullException(nameof(htmlHelper)); } FormContext?formContext = htmlHelper.ViewContext.GetFormContextForClientValidation(); if (htmlHelper.ViewData.ModelState.IsValid) { if (formContext is null) { // No client side validation return; } // TODO: This isn't really about unobtrusive; can we fix up non-unobtrusive to get rid of this, too? if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled && !includePropertyErrors) { // No client-side updates return; } } string validationClass = (htmlHelper.ViewData.ModelState.IsValid) ? HtmlHelper.ValidationSummaryValidCssClassName : HtmlHelper.ValidationSummaryCssClassName; output.WriteStartElement("div"); HtmlAttributeHelper.WriteClass(validationClass, htmlAttributes, output); if (formContext != null) { if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled) { if (includePropertyErrors) { // Only put errors in the validation summary if they're supposed to be included there output.WriteAttributeString("data-valmsg-summary", "true"); } } } // class was already written HtmlAttributeHelper.WriteAttributes(htmlAttributes, output, excludeFn: n => n == "class"); if (!String.IsNullOrEmpty(message)) { if (String.IsNullOrEmpty(headingTag)) { headingTag = htmlHelper.ViewContext.ValidationSummaryMessageElement; } output.WriteStartElement(headingTag !); output.WriteString(message); output.WriteEndElement(); } output.WriteStartElement("ul"); bool empty = true; IEnumerable <ModelState> modelStates = GetModelStateList(htmlHelper, includePropertyErrors); foreach (ModelState modelState in modelStates) { foreach (ModelError modelError in modelState.Errors) { string?errorText = GetUserErrorMessageOrDefault(modelError, modelState: null); if (!String.IsNullOrEmpty(errorText)) { empty = false; output.WriteStartElement("li"); output.WriteString(errorText); output.WriteEndElement(); } } } if (empty) { output.WriteStartElement("li"); output.WriteAttributeString("style", "display:none"); output.WriteEndElement(); } output.WriteEndElement(); // </ul> output.WriteEndElement(); // </div> }