ASP.NET - Common Gotchas [closed] - c#

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
When I am working with ASP.NET, I find that there are always unexpected things I run into that take forever to debug. I figure that having a consolidated list of these would be great for those "weird error" circumstances, plus to expand our knowledge of oddness in the platform.
So: answer with one of your "Gotcha"s!
I'll start:
Under ASP.NET (VB), performing a Response.Redirect inside a try/catch block does not stop execution of the current Response, which can lead to two concurrent Responses executing against the same Session.

Don't dynamically add controls after the page init event as it will screw up the viewstate tree.

Viewstate ... if you are using it ... can get out of control if you are not paying attention to it.

The whole life-cycle thing in general.
Not that I see anything wrong with it, it's just that you'd be amazed at the number of people who start working on large ASP.Net projects before understanding it, rather than vice versa. Hence, it becomes a gotcha.
Note that I said large projects: I think the best way to come to terms with the life cycle is to work on a few smaller projects yourself first, where it doesn't matter so much if you screw them up.

Life cycle of custom controls does not match up perfectly with page life cycle events of same name.

Page_Load is run before control handlers. So you can't make changes in an event handler and then use those changes in the page load. This becomes an issue when you have controls in a master page (such as a login control). You can get around the issue by redirecting, but it's definitely a gotcha.

Having to jump through hoops to get the .ClientID property into javascript.
It'd be nice if the render phase of the lifecycle created a script that set up a var for each server control with the same name as the control that was automatically initialized to the clientID value. Or maybe have some way to easily trigger this action.
Hmm... I bet I could set up a method for this on my own via reflection.

Don't edit your web.config with notepad if you have accented characters, it will replace it with one with the wrong encoding. It will look the same though. Just your application will not run.

I just learned this today: the Bind() method, as used with GridViews and ListViews, doesn't exist. It's actually hiding some Reflector magic that turns it into an Eval() and some kind of variable assignment.
The upshot of this is that calls like:
<%# FormatNameHelper(Bind("Name")) %>
that look perfectly valid will fail. See this blog post for more details.

Debugging is a very cool feature of ASP.Net, but as soon as you change some code in the app_code folder, you trigger a re-build of the application, leading to all sessions being lost.
This can get very annoying while debugging a website, but you can easily prevent this using the "StateServer mode" : it's just a service to start and a line to change in the web.config :
refer to msdn : http://msdn.microsoft.com/en-us/library/ms178586.aspx
InProc mode, which stores session state in memory on the Web server. This is the default.
StateServer mode, which stores session state in a separate process called the ASP.NET state service. This ensures that session state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm.
SQL Server ...
Custom ...
Off!

If you are running Classic ASP applications in the same Virtual Directory as you ASP.Net application, the fist hit on the application must be on an ASP.Net page. This will ensure that the AppPool be built with the right context configurations. If the first page to be hit is a Classic ASP page, the results may vary from application to application. In general the AppPool is configured to use the latest framework.

Making a repeater-like control, and not knowing about INamingContainer.

You have to worry about session timeouts for applications where the user might take a long time.
You also have to worry about uploading timeouts for large applications, too
Validatiors may not always scroll your page to the scene of the data entry error (so the user may not ever see it and will only wonder why the submit button won't work )
If the user enters HTML symbols such as <, > (for example, P > 3.14 ), or an inadvertant <br> from copy-pasting on another page, ASP.NET will reject the page and display a error.
null.ToString() produces a big fat error. Check carefully.
Session pool sharing across multiple applications is a disaster silently waiting to happen
Moving applications around on machines with different environments is a migraine that involves web.config and many potential hours of google
ASP.NET and MySQL are prone to caching problems if you use stored procedures
AJAX can make a mess, too:
There are situations where the client can bypass page validation (especially by pressing ENTER instead of pressing the submit button). You can fix it by calling if(! Page.IsValid) { return ; }
ASP buttons usually don't work correctly inside of UpdatePanels
The more content in your UpdatePanel, the more data is asynchronously transmitted, so the longer it takes to load
If your AJAX panel has a problem or error of some kind, it "locks up" and doesn't respond to events inside it anymore

Custom controls are only supported by the designer when building the control or when building the page that uses the control, but not both.

When using a gridview without a datasource control (i.e. binding a dataset straight to the control) you need to manually implement sorting and paging events as shown here:
http://ryanolshan.com/technology/gridview-without-datasourcecontrol-datasource/

Linq: If you are using Linq-To-SQL, you call SubmitChanges() on the data context and it throws an exception (e.g. duplicate key or other constraint violation), the offending object values remain in your memory while you are debugging, and will be resubmitted every time you subsequently call SubmitChanges().
Now here's the real kicker: the bad values will remain in memory even if you push the "stop" button in your IDE and restart! I don't understand why anyone thought this was a good idea - but that little ASP.NET icon that pops up in your system tray stays running, and it appears to save your object cache. If you want to flush your memory space, you have to right-click that icon and forcibly shut it down! GOTCHA!

You can't reference anything at all above the application's root folder.

All the code I have to maintain that still looks like it was written in vb6, showing complete ignorance of the newer styles.
I'm talking things like CreateObject(), excessive <% %> blocks, And/Or instead of AndAlso/OrElse, Len() instead of .Length(), s/o Hungarian prefix warts, Dim MyVariable with no type, functions with no return type... I could go on.

Being unaware of heaps of existing and extensible functionality in the framework. Things often redone are membership, roles, authorization, site maps. Then there are the controls and the associated tags which can be customized to alleviate issues with the client IDs among others. Also simple things like not knowing to properly use the .config file to auto import namespaces into templates, and being able to do that on a directory basis. Less known things like tag expressions can be valuable at times as well. Surely, as with all frameworks, there is a learning curve and always something left to be desired, however more often than not it is better to customize and extend an existing framework instead of rolling your own.

Not a pure ASP.NET thing, but ...
I was trying to use either a) nested SELECT or b) WITH clause and just could not get it to work, but people who were obviously more knowledgeable (including someone I work with) told me the syntax was fine. TURNS OUT ...
Was not able to use either of those with OLEDB.
OLEDB query to SQL Server fails
(Also, I was bit by the response.redirect() in the try ... catch 'feature' mentioned in the OP! Great thread!)

