ServerControl randomly null - asp.net

I got a master page with a server control in it. Randomly the server control is inaccessible from codebehind. This doesn't happen on a specific action (eg a Button click or so). Currently I have no clue what this could be. I don't think it's output caching since this is not explcitly activated and the error happens far to seldom for that. But I'm going to disable caching in the master page explicitly with next deployment.
Anyone an idea how to find more info to find what's happening? Or has someone had a similar error?
The control is defined in markup. The accompaning codebehind is:
PGFMainNavi.HasAccessToFunction = HasAccessToNaviItem;
// HasAccessToNavi is a local function
Exception is:
System.NullReferenceException: Object reference not set to an instance
of an object
Thanks.
sa

I have similar errors when I cache my controls - and I always check if their null, or if they are the correct types.
I think that your control is cached somewhere.
Use this code, to check that is not cached.
if(PGFMainNavi != null)
{
PGFMainNavi.HasAccessToFunction = HasAccessToNaviItem;
}
or find where you set the case on this control and remove it.
Second Solution
Some times after an online update I get this error, because compiler did fail to read correct all involving files - probably some user read the page the same time I copy the files or something.
To avoid that I always use the app_offline.htm before make my updates.

Related

ASP.NET Hidden Field Persistence During Life Cycle

I feel like I may be overlooking a fundamental concept of the page life-cycle here and have been (either because I can't figure out the right keywords or it hasn't been asked) unable to locate an existing answer so forgive me if this has been asked.
Basically, I need to persist a mutable object between the client side and the server side. Since the viewstate is encrypted/serialized and the session state is server-side only, my solution was to use a hidden field--easy enough, right? Well here's my problem... it seems as though it's working but the data isn't being propagated as I would've expected.
My expectation was this:
Page is loaded for the first time. Server-side class recognizes that the hidden field is empty, initializes the container class, serializes the class to a JSON string and writes that value to the hidden field.
Page_Init: Unavailable.
Page_Load: Unavailable.
Page_LoadComplete: Available.
Server processing completes, object is now available for use by client code.
Object in hidden field is mutated by client code. Client code then fires a postback to the server (via a button).
Server-side processing begins...
Page_Init: Unavailable.
Page_Load: Available, including client-side changes.
Page_LoadComplete: Available, including client-side changes.
All is right in the world, a double-rainbow shines outside my window and a magical unicorn gives me a wink and a nod.
My observation is this:
Page is loaded for the first time. Server-side class recognizes that the hidden field is empty, initializes the container class, serializes the class to a JSON string and writes that value to the hidden field.
Page_Init: Unavailable. (As expected)
Page_Load: Unavailable. (As expected)
Page_LoadComplete: Available. (As expected)
Server processing completes, object is now available for use by client code.
Object in hidden field is mutated by client code. Client code then fires a postback to the server (via a button).
Server-side processing begins...
Page_Init: Unavailable. (As expected)
Page_Load: Available, but not updated with changes made on the client-side. (Unexpected).
Page_LoadComplete: Available, including client-side changes. (As expected)
A dark cloud forms over my cubicle and I begin to contemplate whether or not my laptop would survive the second-story fall off the balcony.
Conclusion
This is causing me a bit of confusing for a couple reasons... the first is that I've never used the "LoadComplete" event before and can't seem to find any examples that suggest it's necessary to or even that it should be done that way. The second is that by the time load complete is raised, other events that rely on the data from the client side have already been fired.
Any help/explanation/suggestion; hell, even criticism is appreciated!
Thanks, Jason
I'm answering this in the hope that this helps save someone else a few hours. After much trial and finally success, I learned that you can get a HiddenField value during the OnInit event. Given a HiddenField with an ID of hidValue, the key line is:
string strValue = Request.Form[hidValue.UniqueID].ToString();
I've ripped a lot of hair on ASP.NET lifecycle :-). I would advise you this:
bind to control events
avoid binding or overriding to page
events
In this case, you should have a protected HiddenField declared in your page/user control. So you really want to bind to the ValueChanged event, and forget about the rest.
Explaination
You can update HiddenField values in javascript and get them back at the server.
If you want your object to be available after Load, using LoadComplete is ok.
If you want this object to be available to all controls when they load, the earliest you can get the data from inputs is by overloading PreLoad and creating your object there.
There is no problem with your logic.
Conclusion
There is some bug in your implementation of it.
Lets take a look at the code now.

Removing / Ignoring Session items that will cause .NET deserialization errors

