2014-10-09 12 views
7

Trong trang MVC 5 của chúng tôi, không có phiên nào, chúng tôi cần nhận/tạo một ID duy nhất cho mỗi yêu cầu. THhis sẽ được sử dụng làm ID để ghi lại tất cả hoạt động trong yêu cầu.Asp.Net MVC Số duy nhất cho mỗi yêu cầu

Có cách nào để gán/nhận giá trị cho Yêu cầu bật tính năng này không?

+0

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) –

Trả lời

8

Thêm nó vào bộ sưu tập yêu cầu mục odetocode.com/articles/111.aspx

Guid.NewGuid() 

sẽ tạo ra một id duy nhất.

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

+1

Nhưng làm cách nào để đính kèm vào Yêu cầu để có thể truy cập được trong toàn bộ vòng đời của yêu cầu. –

+3

Thêm nó vào bộ sưu tập mục yêu cầu http://odetocode.com/articles/111.aspx – TGH

6

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().

+0

tại sao bạn sử dụng 'string.Intern' cho mutex ở đây? – robbymurphy

+0

Bởi vì nó tạo ra một tham chiếu đối tượng mà tôi không phải theo dõi. Tôi nói nhiều hơn về vấn đề này tại đây: http://stackoverflow.com/a/29878495/64334 –

+0

Tại sao lại là downvote? –

Các vấn đề liên quan