Ecco alcuni metodi di estensione che ho creato per questo scopo:
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];
}
}
Aggiornamento
@Luiso fatto un commento su stringhe internati non essere garbage collection. Questo è un buon punto. In un'app web molto impegnativa che non ricicla abbastanza frequentemente (o mai) i pool di app questo sarebbe un problema serio.
Fortunatamente, le versioni recenti di .NET dispongono del supporto effimero tramite la classe ConditionalWeakTable<TK,TV>
. Che dà un modo sicuro e conveniente la memoria di affrontare questo problema:
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;
}
Il mio pacchetto Overby.Extensions.Attachments ha un metodo di estensione che semplificare le cose.
/// <summary>
/// Unique identifier for the object reference.
/// </summary>
public static Guid GetReferenceId(this object obj) =>
obj.GetOrSetAttached(() => Guid.NewGuid(), RefIdKey);
Utilizzando questo metodo di estensione, si sarebbe solo chiamare httpContext.GetReferenceId()
.
fonte
2015-11-22 15:23:57
Possibile duplicato di [ID richiesta univoco di log4net in ASP.NET] (http://stackoverflow.com/questions/15842321/log4net-unique-request-id-in-asp-net) –