Dưới đây là một số phương pháp mở rộng mà tôi tạo ra cho mục đích này:
public static Guid GetId(this HttpContext ctx) => new HttpContextWrapper(ctx).GetId();
public static Guid GetId(this HttpContextBase ctx)
{
const string key = "tq8OuyxHpDgkRg54klfpqg== (Request Id Key)";
if (ctx.Items.Contains(key))
return (Guid) ctx.Items[key];
var mutex = string.Intern($"{key}:{ctx.GetHashCode()}");
lock (mutex)
{
if (!ctx.Items.Contains(key))
ctx.Items[key] = Guid.NewGuid();
return (Guid) ctx.Items[key];
}
}
Cập nhật
@Luiso đã viết nhận xét về chuỗi thực tập nội trú không được thu gom rác thải. đây là một quan điểm tốt. Trong một ứng dụng web rất bận rộn mà không tái chế các nhóm ứng dụng thường xuyên (hoặc bao giờ), đây sẽ là một vấn đề nghiêm trọng.
Rất may, các phiên bản gần đây của .NET có hỗ trợ ephemeron qua lớp ConditionalWeakTable<TK,TV>
. Điều này mang lại một cách an toàn và tiện lợi cho việc giải quyết vấn đề này:
private static readonly ConditionalWeakTable<object, ConcurrentDictionary<string, object>>
Ephemerons = new ConditionalWeakTable<object, ConcurrentDictionary<string, object>>();
public static Guid GetId(this HttpContext ctx) => new HttpContextWrapper(ctx).GetId();
public static Guid GetId(this HttpContextBase ctx)
{
var dict = Ephemerons.GetOrCreateValue(ctx);
var id = (Guid)dict.GetOrAdd(
"c53fd485-b6b6-4da9-9e9d-bf30500d510b",
_ => Guid.NewGuid());
return id;
}
Gói Overby.Extensions.Attachments của tôi có phương pháp mở rộng đơn giản hóa mọi thứ.
/// <summary>
/// Unique identifier for the object reference.
/// </summary>
public static Guid GetReferenceId(this object obj) =>
obj.GetOrSetAttached(() => Guid.NewGuid(), RefIdKey);
Sử dụng phương pháp mở rộng đó, bạn chỉ cần gọi httpContext.GetReferenceId()
.
Nguồn
2015-11-22 15:23:57
Bản sao có thể có của [id yêu cầu duy nhất log4net trong ASP.NET] (http://stackoverflow.com/questions/15842321/log4net-unique-request-id-in-asp-net) –