Databound controls inside an INamingContainer control must not be placed inside templated controls such as FormView. See this bug report for an example. Since INamingContainer controls creates their own namespace for their contained controls, two-way databinding using Bind() will not work properly. But when loading the values everything will look fine (because it is done with Eval()) it is not before you try to post back the values that they will mysteriously seem to not land in the database.
This so question demonstrates the issue well: AJAX Tabcontainer inside formview not inserting values

(VB.NET) If you send an Object via a Property's Get accessor into a function with a ByRef keyword, it will actually attempt to update the object using the Set accessor for the Property.
Ex:
UpdateName(ByRef aName as String)
UpdateName(Employee.Name) will attempt to update the name by using the Set on the Name property of Employee.

Related

NewRelic ignore a single page from monitoring

I have a site hosted on Appharbor (free version), and then have the NewRelic free add-on. I setup the availability monitoring to go against my homepage.
Now, I'm getting a bunch of errors because my REST api page is returning errors. I want NewRelic to completely ignore this page.
How do I have NewRelic ignore this page?
It sounds like you want to investigate DisableBrowserMonitoring() in the New Relic .NET agent API.
If you only want to turn off the RUM feature for some applications (app/website being monitored) you can use the DisableBrowserMonitoring() in the New Relic .NET agent API mentioned above. This disables the automatic insertion of browser monitoring scripts for specific pages. Currently, this is only supported with web applications, but we have experienced success that this can work with static pages. Add this call to any pages you do not wish to instrument with page load timing (sometimes referred to as real user monitoring or RUM). More information, recommendations and an example how to use this here: http://docs.newrelic.com/docs/agents/net-agent/features/net-agent-api#disable_browser.
Another solution is to use the browserMonitoring element child of the configuration element. browserMonitoring configures page load timing (sometimes referred to as real user monitoring or RUM) in your .NET application. Page load timing gives you insight your end users' performance experience. This is accomplished by measuring the time it takes for your users' browsers to download and render your webpages by injecting a small amount of JavaScript code into the header and footer of each page. More information: https://docs.newrelic.com/docs/agents/net-agent/installation-configuration/net-agent-configuration#browsermon-autoInstrument
<browserMonitoring autoInstrument="true">
<attributes enabled=”true”>
<exclude>myApiKey.*</exclude>
<include>myApiKey.foo</include>
</attributes>
</browserMonitoring>
The config file method lets you filter without having to change code. However, you also have to be careful if you use the config option to exclude paths because you're putting a Regular Expression in there, and if it is a complex one (which it shouldn't be) it could affect performance and things like that. On the other hand, if you just use a plain and simple regex to look for a page, it is pretty fast too.
I think that the API calls might perform better but that is totally subjective, and I wanted to give you both options.
Note, after any change in your configuration, you will need to perform an iisreset as administrator and exercise your app for a while to see the changes reflected on your New Relic Dashboard.

What is the equivalent approach of ASP.Net's Page Load method in JSP

