コード例 #1
0
ファイル: FormTagHelper.cs プロジェクト: cemalshukriev/Mvc
        /// <inheritdoc />
        /// <remarks>
        /// Does nothing if user provides an <c>action</c> attribute and <see cref="Antiforgery"/> is <c>null</c> or
        /// <c>false</c>.
        /// </remarks>
        /// <exception cref="InvalidOperationException">
        /// Thrown if <c>action</c> attribute is provided and <see cref="Action"/> or <see cref="Controller"/> are
        /// non-<c>null</c> or if the user provided <c>asp-route-*</c> attributes.
        /// </exception>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }
            if (Method != null)
            {
                output.CopyHtmlAttribute(nameof(Method), context);
            }

            var antiforgeryDefault = true;

            // If "action" is already set, it means the user is attempting to use a normal <form>.
            if (output.Attributes.ContainsName(HtmlActionAttributeName))
            {
                if (Action != null || Controller != null || Area != null || Route != null || RouteValues.Count != 0)
                {
                    // User also specified bound attributes we cannot use.
                    throw new InvalidOperationException(
                        Resources.FormatFormTagHelper_CannotOverrideAction(
                            "<form>",
                            HtmlActionAttributeName,
                            ActionAttributeName,
                            ControllerAttributeName,
                            AreaAttributeName,
                            RouteAttributeName,
                            RouteValuesPrefix));
                }

                // User is using the FormTagHelper like a normal <form> tag. Antiforgery default should be false to
                // not force the antiforgery token on the user.
                antiforgeryDefault = false;
            }
            else
            {
                IDictionary<string, object> routeValues = null;
                if (_routeValues != null && _routeValues.Count > 0)
                {
                    // Convert from Dictionary<string, string> to Dictionary<string, object>.
                    routeValues = new Dictionary<string, object>(_routeValues.Count, StringComparer.OrdinalIgnoreCase);
                    foreach (var routeValue in _routeValues)
                    {
                        routeValues.Add(routeValue.Key, routeValue.Value);
                    }
                }

                if (Area != null)
                {
                    if (routeValues == null)
                    {
                        routeValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                    }

                    // Unconditionally replace any value from asp-route-area. 
                    routeValues["area"] = Area;
                }

                TagBuilder tagBuilder;
                if (Route == null)
                {
                    tagBuilder = Generator.GenerateForm(
                        ViewContext,
                        Action,
                        Controller,
                        routeValues,
                        method: null,
                        htmlAttributes: null);
                }
                else if (Action != null || Controller != null)
                {
                    // Route and Action or Controller were specified. Can't determine the action attribute.
                    throw new InvalidOperationException(
                        Resources.FormatFormTagHelper_CannotDetermineActionWithRouteAndActionOrControllerSpecified(
                            "<form>",
                            RouteAttributeName,
                            ActionAttributeName,
                            ControllerAttributeName,
                            HtmlActionAttributeName));
                }
                else
                {
                    tagBuilder = Generator.GenerateRouteForm(
                        ViewContext,
                        Route,
                        routeValues,
                        method: null,
                        htmlAttributes: null);
                }

                if (tagBuilder != null)
                {
                    output.MergeAttributes(tagBuilder);
                    output.PostContent.AppendHtml(tagBuilder.InnerHtml);
                }

                if (string.Equals(Method, FormMethod.Get.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    antiforgeryDefault = false;
                }
            }

            if (Antiforgery ?? antiforgeryDefault)
            {
                var antiforgeryTag = Generator.GenerateAntiforgery(ViewContext);
                if (antiforgeryTag != null)
                {
                    output.PostContent.AppendHtml(antiforgeryTag);
                }
            }
        }
コード例 #2
0
ファイル: ImageTagHelper.cs プロジェクト: ymd1223/Mvc
        /// <inheritdoc />
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            output.CopyHtmlAttribute(SrcAttributeName, context);
            ProcessUrlAttribute(SrcAttributeName, output);

            if (AppendVersion)
            {
                EnsureFileVersionProvider();

                // Retrieve the TagHelperOutput variation of the "src" attribute in case other TagHelpers in the
                // pipeline have touched the value. If the value is already encoded this ImageTagHelper may
                // not function properly.
                Src = output.Attributes[SrcAttributeName].Value as string;

                output.Attributes.SetAttribute(SrcAttributeName, _fileVersionProvider.AddFileVersionToPath(Src));
            }
        }
コード例 #3
0
ファイル: OptionTagHelper.cs プロジェクト: cemalshukriev/Mvc
        /// <inheritdoc />
        /// <remarks>
        /// Does nothing unless <see cref="TagHelperContext.Items"/> contains a
        /// <see cref="SelectTagHelper"/> <see cref="Type"/> entry and that entry is a non-<c>null</c>
        /// <see cref="CurrentValues"/> instance. Also does nothing if the associated &lt;option&gt; is already
        /// selected.
        /// </remarks>
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // Pass through attributes that are also well-known HTML attributes.
            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            // Nothing to do if this <option/> is already selected.
            if (!output.Attributes.ContainsName("selected"))
            {
                // Is this <option/> element a child of a <select/> element the SelectTagHelper targeted?
                object formDataEntry;
                context.Items.TryGetValue(typeof(SelectTagHelper), out formDataEntry);

                // ... And did the SelectTagHelper determine any selected values?
                var currentValues = formDataEntry as CurrentValues;
                if (currentValues?.Values != null && currentValues.Values.Count != 0)
                {
                    // Select this <option/> element if value attribute or (if no value attribute) body matches a
                    // selected value. Body is encoded as-needed while executing child content. But TagHelperOutput
                    // itself encodes attribute values later, when start tag is generated.
                    bool selected;
                    if (Value != null)
                    {
                        selected = currentValues.Values.Contains(Value);
                    }
                    else
                    {
                        if (currentValues.ValuesAndEncodedValues == null)
                        {
                            // Include encoded versions of all selected values when comparing with body.
                            var allValues = new HashSet<string>(currentValues.Values, StringComparer.OrdinalIgnoreCase);
                            foreach (var selectedValue in currentValues.Values)
                            {
                                allValues.Add(Generator.Encode(selectedValue));
                            }

                            currentValues.ValuesAndEncodedValues = allValues;
                        }

                        TagHelperContent childContent;
                        if (output.IsContentModified)
                        {
                            // Another tag helper has modified the body. Use what they wrote.
                            childContent = output.Content;
                        }
                        else
                        {
                            childContent = await output.GetChildContentAsync();
                        }

                        selected = currentValues.ValuesAndEncodedValues.Contains(childContent.GetContent());
                    }

                    if (selected)
                    {
                        output.Attributes.Add("selected", "selected");
                    }
                }
            }
        }
