Exemple #1
0
        protected virtual TagBuilder GenerateInput(
            [NotNull] ViewContext viewContext,
            InputType inputType,
            ModelMetadata metadata,
            string name,
            object value,
            bool useViewData,
            bool isChecked,
            bool setId,
            bool isExplicitValue,
            string format,
            IDictionary <string, object> htmlAttributes)
        {
            // Not valid to use TextBoxForModel() and so on in a top-level view; would end up with an unnamed input
            // elements. But we support the *ForModel() methods in any lower-level template, once HtmlFieldPrefix is
            // non-empty.
            var fullName = GetFullHtmlFieldName(viewContext, name);

            if (string.IsNullOrEmpty(fullName))
            {
                throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, "name");
            }

            var tagBuilder = new TagBuilder("input");

            tagBuilder.MergeAttributes(htmlAttributes);
            tagBuilder.MergeAttribute("type", GetInputTypeString(inputType));
            tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);

            var valueParameter = FormatValue(value, format);
            var usedModelState = false;

            switch (inputType)
            {
            case InputType.CheckBox:
                var modelStateWasChecked = GetModelStateValue(viewContext, fullName, typeof(bool)) as bool?;
                if (modelStateWasChecked.HasValue)
                {
                    isChecked      = modelStateWasChecked.Value;
                    usedModelState = true;
                }

                goto case InputType.Radio;

            case InputType.Radio:
                if (!usedModelState)
                {
                    var modelStateValue = GetModelStateValue(viewContext, fullName, typeof(string)) as string;
                    if (modelStateValue != null)
                    {
                        isChecked      = string.Equals(modelStateValue, valueParameter, StringComparison.Ordinal);
                        usedModelState = true;
                    }
                }

                if (!usedModelState && useViewData)
                {
                    isChecked = EvalBoolean(viewContext, fullName);
                }

                if (isChecked)
                {
                    tagBuilder.MergeAttribute("checked", "checked");
                }

                tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
                break;

            case InputType.Password:
                if (value != null)
                {
                    tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
                }

                break;

            case InputType.Text:
            default:
                var attributeValue = (string)GetModelStateValue(viewContext, fullName, typeof(string));
                if (attributeValue == null)
                {
                    attributeValue = useViewData ? EvalString(viewContext, fullName, format) : valueParameter;
                }

                tagBuilder.MergeAttribute("value", attributeValue, replaceExisting: isExplicitValue);
                break;
            }

            if (setId)
            {
                tagBuilder.GenerateId(fullName, IdAttributeDotReplacement);
            }

            // If there are any errors for a named field, we add the CSS attribute.
            ModelState modelState;

            if (viewContext.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0)
            {
                tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
            }

            tagBuilder.MergeAttributes(GetValidationAttributes(viewContext, metadata, name));

            return(tagBuilder);
        }
