+
Skip to content

add yet another ASP.NET validation sample #63

@BryanWilhite

Description

@BryanWilhite

this sample should use conventional collection naming conventions with PartialAsync instead of EditorFor

the following IHtmlHelperExtensions class should be memorialized (see GetConventionalCollectionId and GetConventionalCollectionName below):

    /// <summary>
    /// Extensions of <see cref="IHtmlHelper"/>
    /// </summary>
    public static class IHtmlHelperExtensions
    {
 
        /// <summary>
        /// Adds the <c>display:none</c> CSS style
        /// based on the specified condition.
        /// </summary>
        /// <param name="helper">The <see cref="IHtmlHelper"/>.</param>
        /// <param name="condition">The condition under which to show the HTML.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">helper</exception>
        public static HtmlString AddDisplayNone(this IHtmlHelper? helper, bool condition) =>
            helper.AddMarkup(@"style=""display:none""", condition);
 
        /// <summary>
        /// Wraps the specified content with our conventional <c>span</c> visual for icons.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <param name="content">The content.</param>
        /// <param name="containerCssClassNames">The container CSS class names.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static HtmlString AddIconContainer(this IHtmlHelper? helper, HtmlString? content, string? containerCssClassNames = "icon")
        {
            ArgumentNullException.ThrowIfNull(helper);
            if (string.IsNullOrWhiteSpace(containerCssClassNames)) containerCssClassNames = "icon";
 
            var sb = new StringBuilder();
 
            sb.AppendLine($"<span aria-hidden=\"true\" class=\"{containerCssClassNames}\">");
            sb.Append(content?.Value);
            sb.AppendLine("</span>");
 
            return new HtmlString(sb.ToString());
        }
 
        /// <summary>
        /// Adds the markup, arbitrary HTML in the specified <see cref="string"/>.
        /// </summary>
        /// <param name="helper">The <see cref="IHtmlHelper"/>.</param>
        /// <param name="html">The HTML.</param>
        /// <param name="condition">The condition under which to show the HTML.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">helper</exception>
        public static HtmlString AddMarkup(this IHtmlHelper? helper, string? html, bool condition)
        {
            ArgumentNullException.ThrowIfNull(helper);
 
            return condition ? new HtmlString(html) : HtmlString.Empty;
        }
 
        /// <summary>
        /// Wraps the specified content with our conventional <c>svg</c> visual.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <param name="content">The content.</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <remarks>
        /// These are the conventions:
        /// - <c>fill</c> is <c>currentColor</c>
        /// - <c>preserveAspectRatio</c> is <c>xMidYMid meet</c>
        /// - <c>viewBox</c> is <c>0 0 16 16</c> which assumes that most original SVG art is 16 by 16 pixels
        /// </remarks>
        public static HtmlString AddSvgContainer(this IHtmlHelper? helper, HtmlString? content)
        {
            ArgumentNullException.ThrowIfNull(helper);
 
            var sb = new StringBuilder();
 
            sb.AppendLine("<svg fill=\"currentColor\" preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\">");
            sb.Append(content?.Value);
            sb.AppendLine("</svg>");
 
            return new HtmlString(sb.ToString());
        }
 
        /// <summary>
        /// Adds a <c>svg</c> <c>path</c> visual element(s) from the specified markup.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <param name="pathElementMarkup">The <c>path</c> element markup.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static HtmlString AddSvgPaths(this IHtmlHelper? helper, string? pathElementMarkup)
        {
            ArgumentNullException.ThrowIfNull(helper);
 
            if(string.IsNullOrEmpty(pathElementMarkup))
                throw new ArgumentNullException(nameof(pathElementMarkup));
 
            var sb = new StringBuilder();
 
            var markupArray = pathElementMarkup.Split(Environment.NewLine);
 
            foreach(var markup in markupArray) sb.AppendLine(markup);
 
            return new HtmlString(sb.ToString());
        }
 
        /// <summary>
        /// Calls <see cref="AddIconContainer" /> and <see cref="AddSvgContainer" />
        /// with content from <see cref="AddSvgPaths" />.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <param name="pathElementMarkup">The path element markup.</param>
        /// <param name="containerCssClassNames">The container CSS class names.</param>
        /// <returns></returns>
        public static HtmlString AddSvgPathsIconContainer(this IHtmlHelper? helper, string? pathElementMarkup, string? containerCssClassNames = "icon") =>
            helper.AddIconContainer(
                helper.AddSvgContainer(
                    helper.AddSvgPaths(pathElementMarkup)), containerCssClassNames);
 
        /// <summary>
        /// Adds a hidden <c>svg</c> element
        /// with a <c>symbol</c> element
        /// for every specified item in the SVG path data.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <param name="svgPathData">The SVG path data.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static HtmlString AddSvgSymbolsBlock(this IHtmlHelper? helper, params (string id, string d)[] svgPathData)
        {
            ArgumentNullException.ThrowIfNull(helper);
 
            var sb = new StringBuilder();
 
            sb.AppendLine("<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none;\">");
            foreach (var item in svgPathData)
            {
                sb.AppendLine($"    <symbol id=\"{item.id}\">");
                if(item.d.Contains("<path"))
                    sb.AppendLine($"        {item.d.Trim().Replace(Environment.NewLine, $"{Environment.NewLine}        ")}");
                else
                    sb.AppendLine($"        <path d=\"{item.d.Trim()}\"");
                sb.AppendLine("    </symbol>");
            }
            sb.AppendLine("</svg>");
 
            return new HtmlString(sb.ToString());
        }
 
        /// <summary>
        /// Calls <see cref="AddSvgContainer"/> with <c>use xlink</c> content.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <param name="xLinkId">The <c>xlink</c> identifier without the hash (<c>#</c>).</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static HtmlString AddSvgXLinkContainer(this IHtmlHelper? helper, string xLinkId)
        {
            ArgumentNullException.ThrowIfNull(helper);
 
            return helper.AddSvgContainer(new HtmlString($"<use xlink:href=\"#{xLinkId}\" />"));
        }
 
        /// <summary>
        /// Concatenates the specified array of <see cref="HtmlString"/>.
        /// </summary>
        /// <param name="helper">The <see cref="IHtmlHelper"/>.</param>
        /// <param name="htmlStrings">The array of <see cref="HtmlString"/>.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">first</exception>
        public static HtmlString Concatenate(this IHtmlHelper? helper, params HtmlString[] htmlStrings)
        {
            ArgumentNullException.ThrowIfNull(helper);
 
            var sb = new StringBuilder();
 
            foreach (var htmlString in htmlStrings) sb.Append(htmlString);
 
            return new HtmlString(sb.ToString());
        }
 
        /// <summary>
        /// Returns the conventional ASP.NET collection identifer
        /// for the <c>id</c> attribute of an element.
        /// </summary>
        /// <param name="helper">The <see cref="IHtmlHelper"/>.</param>
        /// <param name="collectionName">The name of the collection</param>
        /// <param name="index">The index in the collection</param>
        /// <param name="propertyName">The property name of the object of the collection.</param>
        /// <remarks>
        /// This member returns a string of the form:
        /// <code>$"{collectionName}__{index}_{propertyName}"</code>
        /// </remarks>
        public static string GetConventionalCollectionId(this IHtmlHelper? helper, string collectionName, int index, string propertyName)
        {
            ArgumentNullException.ThrowIfNull(helper);
 
            return $"{collectionName}__{index}_{propertyName}";
        }
 
        /// <summary>
        /// Returns the conventional ASP.NET collection identifer
        /// for the <c>name</c> attribute of an element.
        /// </summary>
        /// <param name="helper">The <see cref="IHtmlHelper"/>.</param>
        /// <param name="collectionName">The name of the collection</param>
        /// <param name="index">The index in the collection</param>
        /// <param name="propertyName">The property name of the object of the collection.</param>
        /// <remarks>
        /// This member returns a string of the form:
        /// <code>$"{collectionName}[{index}].{propertyName}"</code>
        /// </remarks>
        public static string GetConventionalCollectionName(this IHtmlHelper? helper, string collectionName, int index, string propertyName)
        {
            ArgumentNullException.ThrowIfNull(helper);
 
            return $"{collectionName}[{index}].{propertyName}";
        }
    }

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载