tags:

views:

444

answers:

3

In the line "Response.Cookies...", I get an object reference not set to an instance of an object. Is there a way to fix this and use a timer in my ASPX code behind?

protected void Page_Load(object sender, EventArgs e)
{

    object o = new object();

    TimerCallback timercallback = new TimerCallback(StartCallback);

    System.Threading.Timer timer = new Timer(timercallback, o, 0, 50000);



    if (are.WaitOne())
    {
        Response.Redirect("Default.aspx");
    }
}


public void StartCallback(object o)
{
    //Request.Cookies["haspassed?"].Value = "";

    Response.Cookies["haspassed?"].Expires = System.DateTime.Now.AddMonths(-1);

    are.Set();
}

Thanks

+1  A: 

iirc the new thread which StartCallback is going to operate in isn't going to have an HTTPContext, so the nullpointer is that Response does not exist. Why not pass it the context as "o"?

annakata
I wondered about that - but I believe Response is just a reference within the Page. (It's not like HttpContext.Current.)
Jon Skeet
I don't think that's the case. There's a public HttpRequest Request { get; } on the Page class, but I can't imagine how that can point at *this* request context within another thread. Easy to test though, put a breakpoint on it and see what's null :)
annakata
Actually since Page is an IHttpHandler with it's own Context property I think it's probably *exactly* like HttpContext.Current...
annakata
A: 

So I cast o to a HttpContext object? I'll give that a go.

I'm using a C# timer out of preference of server side coding than JS, really.

A). you should post this as a comment not an additional answer if possible, B). yes, but of course remember to pass it in as well, and C). I think the question is why are you doing this in a timer at all, you could be setting it in the page_load. What's the gain?
annakata
A: 

It's an odd problem; Response (according to Reflector) is:

[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public HttpResponse Response
{
    get
    {
        if (this._response == null)
        {
            throw new HttpException(SR.GetString("Response_not_available"));
        }
        return this._response;
    }
}

So it can't return null - you'd get an HttpException instead.

Likewise, Cookies is:

public HttpCookieCollection Cookies
{
    get
    {
        if (this._cookies == null)
        {
            this._cookies = new HttpCookieCollection(this, false);
        }
        return this._cookies;
    }
}

So you wouldn't get null there either.

The Cookies' indexer? Nope:

public HttpCookie Get(string name)
{
    HttpCookie cookie = (HttpCookie) base.BaseGet(name);
    if ((cookie == null) && (this._response != null))
    {
        cookie = new HttpCookie(name);
        this.AddCookie(cookie, true);
        this._response.OnCookieAdd(cookie);
    }
    return cookie;
}

So I thought, the only thing we have left, is inside the Cookies indexer, if this._response == null, the cookie setting will not happen and this will return null. But that can't happen either since _cookies is only ever in that line we saw earlier, which calls a constructor which is the only place where _response is set - set to the correct HttpRespones, never null.

In conclusion, I've dug deep in there and can't see any way for the Response.Cookies["haspassed?"].Expires setter to ever throw a NullReferenceException.

configurator