I'm trying to be clever by allowing a small validation method to be defined "inline" in ASCX templates as an Action<,>, like so:
<%= OnValidation(delegate(FormSubmission form, FormResult errors) {
// form checks in here, append errors to errors variable if required
}) %>
It actually works a treat, but in order to ensure it can be called during postbacks I need to store the method in the session against that form ID. This also works, up until the point where the app needs to rebuild or references change, then the whole thing crashes out because it can't find "App_Webxxxx" in order to deserialize the methods that are left in the user's session (I guess this wouldn't happen if I was using InProc sessions as clearing my cookies gets rid of the error, but it has to work in SQLServer mode too).
To this end, is there a way to remove those types of items before they cause problems or simply ignore them (the lazy option, I know)? I can't just remove them after they've been run as the user may not submit the form. The best I can think is to do some checking on Application_Start, but I'm not sure if that will even execute, and what to check for.
Any clues very much appreciated!

Cache user control

The problem of ouputcaching is avoiding accessing the object, it is cached and it will not be processed at ALL and it is a HTML. for example, what if I want to post back to initialize countries drop down list with specific selection, I don't want to go back and rebuild the whole control and rebind to a collection of countries to just intialize the contol to a certain country.
Output caching will not solve the problem because it caches the HTML, not the object, the object will be null, I can't manipulate it.
Is there away to cache the server object rather than caching its output html?
If u don't think this is possible please reply back, so I know that it is impossible if alot of people say so.
Thanks
It's quite possible - just use the HttpRuntime cache:
HttpRuntime.Cache.Add("myKey", myCountryList);
And then fetch the object back out:
CountryList myCountryList = HttpRuntime.Cache["myKey"] as CountryList;
if(myCountryList == null)
{
//the object isn't in cache
}
This is the most simple usage - the cache is fairly robust and supports some more complex behaviors like invalidation, callbacks, etc. which is all covered in the link above.

ASP.NET control events exception handling

Suppose I have a button in an aspx page that performs a save of the form data to the database. In the associated event handler, before sending the updates, I read something from a webservice, operation that might result in an exception. In case of an error I want to have an adequate message displayed on the page, and all the data in the form preserved. How can I achieve this? Also, all my pages inherit from a basepage, so I would like, if possible to have all the error handling code in the base class. I do not want, if possible, to surround any web service call with try-catch blocks, I would in case of any unhandled exception to call some method automatically, something like Page_error, but still preserve the data in my forms.
You can easily put a method that manages the display message (maybe setting the text of some errorMessageLabel) in a superclass called from any derived class (if you wanna use inheritance to setup a template for your pages) if an exception is thrown (you can put the call to the superclas method in a catch block if there's actually an exception being thrown or you can manage this manually if the webservice is unavailable depending on your programming style).
As far as preserving the data presented, if viewstate is on and you are not populating your page dynamically then you're ok - if not, you need to explicitly save state information in viewState or session entries and retrieve them back if something goes wrong.
This bit really depends on how your page is actually implemented.

Hiding the stacktrace for an exception returned by a asp.net WebMethod?

I am using methods with the Attribute [WebMethod] in my aspx pages. I don't use any asp.net ajax but jQuery to call these methods and return objects in JSON. This all works fine.
Next I added an authorization check inside the webMethod, if the current user doesn't have access to the feature I need to let the calling JavaScript know.
So I am throwing an AccessViolationException exception which can then be parsed by the OnError callback function in JavaScript. This works too but the exception includes the full StackTrace and I don't want to make this available to the calling client.
What other ways I could use to return an "Access Denied" to the client when the WebMethod returns a business object?
I'm using ASP.Net 3.5SP1 and jQuery 1.32
You can also add a:
customErrors mode="On"/
in your web.config, this will cut away the stack trace and leave you only the exception message
Why propagate errors through the wire? why not use an error response ?
Just wrap your object in a response object wich can contain an error code for status and an error message to present to users.
As suggested by NunFur I changed my approach and rather than throwing an error, I return a 'richer' object.
There are at least two options, the first one would be to encapsulate my business object into a response object with some status properties. I tried this but it makes the JSON more complicated.
So rather than adding a new object I added two properties to my business object, something like ServiceStatus and ServiceMessage. By default these are 200 and '', but can be set by the WebMethod code if anything goes wrong (no access, proper error). In this case they business object will be 'empty' (no data). The JavaScript code then first checks for the ServiceStatus and reacts appropriately.
I add the two fields to all my objects that are returned by WebMethods, even a simple string. They have to implement an Interface with those two properties.
Now I have complete control over that goes over the wire in case something unexpected is happening.
Thanks for the input
I save exceptions for when things go really wrong. (e.g. can't connect to the database)
Either return nothing (null/nill/whatever), or return a false bool value.
Sorry that I don't have a better answer than that...I'll have to keep looking myself.
You could look at SoapException: http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapexception(VS.71).aspx
I'm just not sure, if it will work when it is called from JavaScript. Espeially if it's called with a get-request.
BTW AccessViolationException is to my best knowlegde ment to be thrown when the application is accessing memory it has no access to.
/Asger

Resources