简体   繁体   中英

ASP.NET Custom HttpContext Threading Issue

Often i have to access the same information across multiple requests from within any part of my ASP.NET application. Using the example below I'm try to get the current request's URL (as often I forget which property I need). I'm trying to come up with an approach that is similar to how ASP.NET handles the HttpContext. So far i have come up with the following:

public interface ICustomContext {
    HttpContextBase Http { get; }
    string Url { get; }
}

public class CustomContext : ICustomContext {
    private readonly HttpContextBase _httpContext;

    public CustomContext(HttpContextBase httpContext) {
        _httpContext = httpContext;
    }

    public HttpContextBase Http {
        get { return _httpContext; }
    }

    public string Url {
        get { return Http.Request.Url.AbsoluteUri; }
    }
}

public class MyContext {
    private static ICustomContext _instance = new CustomContext(new HttpContextWrapper(HttpContext.Current));

    public static ICustomContext Current {
        get { return _instance; }
    }
}

This allows me to add additional properties later on top of my own context. I hoped i could simply say:

MyContext.Current.Url;

However it always returns the url of the page when it is first called. I'm guessing this is some sort of threading issue but i'm not sure how to solve it.

I'd appreciate the help. Oh and please note I would ideally like a solution which is clean and easily testable.

Thanks

I think the clue in row with static field

private static ICustomContext _instance

try to change it to

public static ICustomContext Current {
        get { return new CustomContext(HttpContext.Current); }
    }

I have found a nice way to handle this. My initial thought was to store the instance in the HttpContext.Current.Items collection (as this exists per request). Then i realized since i'm using Microsoft Unity as my Ioc and i've defined my own LifetimeManager which stores the object in the HttpContext.Current.Items collection i could register the types by saying:

container.RegisterType<HttpContextBase>(new InjectionFactory(c => {
    return new HttpContextWrapper(HttpContext.Current);
}));
container.RegisterType<ICustomContext, CustomContext>(new PerRequestLifetimeManager<ICustomContext>());

Now i can define my static property like so:

public static ICustomContext Current {
    get { return DependencyResolver.Current.GetService<ICustomContext>(); }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM