C# Extension Methods that come in handy for an ASP.Net Project

vengi83644

Venkatesan Rethinam

Posted on February 4, 2024

C# Extension Methods that come in handy for an ASP.Net Project

In the realm of C# and ASP.NET development, extension methods serve as invaluable tools, empowering developers to enhance the expressiveness and efficiency of their code. In this blog post, we will delve into some of the basic extension methods that any ASP.Net Core project needs and can elevate your web development projects.

HTTPContext Extensions

Get Base Path

public static string GetBasePath(this HttpContext httpContext)
{
    return $"{httpContext.Request.Scheme}://{httpContext.Request.Host}";
}
Enter fullscreen mode Exit fullscreen mode

Check if the Request Header has a particular key

public static bool HasRequestHeader(this HttpContext httpContext, string headerName)
{
    return httpContext.Request.Headers.ContainsKey(headerName);
}
Enter fullscreen mode Exit fullscreen mode

Check if the Response Header has a particular key

public static bool HasResponseHeader(this HttpContext httpContext, string headerName)
{
    return httpContext.Response.Headers.ContainsKey(headerName);
}
Enter fullscreen mode Exit fullscreen mode

Check if the Request Header key has the required value

public static bool HasRequestHeaderValue(this HttpContext httpContext, string headerName, string headerValue)
{
    return httpContext.Request.Headers.TryGetValue(headerName, out var header)
        && header.Any(a => a.Equals(headerValue, StringComparison.OrdinalIgnoreCase));
}
Enter fullscreen mode Exit fullscreen mode

Check if the Response Header key has the required value

public static bool HasResponseHeaderValue(this HttpContext httpContext, string headerName, string headerValue)
{
    return httpContext.Response.Headers.TryGetValue(headerName, out var header)
        && header.Any(a => a.Equals(headerValue, StringComparison.OrdinalIgnoreCase));
}
Enter fullscreen mode Exit fullscreen mode

IEnumerable Extensions

Convert any IEnumerable to CSV String

public static string ConvertToCSVString<T>(this IEnumerable<T> items)
{
    if (items.Any())
    {
        var lines = new List<string>();
        var header = string.Empty;

        if (items.FirstOrDefault().GetType() == typeof(JObject))
        {
            var jObject = (JObject)Convert.ChangeType(items.FirstOrDefault(), typeof(JObject));

            header = string.Join(",", jObject.Properties().Select(x => x.Name));

            lines.Add(header);

            ////DO NOT include the starting and ending quotes inside the $ string interpolation.
            var valueLines = items.Select(row =>
                                    string.Join(",", header.Split(',')
                                        .Select(a => "\"" + $"{((JObject)Convert.ChangeType(row, typeof(JObject))).GetValue(a)}"?
                                                        .Replace(Environment.NewLine, string.Empty, StringComparison.OrdinalIgnoreCase)
                                                        .Replace("\"", "\"\"", StringComparison.OrdinalIgnoreCase)
                                                        + "\""
                                                        )));

            lines.AddRange(valueLines);
        }
        else
        {
            var props = items.FirstOrDefault().GetType().GetProperties();

            header = string.Join(",", props.Select(x => x.Name));

            lines.Add(header);

            //DO NOT include the starting and ending quotes inside the $ string interpolation.
            var valueLines = items.Select(row =>
                                    string.Join(",", header.Split(',')
                                        .Select(a => "\"" + $"{row.GetType().GetProperty(a).GetValue(row, null)}"?
                                                        .Replace(Environment.NewLine, string.Empty, StringComparison.OrdinalIgnoreCase)
                                                        .Replace("\"", "\"\"", StringComparison.OrdinalIgnoreCase)
                                                        + "\""
                                                        )));

            lines.AddRange(valueLines);
        }

        var csvString = string.Join("\r\n", lines.ToArray());

        return csvString;
    }
    else
    {
        return string.Empty;
    }
}
Enter fullscreen mode Exit fullscreen mode

Convert any IEnumerable to DataTable

public static DataTable ToDataTable<T>(this IEnumerable<T> items)
{
    DataTable dataTable = new DataTable(typeof(T).Name);

    PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (PropertyInfo prop in Props)
    {
        dataTable.Columns.Add(prop.Name);
    }
    foreach (T item in items)
    {
        var values = new object[Props.Length];
        for (int i = 0; i < Props.Length; i++)
        {
            values[i] = Props[i].GetValue(item, null);
        }
        dataTable.Rows.Add(values);
    }

    return dataTable;
}
Enter fullscreen mode Exit fullscreen mode

Session Extensions

Replace a value in a Session key

public static void Replace(this ISession session, string key, object data)
{
    if (session.Keys.Any(x => x.Equals(key, StringComparison.OrdinalIgnoreCase)))
    {
        session.Remove(key);
    }

    session.SetString(key, JsonConvert.SerializeObject(data));
}
Enter fullscreen mode Exit fullscreen mode

Get value from a Session key

public static bool TryGet<T>(this ISession session, string key, out T data, bool removeKey = false)
{
    if (session.Keys.Any(x => x.Equals(key, StringComparison.OrdinalIgnoreCase)))
    {
        var objString = session.GetString(key);

        data = JsonConvert.DeserializeObject<T>(objString);

        if (removeKey)
        {
            session.Remove(key);
        }

        return true;
    }

    data = default;
    return false;
}
Enter fullscreen mode Exit fullscreen mode

ClaimsPrincipal Extensions

Check if the claims has a particular Role