While working on an ASP.NET project, I really liked the concept of a class for each page or webform, where I could write all the method and actions I want, and more importantly, the Page Load method.
Everyone says that we should avoid using scriplets, either in ASP or JSP.
And I suppose that the Page Load existed for us so that we don't use scriplets anymore.
Because I heard and read many times that we can't know when these scriplets will run, but in the Page Load method, we know exactly how the codes will run and how the page will be rendered.
But in JSP, as far as I know, we don't have this type of server-side class for each page.
Instead we have something called servelts, which everyone encourages to use.
But technically servlets are independent from the normal JSP pages.
So still, I'm using scriplets in my JSP pages, even though I'm trying to make them less as much as I could, but I still use some scriplets to check the Session and some URL parameters.
Isn't there a similar idea or approach to the Page Load (ASP) in JSP?
BalusC was right in saying you are comparing apples to oranges. JSF was created in response to asp.net. (source # 47 minutes) It has grown independently and you might do well to look into all the different frameworks and paradigms out there. While JSF will work similar to asp.net there are plenty of alternatives worth exploring. In .NET you might want to look into MVC4. In Java there is Tapestry, Spring MVC, Seams, etc.
I would start with wiki comparison and go from there. At your stage in the game I would pick one and try to get familiar with it, than try 2 more to do that same thing.
http://en.wikipedia.org/wiki/Comparison_of_web_application_frameworks#Java_2

Options for storing Session state with SharePoint

I have written a user control for our SharePoint site that builds an HTML menu - this has been injected into the master page and as such ends up rendering on all pages that use it. There are some pretty computationally expensive calls made while generating this HTML and caching is the logical choice for keeping the page loads snappy. The HttpRuntime Cache has worked perfectly for this so far.
Now we are embarking down version 1.1 of this user control and a new requirement has crept in to allow per-user customization of the menu. Not a problem, except that I can no longer blindly use the HttpRuntime Cache object - or at least, not use it without prefacing the user id and making it user specific someway.
Ideally I would like to be able to use the ASP.NET Session collection to store the user specific code. I certainly don't need it hanging around in the cache if the user isn't active and further, this really is kind of session specific data. I have looked at several options including it in the ViewState or enabling Session management (by default it is disabled for a good reason). But I am really not all that happy with either of them.
So my question is: How should I go about caching output like this on a per user basis? Right now, my best bet seems to be include their user id in the Cache key, and give it a sliding expiration.
It's worth pointing out that I believe the 'end of days' link providing is relevant for SPS2003 not MOSS2007 - afaik MOSS integration into Asp.Net means that the mentioned issue is not a problem in MOSS.
I use ViewState on a fairly large MOSS 2007 deployment (1000+ users) for custom webparts and pages, and I haven't noticed a detrimental effect on the deployment performance at all.
Just use it, is my advice.
I don't understand why you wouldn't use SharePoints built in web part caching mechanism for this on a per user basis (Personal) - its exactly what its designed for.
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webpartpages.webpart.partcacheread.aspx

Response.Redirect bad seed or just misunderstood

Recently I posted a answer to a question that I thought was quite an easy one, The question was about issues with the lifecyle of the page in asp.net where items would only reflect the changes made after the first postback, so I suggested using
Response.Redirect(Request.RawUrl)
And almost instantly got voted down for this as (Why cause another round trip)
Well I want your suggestion, is this type of thing good practise, simply practical or should never be used, please back up your answer with a little motivation its something I do from time to time and now question if I should rethink it.
This is the original post
Dynamically Change User Control in ASP.Net
There is nothing inherently wrong with Reponse.Redirect, just in most cases it isn't required in that kind of situation. You can change the way the page is constructed by working with the lifecycle rather than against it. Then there shouldbe no need for another postback.
The ASP.Net page lifecycle provides plenty of opportunities to step in and set things up, so I don't see that it would be necessary to use Response.Redirect to make the client load the page twice.
As an aside, using Response.Redirect with just the one argument can throw a ThreadAbortException, so it's often best to use the overload Response.Redirect(string url, bool endResponse) with the second argument set to false. This definitely applies to ASP.Net 1.0 and 1.1 (see here), not sure about 2.0.
Another solution would be to use an UpdatePanel with an AutoPostBack DropDownList to switch the user controls, then that is only responsible for switching the user control, and when the main submit button (or other event) posts back the whole form, you can process all of the data.
UpdatePanels do update the local page ViewState, if you do it correctly.
It seems like programming by coincidence, but much of ASP.net is that.

Unable to view values of variables while debugging

I'm trying to debug portions of the current application I'm working on, however when I try and check the value of a property/variable I get the error:
Cannot evaluate expression because a thread is stopped at a point where garbage collection is impossible, possibly because the code is optimized.
This is just a regular ASP.NET project. In some portions of the application I can view the properties and variables perfectly fine. I haven't figured out what's different about the blocks of code that I can and can not see the values of the variables in.
The problem was documented on an MSDN blog, as being a size limitation of certain types in certain situations, more details in the link. I believe it was 256 bytes and/or the total size/count of the number of arguments passed to a function. Sorry to say there does not seem to be a quick fix, but hopefully the MSDN blog entry will help you identify a way to solve your problem.
This article, Rules of Funceval gives a number of reasons why this can occur. If debugging is turned on and optimisation turned off already, there doesn't seem to be much else you can do about this problem.
Are you making release builds? Try changing the configuration to "debug" and see if it improves.
We have the same problem in two of our WinForm user controls. In both cases the user controls contain a lot of business logic (2000 and 3000 lines of code respectively) and make use of multiple fairly heavy objects (they have 30+ properties that get populated automatically from the database the first time when one of the properties are accessed). When you try to step through the (somewhat complicated) validation and saving methods, you get this same message when trying to access object properties.
We have come to the conclusion that the size and complexity of the user control combined with the size and complexity of the objects used and conditional database access just becomes too much for the debugger to handle and that we should probably just do some major refactoring to move most of the business logic out of the user control. It would be interesting to know if your problem arises from the same kind of situation and whether doing the said kind of refactoring actually does make a difference (we have not had the time and/or courage :) to do so).

Categories

Resources