Asp.Net MVC Unique id per request

前端 未结 3 928
醉梦人生
醉梦人生 2021-02-20 00:04

In our MVC 5 site, no session, we need to get/generate a unique ID per request. THhis will be used as an ID for logging all activity in the request.

Is there a way to as

相关标签:
3条回答
  • 2021-02-20 00:48

    If you need a single value without having to implement something like Guid.NewGuid(), perhaps the HttpContext timestamp will work for you.

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

    A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond, or 10 million ticks in a second.

    Then this solution should be evaluated according to their circumstances because there is the possibility that two requests fall on the same tick of time.

    0 讨论(0)
  • Here's some extension methods that I created for this purpose:

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

    Update

    @Luiso made a comment about interned strings not being garbage collected. This is a good point. In a very busy web app that doesn't recycle app pools frequently enough (or ever) this would be a serious issue.

    Thankfully, recent versions of .NET have ephemeron support via the ConditionalWeakTable<TK,TV> class. Which gives a convenient and memory safe way of tackling this problem:

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

    My Overby.Extensions.Attachments package has an extension method that simplify things.

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

    Using that extension method, you would just call httpContext.GetReferenceId().

    0 讨论(0)
  • 2021-02-20 01:07

    Add it to the request item collection odetocode.com/articles/111.aspx

    Guid.NewGuid()
    

    Will generate a unique id.

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

    0 讨论(0)
提交回复
热议问题