Exemple #2
0
        /// <inheritdoc />
        public virtual TagBuilder GenerateValidationSummary(
            [NotNull] ViewContext viewContext,
            bool excludePropertyErrors,
            string message,
            string headerTag,
            object htmlAttributes)
        {
            var formContext = viewContext.ClientValidationEnabled ? viewContext.FormContext : null;

            if (viewContext.ViewData.ModelState.IsValid && (formContext == null || excludePropertyErrors))
            {
                // No client side validation/updates
                return(null);
            }

            string wrappedMessage;

            if (!string.IsNullOrEmpty(message))
            {
                if (string.IsNullOrEmpty(headerTag))
                {
                    headerTag = viewContext.ValidationSummaryMessageElement;
                }
                var messageTag = new TagBuilder(headerTag);
                messageTag.SetInnerText(message);
                wrappedMessage = messageTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
            }
            else
            {
                wrappedMessage = null;
            }

            // If excludePropertyErrors is true, describe any validation issue with the current model in a single item.
            // Otherwise, list individual property errors.
            var htmlSummary = new StringBuilder();
            var modelStates = ValidationHelpers.GetModelStateList(viewContext.ViewData, excludePropertyErrors);

            foreach (var modelState in modelStates)
            {
                foreach (var modelError in modelState.Errors)
                {
                    var errorText = ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState: null);

                    if (!string.IsNullOrEmpty(errorText))
                    {
                        var listItem = new TagBuilder("li");
                        listItem.SetInnerText(errorText);
                        htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
                    }
                }
            }

            if (htmlSummary.Length == 0)
            {
                htmlSummary.AppendLine(HiddenListItem);
            }

            var unorderedList = new TagBuilder("ul")
            {
                InnerHtml = htmlSummary.ToString()
            };

            var tagBuilder = new TagBuilder("div");

            tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));

            if (viewContext.ViewData.ModelState.IsValid)
            {
                tagBuilder.AddCssClass(HtmlHelper.ValidationSummaryValidCssClassName);
            }
            else
            {
                tagBuilder.AddCssClass(HtmlHelper.ValidationSummaryCssClassName);
            }

            tagBuilder.InnerHtml = wrappedMessage + unorderedList.ToString(TagRenderMode.Normal);

            if (formContext != null && !excludePropertyErrors)
            {
                // Inform the client where to replace the list of property errors after validation.
                tagBuilder.MergeAttribute("data-valmsg-summary", "true");
            }

            return(tagBuilder);
        }
Exemple #3
0
        /// <inheritdoc />
        public virtual TagBuilder GenerateTextArea(
            [NotNull] ViewContext viewContext,
            ModelMetadata metadata,
            string name,
            int rows,
            int columns,
            object htmlAttributes)
        {
            if (rows < 0)
            {
                throw new ArgumentOutOfRangeException("rows", Resources.HtmlHelper_TextAreaParameterOutOfRange);
            }

            if (columns < 0)
            {
                throw new ArgumentOutOfRangeException("columns", Resources.HtmlHelper_TextAreaParameterOutOfRange);
            }

            var fullName = GetFullHtmlFieldName(viewContext, name);

            if (string.IsNullOrEmpty(fullName))
            {
                throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, "name");
            }

            ModelState modelState;

            viewContext.ViewData.ModelState.TryGetValue(fullName, out modelState);

            var value = string.Empty;

            if (modelState != null && modelState.Value != null)
            {
                value = modelState.Value.AttemptedValue;
            }
            else if (metadata.Model != null)
            {
                value = metadata.Model.ToString();
            }

            var tagBuilder = new TagBuilder("textarea");

            tagBuilder.GenerateId(fullName, IdAttributeDotReplacement);
            tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes), true);
            if (rows > 0)
            {
                tagBuilder.MergeAttribute("rows", rows.ToString(CultureInfo.InvariantCulture), true);
            }

            if (columns > 0)
            {
                tagBuilder.MergeAttribute("columns", columns.ToString(CultureInfo.InvariantCulture), true);
            }

            tagBuilder.MergeAttribute("name", fullName, true);
            tagBuilder.MergeAttributes(GetValidationAttributes(viewContext, metadata, name));

            // If there are any errors for a named field, we add this CSS attribute.
            if (modelState != null && modelState.Errors.Count > 0)
            {
                tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
            }

            // 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".
            tagBuilder.InnerHtml = Environment.NewLine + WebUtility.HtmlEncode(value);

            return(tagBuilder);
        }
