在 C# 和 ASP.NET 开发领域,扩展方法作为宝贵的工具,使开发人员能够增强其代码的表现力和效率。在这篇博文中,我们将深入探讨任何 ASP.Net Core 项目都需要的一些基本扩展方法,这些方法可以提升您的 Web 开发项目。
public static string GetBasePath(this HttpContext httpContext)
{
return $”{httpContext.Request.Scheme}://{httpContext.Request.Host}”;
}
public static bool HasRequestHeader(this HttpContext httpContext, string headerName)
{
return httpContext.Request.Headers.ContainsKey(headerName);
}
public static bool HasResponseHeader(this HttpContext httpContext, string headerName)
{
return httpContext.Response.Headers.ContainsKey(headerName);
}
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));
}
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));
}
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;
}
}
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;
}
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));
}
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;
}
public static bool HasRole(this ClaimsPrincipal principal, string role)
{
return principal.HasClaim(c =>
c.Type == ClaimTypes.Role &&
c.Value.Equals(role, StringComparison.OrdinalIgnoreCase));
}
public static IEnumerable<string> GetRoles(this ClaimsPrincipal principal)
{
return principal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(s => s.Value);
}
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));
}
public static DateTime ConvertToTimeZone(this DateTime dateTime, string timeZoneId)
{
return TimeZoneInfo.ConvertTimeFromUtc(dateTime, TimeZoneInfo.FindSystemTimeZoneById(timeZoneId));
}
public static bool IsBetweenTimeRange(this DateTime comparisonTime, DateTime? startDate, DateTime? endDate)
{
return (startDate.HasValue ? comparisonTime >= startDate.Value : true) && (endDate.HasValue ? comparisonTime \<= endDate.Value : true);
}
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);
}
public static DateTimeOffset? ToDateTimeOffset(this DateTime? dateTime, string timeZoneId)
{
return dateTime.HasValue ? new DateTimeOffset(dateTime.Value, TimeZoneInfo.FindSystemTimeZoneById(timeZoneId).BaseUtcOffset) : null;
}
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;
}
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();
}
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);
}
}
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);
}
public static bool IsValidEmail(this string email)
{
var isValid = true;
try
{
var emailAddress = new MailAddress(email.Trim());
}
catch
{
isValid = false;
}
return isValid;
}