コード例 #4
0
ファイル: LinkTagHelper.cs プロジェクト: cemalshukriev/Mvc
        /// <inheritdoc />
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // Pass through attribute that is also a well-known HTML attribute.
            if (Href != null)
            {
                output.CopyHtmlAttribute(HrefAttributeName, context);
            }

            // If there's no "href" attribute in output.Attributes this will noop.
            ProcessUrlAttribute(HrefAttributeName, output);

            // Retrieve the TagHelperOutput variation of the "href" attribute in case other TagHelpers in the
            // pipeline have touched the value. If the value is already encoded this LinkTagHelper may
            // not function properly.
            Href = output.Attributes[HrefAttributeName]?.Value as string;

            Mode mode;
            if (!AttributeMatcher.TryDetermineMode(context, ModeDetails, Compare, out mode))
            {
                // No attributes matched so we have nothing to do
                return;
            }

            if (AppendVersion == true)
            {
                EnsureFileVersionProvider();

                if (Href != null)
                {
                    var index = output.Attributes.IndexOfName(HrefAttributeName);
                    output.Attributes[index] = new TagHelperAttribute(
                        HrefAttributeName,
                        _fileVersionProvider.AddFileVersionToPath(Href));
                }
            }

            var builder = new DefaultTagHelperContent();
            if (mode == Mode.GlobbedHref || mode == Mode.Fallback && !string.IsNullOrEmpty(HrefInclude))
            {
                BuildGlobbedLinkTags(output.Attributes, builder);
                if (string.IsNullOrEmpty(Href))
                {
                    // Only HrefInclude is specified. Don't render the original tag.
                    output.TagName = null;
                    output.Content.SetHtmlContent(HtmlString.Empty);
                }
            }

            if (mode == Mode.Fallback)
            {
                string resolvedUrl;
                if (TryResolveUrl(FallbackHref, resolvedUrl: out resolvedUrl))
                {
                    FallbackHref = resolvedUrl;
                }

                BuildFallbackBlock(builder);
            }

            output.PostElement.SetHtmlContent(builder);
        }
コード例 #5
0
ファイル: InputTagHelper.cs プロジェクト: ymd1223/Mvc
        /// <inheritdoc />
        /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks>
        /// <exception cref="InvalidOperationException">
        /// Thrown if <see cref="Format"/> is non-<c>null</c> but <see cref="For"/> is <c>null</c>.
        /// </exception>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
            // from a TagBuilder.
            if (InputTypeName != null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient.
            // IHtmlGenerator will enforce name requirements.
            var metadata = For.Metadata;
            var modelExplorer = For.ModelExplorer;
            if (metadata == null)
            {
                throw new InvalidOperationException(Resources.FormatTagHelpers_NoProvidedMetadata(
                    "<input>",
                    ForAttributeName,
                    nameof(IModelMetadataProvider),
                    For.Name));
            }

            string inputType;
            string inputTypeHint;
            if (string.IsNullOrEmpty(InputTypeName))
            {
                // Note GetInputType never returns null.
                inputType = GetInputType(modelExplorer, out inputTypeHint);
            }
            else
            {
                inputType = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            // inputType may be more specific than default the generator chooses below.
            if (!output.Attributes.ContainsName("type"))
            {
                output.Attributes.SetAttribute("type", inputType);
            }

            TagBuilder tagBuilder;
            switch (inputType)
            {
                case "checkbox":
                    GenerateCheckBox(modelExplorer, output);
                    return;

                case "hidden":
                    tagBuilder = Generator.GenerateHidden(
                        ViewContext,
                        modelExplorer,
                        For.Name,
                        value: For.Model,
                        useViewData: false,
                        htmlAttributes: null);
                    break;

                case "password":
                    tagBuilder = Generator.GeneratePassword(
                        ViewContext,
                        modelExplorer,
                        For.Name,
                        value: null,
                        htmlAttributes: null);
                    break;

                case "radio":
                    tagBuilder = GenerateRadio(modelExplorer);
                    break;

                default:
                    tagBuilder = GenerateTextBox(modelExplorer, inputTypeHint, inputType);
                    break;
            }

            if (tagBuilder != null)
            {
                // This TagBuilder contains the one <input/> element of interest. Since this is not the "checkbox"
                // special-case, output is a self-closing element no longer guaranteed.
                output.MergeAttributes(tagBuilder);
                output.Content.AppendHtml(tagBuilder.InnerHtml);
            }
        }