Exemple #4
0
        /// <inheritdoc />
        public virtual TagBuilder GenerateValidationMessage(
            [NotNull] ViewContext viewContext,
            string name,
            string message,
            string tag,
            object htmlAttributes)
        {
            var fullName = GetFullHtmlFieldName(viewContext, name);

            if (string.IsNullOrEmpty(fullName))
            {
                throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, "expression");
            }

            var formContext = viewContext.ClientValidationEnabled ? viewContext.FormContext : null;

            if (!viewContext.ViewData.ModelState.ContainsKey(fullName) && formContext == null)
            {
                return(null);
            }

            ModelState modelState;
            var        tryGetModelStateResult = viewContext.ViewData.ModelState.TryGetValue(fullName, out modelState);
            var        modelErrors            = tryGetModelStateResult ? modelState.Errors : null;

            ModelError modelError = null;

            if (modelErrors != null && modelErrors.Count != 0)
            {
                modelError = modelErrors.FirstOrDefault(m => !string.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0];
            }

            if (modelError == null && formContext == null)
            {
                return(null);
            }

            // Even if there are no model errors, we generate the span and add the validation message
            // if formContext is not null.
            if (string.IsNullOrEmpty(tag))
            {
                tag = viewContext.ValidationMessageElement;
            }
            var tagBuilder = new TagBuilder(tag);

            tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));

            // Only the style of the span is changed according to the errors if message is null or empty.
            // Otherwise the content and style is handled by the client-side validation.
            var className = (modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName;

            tagBuilder.AddCssClass(className);

            if (!string.IsNullOrEmpty(message))
            {
                tagBuilder.SetInnerText(message);
            }
            else if (modelError != null)
            {
                tagBuilder.SetInnerText(ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState));
            }

            if (formContext != null)
            {
                tagBuilder.MergeAttribute("data-valmsg-for", fullName);

                var replaceValidationMessageContents = string.IsNullOrEmpty(message);
                tagBuilder.MergeAttribute("data-valmsg-replace",
                                          replaceValidationMessageContents.ToString().ToLowerInvariant());
            }

            return(tagBuilder);
        }
Exemple #5
0
        /// <inheritdoc />
        public virtual TagBuilder GenerateSelect(
            [NotNull] ViewContext viewContext,
            ModelMetadata metadata,
            string optionLabel,
            string name,
            IEnumerable <SelectListItem> selectList,
            bool allowMultiple,
            object htmlAttributes)
        {
            var fullName = GetFullHtmlFieldName(viewContext, name);

            if (string.IsNullOrEmpty(fullName))
            {
                throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, "name");
            }

            // If we got a null selectList, try to use ViewData to get the list of items.
            var usedViewData = false;

            if (selectList == null)
            {
                if (string.IsNullOrEmpty(name))
                {
                    // Avoid ViewData.Eval() throwing an ArgumentException with a different parameter name. Note this
                    // is an extreme case since users must pass a non-null selectList to use CheckBox() or ListBox()
                    // in a template, where a null or empty name has meaning.
                    throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, "name");
                }

                selectList   = GetSelectListItems(viewContext, name);
                usedViewData = true;
            }

            var type         = allowMultiple ? typeof(string[]) : typeof(string);
            var defaultValue = GetModelStateValue(viewContext, fullName, type);

            // 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 == null && !string.IsNullOrEmpty(name))
            {
                if (!usedViewData)
                {
                    defaultValue = viewContext.ViewData.Eval(name);
                }
                else if (metadata != null)
                {
                    defaultValue = metadata.Model;
                }
            }

            if (defaultValue != null)
            {
                selectList = UpdateSelectListItemsWithDefaultValue(selectList, defaultValue, allowMultiple);
            }

            // Convert each ListItem to an <option> tag and wrap them with <optgroup> if requested.
            var listItemBuilder = GenerateGroupsAndOptions(optionLabel, selectList);

            var tagBuilder = new TagBuilder("select")
            {
                InnerHtml = listItemBuilder.ToString()
            };

            tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
            tagBuilder.MergeAttribute("name", fullName, true /* replaceExisting */);
            tagBuilder.GenerateId(fullName, IdAttributeDotReplacement);
            if (allowMultiple)
            {
                tagBuilder.MergeAttribute("multiple", "multiple");
            }

            // If there are any errors for a named field, we add the css attribute.
            ModelState modelState;

            if (viewContext.ViewData.ModelState.TryGetValue(fullName, out modelState))
            {
                if (modelState.Errors.Count > 0)
                {
                    tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
                }
            }

            tagBuilder.MergeAttributes(GetValidationAttributes(viewContext, metadata, name));

            return(tagBuilder);
        }