csharp/cnAbp/abp-cli/modules/blogging/src/Volo.Blogging.Web/Areas/Blog/Helpers/TagHelpers/GravatarTagHelper.cs

GravatarTagHelper.cs
using System;
using System.ComponentModel;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace Volo.Blogging.Areas.Blog.Helpers.TagHelpers
{
    /// 
    /// 
    ///  Returns a Globally Recognised Avatar https://en.gravatar.com
    /// 
    [HtmlTargetElement("img", Attributes = "gravatar-email")]
    public clast GravatarTagHelper : TagHelper
    {
        private readonly IHttpContextAccessor _contextAccessor;

        public GravatarTagHelper(IHttpContextAccessor contextAccessor)
        {
            _contextAccessor = contextAccessor;
        }

        /// 
        /// Email Address for the Gravatar
        /// 
        [HtmlAttributeName("gravatar-email")]
        public string Email { get; set; }

        /// 
        /// Gravatar content rating (note that Gravatars are self-rated)
        /// 
        [HtmlAttributeName("gravatar-rating")]
        public GravatarRating Rating { get; set; } = GravatarRating.GeneralAudiences;

        /// 
        /// Size in pixels (default: 80)
        /// 
        [HtmlAttributeName("gravatar-size")]
        public int Size { get; set; } = 80;

        /// 
        /// URL to a custom default image (e.g: 'Url.Content("~/images/no-grvatar.png")' )
        /// 
        [HtmlAttributeName("default-image-url")]
        public string DefaultImageUrl { get; set; } = "";

        /// 
        /// Prefer the default image over the users own Gravatar
        /// 
        [HtmlAttributeName("force-default-image")]
        public bool ForceDefaultImage { get; set; }

        /// 
        /// Default image if user hasn't created a Gravatar
        /// 
        [HtmlAttributeName("default-image")]
        public GravatarDefaultImage DefaultImage { get; set; } = GravatarDefaultImage.Default;

        /// 
        /// Always do secure (https) requests
        /// 
        [HtmlAttributeName("force-secure-request")]
        public bool ForceSecureRequest { get; set; } = true;


        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            var emailAddress = Email == null ? string.Empty : Email.Trim().ToLower();

            var url = string.Format("{0}://{1}.gravatar.com/avatar/{2}?s={3}{4}{5}{6}",
                GetUrlScheme(),
                GetUrlPrefix(),
                GetMd5Hash(emailAddress),
                Size,
                GetDefaultImageParameter(),
                GetForceDefaultImageParameter(),
                GetRatingParameter()
            );

            output.Attributes.SetAttribute("src", url);
        }

        private string GetUrlScheme()
        {
            return ForceSecureRequest || _contextAccessor.HttpContext.Request.IsHttps
                ? "https" : "http";
        }

        private string GetUrlPrefix()
        {
            return ForceSecureRequest || _contextAccessor.HttpContext.Request.IsHttps ? "secure" : "www";
        }

        private string GetDefaultImageParameter()
        {
            return "&d=" + (!string.IsNullOrEmpty(DefaultImageUrl)
                       ? System.Net.WebUtility.UrlEncode(DefaultImageUrl)
                       : GetEnumDescription(DefaultImage));
        }

        private string GetForceDefaultImageParameter()
        {
            return ForceDefaultImage ? "&f=y" : "";
        }

        private string GetRatingParameter()
        {
            return "&r=" + GetEnumDescription(Rating);
        }

        /// 
        /// Generates an MD5 hash of the given string
        /// 
        /// Source: http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx 
        private static string GetMd5Hash(string input)
        {
            // Convert the input string to a byte array and compute the hash.
            var data = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            var sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data
            // and format each one as a hexadecimal string.
            foreach (var t in data)
            {
                sBuilder.Append(t.ToString("x2"));
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();
        }

        /// 
        /// Returns the value of a Description for a given Enum value
        /// 
        /// Source: http://blogs.msdn.com/b/abhinaba/archive/2005/10/21/483337.aspx 
        /// 
        /// 
        private static string GetEnumDescription(Enum en)
        {
            var type = en.GetType();
            var memInfo = type.GetMember(en.ToString());

            if (memInfo == null || memInfo.Length