using AngleSharp;
using AngleSharp.Dom;
using Ganss.Xss;
using Markdig;
using IConfiguration = Microsoft.Extensions.Configuration.IConfiguration;
namespace Dpz.Core.Web.Library;
/// <summary>
/// Mumble 视图帮助类,提供图片处理和 Markdown 转换等功能
/// </summary>
public class MumbleViewHelper(IConfiguration configuration)
{
private readonly string _cdnHost = configuration["upyun:Host"] ?? string.Empty;
private readonly IBrowsingContext _context = BrowsingContext.New(Configuration.Default);
private readonly HtmlSanitizer _sanitizer = CreateSanitizer(configuration);
/// <summary>
/// 判断图片是否为自有 CDN 图片
/// </summary>
/// <param name="imageUrl">图片 URL</param>
/// <returns>是否为自有 CDN 图片</returns>
private bool IsOwnCdnImage(string? imageUrl)
{
if (string.IsNullOrWhiteSpace(_cdnHost) || string.IsNullOrWhiteSpace(imageUrl))
{
return false;
}
try
{
var imageUri = new Uri(imageUrl, UriKind.Absolute);
var cdnUri = new Uri(_cdnHost, UriKind.Absolute);
return string.Equals(imageUri.Host, cdnUri.Host, StringComparison.OrdinalIgnoreCase);
}
catch
{
return false;
}
}
/// <summary>
/// 获取缩略图 URL
/// </summary>
/// <param name="imageUrl">原图 URL</param>
/// <returns>缩略图 URL</returns>
public string GetThumbnailUrl(string imageUrl)
{
return IsOwnCdnImage(imageUrl) ? imageUrl + "!thumb" : imageUrl;
}
/// <summary>
/// 处理 Markdown 并提取图片
/// </summary>
/// <param name="html">HTML 内容</param>
/// <param name="sanitize">是否进行 XSS 清理,默认为 true</param>
/// <returns>处理后的内容和图片列表</returns>
public async Task<(string content, List<string> images)> ProcessHtmlAndExtractImages(
string html,
bool sanitize = true
)
{
var document = await _context.OpenAsync(y => y.Content(html));
var imageUrls = new List<string>();
ProcessLinks(document);
ExtractImages(document, imageUrls);
var content = sanitize
? _sanitizer.Sanitize(document.Body?.InnerHtml ?? string.Empty)
: document.Body?.InnerHtml ?? string.Empty;
return (content, imageUrls);
}
/// <summary>
/// 从 Markdown 提取图片(用于历史记录)
/// </summary>
/// <param name="markdown">Markdown 内容</param>
/// <returns>处理后的 HTML 内容和图片列表</returns>
public async Task<(string content, List<string> images)> ExtractImagesFromMarkdown(
string markdown
)
{
var pipeline = new MarkdownPipelineBuilder().DisableHtml().Build();
var html = Markdown.ToHtml(markdown, pipeline);
var document = await _context.OpenAsync(x => x.Content(html));
var imageUrls = new List<string>();
ExtractImages(document, imageUrls);
return (document.Body?.InnerHtml ?? string.Empty, imageUrls);
}
/// <summary>
/// 处理链接,添加 target 和 rel 属性
/// </summary>
private static void ProcessLinks(IDocument document)
{
var links = document.GetElementsByTagName("a");
foreach (var link in links)
{
var href = link.GetAttribute("href");
if (
href != null
&& !href.StartsWith("javascript", StringComparison.CurrentCultureIgnoreCase)
)
{
link.SetAttribute("target", "_blank");
link.SetAttribute("rel", "noopener noreferrer");
}
}
}
/// <summary>
/// 提取并移除图片元素
/// </summary>
private static void ExtractImages(IDocument document, List<string> imageUrls)
{
var images = document.GetElementsByTagName("img");
var imagesToRemove = new List<IElement>();
foreach (var img in images)
{
var src = img.GetAttribute("src");
if (
!string.IsNullOrWhiteSpace(src)
&& !src.Contains("notfound.png", StringComparison.OrdinalIgnoreCase)
)
{
imageUrls.Add(src);
imagesToRemove.Add(img);
}
}
foreach (var img in imagesToRemove)
{
img.Remove();
}
}
/// <summary>
/// 创建 HtmlSanitizer 实例
/// </summary>
private static HtmlSanitizer CreateSanitizer(IConfiguration configuration)
{
var rule = configuration.GetSection("XSS").Get<CrossSiteRule>();
return rule?.CustomHtmlSanitizer() as HtmlSanitizer ?? new HtmlSanitizer();
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
这是一个名为 MumbleViewHelper 的 C# 工具类,主要用于处理网页内容中的 HTML、Markdown 和图片。让我详细解释一下这个类的功能和实现:
类的整体结构
这是一个使用主构造函数的类(C# 12+ 特性),接收一个 IConfiguration 参数用于获取配置信息。
主要字段
_cdnHost: 从配置中获取的 CDN 主机地址_context: AngleSharp 的浏览上下文,用于解析 HTML_sanitizer: HTML 清理器,用于防止 XSS 攻击
核心功能
1. CDN 图片识别 (IsOwnCdnImage)
private bool IsOwnCdnImage(string? imageUrl)
- 判断给定的图片 URL 是否属于自己的 CDN
- 通过比较图片 URL 的主机名与配置的 CDN 主机名来判断
2. 缩略图处理 (GetThumbnailUrl)
public string GetThumbnailUrl(string imageUrl)
- 如果是自有 CDN 图片,在 URL 后添加 "!thumb" 参数获取缩略图
- 否则返回原图 URL
3. HTML 处理和图片提取 (ProcessHtmlAndExtractImages)
public async Task<(string content, List<string> images)> ProcessHtmlAndExtractImages(string html, bool sanitize = true)
这是核心方法,功能包括:
- 解析 HTML 内容
- 处理链接(添加安全属性)
- 提取图片 URL 并从内容中移除图片元素
- 可选择性地进行 XSS 清理
- 返回处理后的内容和图片列表
4. Markdown 图片提取 (ExtractImagesFromMarkdown)
public async Task<(string content, List<string> images)> ExtractImagesFromMarkdown(string markdown)
- 将 Markdown 转换为 HTML
- 提取其中的图片信息
- 主要用于处理历史记录
辅助方法
ProcessLinks
- 为所有链接添加
target="_blank"和rel="noopener noreferrer"属性 - 提高安全性,防止新窗口访问原页面的 window 对象
ExtractImages
- 遍历文档中的所有图片元素
- 提取图片的 src 属性到列表中
- 过滤掉 "notfound.png" 图片
- 从文档中移除图片元素
CreateSanitizer
- 根据配置创建 HTML 清理器
- 用于防止 XSS 攻击
使用的第三方库
- AngleSharp: HTML/XML 解析库
- Ganss.Xss: XSS 防护库
- Markdig: Markdown 解析库
典型使用场景
这个类适用于类似微博、博客或社交媒体平台,需要:
- 处理用户输入的 HTML 或 Markdown 内容
- 提取内容中的图片进行单独展示
- 确保内容安全性(防 XSS)
- 优化图片显示(缩略图)
整体来说,这是一个功能完善的内容处理工具类,特别适合处理富文本内容和图片管理的场景。
评论加载中...