每个请求的Asp.Net MVC唯一ID

时间:2014-10-09 21:51:07

标签: asp.net-mvc asp.net-mvc-5

在我们的MVC 5站点中,没有会话,我们需要为每个请求获取/生成唯一ID。这将用作记录请求中所有活动的ID。

有没有办法为请求分配/获取值以启用此功能?

3 个答案:

答案 0 :(得分:9)

将其添加到请求项集合odetocode.com/articles/111.aspx

Guid.NewGuid()

将生成唯一ID。

http://msdn.microsoft.com/en-us/library/system.guid.newguid(v=vs.110).aspx

答案 1 :(得分:6)

这是我为此目的创建的一些扩展方法:

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];
    }
}

更新

@Luiso发表评论说实习字符串不是垃圾收集。这是个好的观点。在一个非常繁忙的网络应用程序中,它不会经常(或永远)回收应用程序池,这将是一个严重的问题。

值得庆幸的是,最新版本的.NET通过ConditionalWeakTable<TK,TV>类提供了ephemeron支持。这提供了一种方便且内存安全的方法来解决这个问题:

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;
}

我的Overby.Extensions.Attachments包有一个简化方法的扩展方法。

/// <summary>
/// Unique identifier for the object reference.
/// </summary>
public static Guid GetReferenceId(this object obj) =>
    obj.GetOrSetAttached(() => Guid.NewGuid(), RefIdKey);

使用该扩展方法,您只需拨打httpContext.GetReferenceId()

答案 2 :(得分:1)

如果您只需要一个值而无需实现类似Guid.NewGuid()的内容,那么HttpContext时间戳可能对您有用。

int requestId = System.Web.HttpContext.Current.Timestamp.Ticks;

一个滴答声代表一百纳秒或十分之一秒。一毫秒内有10,000个滴答声,一秒内有1,000万个滴答声。

然后应根据他们的情况评估此解决方案,因为两个请求可能会在同一时间间隔出现。