public static bool HasRole(this ClaimsPrincipal principal, string role)
{
    return principal.HasClaim(c =>
                                    c.Type == ClaimTypes.Role &&
                                    c.Value.Equals(role, StringComparison.OrdinalIgnoreCase));
}
Enter fullscreen mode Exit fullscreen mode

Get Roles from the claims

public static IEnumerable<string> GetRoles(this ClaimsPrincipal principal)
{
    return principal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(s => s.Value);
}
Enter fullscreen mode Exit fullscreen mode

Get a particular claim from the claims

 public static T GetClaim<T>(this ClaimsPrincipal principal, string claim)
 {
     var result = principal?.Claims?.FirstOrDefault(f => f.Type.Equals(claim, StringComparison.OrdinalIgnoreCase))?.Value;

     return (T)Convert.ChangeType(result, typeof(T));
 }
Enter fullscreen mode Exit fullscreen mode

DateTime Extensions

Convert to a different TimeZone

public static DateTime ConvertToTimeZone(this DateTime dateTime, string timeZoneId)
{
    return TimeZoneInfo.ConvertTimeFromUtc(dateTime, TimeZoneInfo.FindSystemTimeZoneById(timeZoneId));
}
Enter fullscreen mode Exit fullscreen mode

Check if a given DateTime is between a time range

public static bool IsBetweenTimeRange(this DateTime comparisonTime, DateTime? startDate, DateTime? endDate)
{
    return (startDate.HasValue ? comparisonTime >= startDate.Value : true) && (endDate.HasValue ? comparisonTime <= endDate.Value : true);
}
Enter fullscreen mode Exit fullscreen mode

Check if a give DateTimeOffset is between a time range

public static bool IsBetweenTimeRange(this DateTime comparisonTime, DateTimeOffset? startDate, DateTimeOffset? endDate)
{
    return comparisonTime.IsBetweenTimeRange(startDate.HasValue ? startDate.Value.DateTime : null, endDate.HasValue ? endDate.Value.DateTime : null);
}
Enter fullscreen mode Exit fullscreen mode

Convert to a DateTimeOffset based on a TimeZone

public static DateTimeOffset? ToDateTimeOffset(this DateTime? dateTime, string timeZoneId)
{
    return dateTime.HasValue ? new DateTimeOffset(dateTime.Value, TimeZoneInfo.FindSystemTimeZoneById(timeZoneId).BaseUtcOffset) : null;
}
Enter fullscreen mode Exit fullscreen mode

Enum Extensions

Get display name of an Enum

public static string GetDisplayName(this Enum enumValue)
{
    var displayName = enumValue.GetType().GetMember(enumValue.ToString()).FirstOrDefault().GetCustomAttribute<DisplayAttribute>()?.GetName();

    return string.IsNullOrWhiteSpace(displayName) ? enumValue.ToString() : displayName;
}
Enter fullscreen mode Exit fullscreen mode

HTTPResponseMessage Extensions

Ensure the HTTPResponseMessage has a Success Status code and log failures

public static async Task EnsureSuccessStatusCodeAndLogFailures(this HttpResponseMessage httpResponseMessage, ILogger logger)
{
    if (httpResponseMessage == null)
    {
        throw new ArgumentNullException(nameof(httpResponseMessage));
    }
    if (logger == null)
    {
        throw new ArgumentNullException(nameof(logger));
    }

    if (!httpResponseMessage.IsSuccessStatusCode)
    {
        var response = await httpResponseMessage.Content?.ReadAsStringAsync();

        var requestUri = httpResponseMessage.RequestMessage?.RequestUri;

        logger.LogError($"HTTP call to {requestUri} returned status code {httpResponseMessage.StatusCode} with response {response}");
    }

    httpResponseMessage.EnsureSuccessStatusCode();
}
Enter fullscreen mode Exit fullscreen mode

TokenResponse Extensions

Ensure the TokenResponse has a Success Status and log failures

public static void CheckResponseAndLogFailures(this TokenResponse tokenResponse, ILogger logger)
{
    if (tokenResponse == null)
    {
        throw new ArgumentNullException(nameof(tokenResponse));
    }
    if (logger == null)
    {
        throw new ArgumentNullException(nameof(logger));
    }

    if (tokenResponse.IsError)
    {
        var response = JsonConvert.SerializeObject(tokenResponse);

        logger.LogError("Access Token call to returned with error and data: {data}", response);
    }
}
Enter fullscreen mode Exit fullscreen mode

String Extensions

Slugify

public static string Slugify(this string phrase)
{
    if (string.IsNullOrWhiteSpace(phrase))
    {
        return string.Empty;
    }

    var output = phrase.RemoveAccents().ToLower();

    output = Regex.Replace(output, @"[^A-Za-z0-9\s-]", "");

    output = Regex.Replace(output, @"\s+", " ").Trim();

    output = Regex.Replace(output, @"\s", "-");

    return output;
}

public static string RemoveAccents(this string text)
{
    if (string.IsNullOrWhiteSpace(text))
        return text;

    text = text.Normalize(NormalizationForm.FormD);
    char[] chars = text
        .Where(c => CharUnicodeInfo.GetUnicodeCategory(c)
        != UnicodeCategory.NonSpacingMark).ToArray();

    return new string(chars).Normalize(NormalizationForm.FormC);
}
Enter fullscreen mode Exit fullscreen mode

Check if a email is valid

public static bool IsValidEmail(this string email)
{
    var isValid = true;

    try
    {
        var emailAddress = new MailAddress(email.Trim());
    }
    catch
    {
        isValid = false;
    }

    return isValid;
}
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
vengi83644
Venkatesan Rethinam

Posted on February 4, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related