Thursday, September 26, 2013

Dynamically Created Control Not Firing Events in ASP.Net

I have an aspx page where when someone changes the value in a Drop Down List the database is queried and records are displayed in an HTML table.  As the table is created I add a Button control to each row.  I have tried this with a CheckBox as well with similar results.  I also wire up a click event for each button when it is created.  All the events for the Buttons point to the same event.

The grid is created properly, with the button on each line.  When I click one of the buttons the Page_Load event fires, but the click event does not.

When I dynamically create a button outside the grid from the Drop Down List's SelectedIndexChanged event it also does not fire the click event.

When I move the button creation code to the Page_Load event wrapped in an If (!IsPostback) block the Click event works properly.

It appears that if the control is not created in Form_Load or Form_Init the dynamic control's events do not fire.  I have not found a solution to be able to do what I want, but I thought what I found in my research so far might be useful to someone.

Monday, August 5, 2013

How to Get SQL Report Services Report Built With Report Builder to Display No Page Breaks on Screen, But Still Break When Printed

I created a report with Report Builder 3.  My users are us to seeing reports displayed on screen with no page breaks.  It looks like the default is to have page breaks.  I found that in the report properties there are a couple of properties to manage page breaks.

In Report Builder, right click outside the report body and click Report Properties.  In the properties window there is a page section when you have it sorted by property category.  In that section there is a property called InterActiveSize.  If you set the height and the width of this property both to be 0 the report is displayed on screen in one long page with no breaks.

The other property is PageSize.  This has to do with the printed page.  It is right below the margin property where you can control margins.  I think this only controls them for the printed page.

Friday, August 2, 2013

Data Bound GridView and Asp.Net Ajax UpdatePanel

I tried loading a couple of grids through an update panel with a timer to try to get the rest of the page to display to the user quickly and do the heavy lifting of these two grids in the background.

I wrapped the two grids in an update panel and added a timer.  I put code in the tick event of the timer.  I loaded the page and it came up quickly and moments later the grids filled in.  Moments after that all of my dynamic data i have created with template fields was erased.  The main data that was being bound was still there.

As I researched it I found that the RowCreated event was firing repeatedly.  I viewed the call stack and saw that it was being fired by system code that I could not see and not by my code.

I tried using session variables to get it to routed around the multiple calls, but the damage was being done before it got to the RowCreated event.  The event also was getting null values for ID fields I was using to populate the grid correctly, which is why the dynamic data was not being displayed.

I did a couple of hours of research, but found nothing specific to my problem, but I did start stumbling upon two properties of the update panel, ChildrenAsTriggers and UpdateMode.  Honestly I don't entirely understand UpdateMode yet, but ChildrenAsTriggers got me thinking that maybe the grid was triggering a refresh of its own somehow after I got everything set the way I wanted it.

I set ChildrenAsTriggers="false".  It required that I have UpdateMode="Conditional".  I think this also required that I have an explicit Trigger tag for the update panel that was set to the Tick event of my timer.

After all that, it appears to be working.

Friday, June 28, 2013

IIS Routing and Paths With 404 in Them

We had a problem today with a path routing.  We had a path similar to this http://localhost:54612/mydir/invoice/40414

It appeared that this path was never getting to the code, but being bounced back by IIS.  The URL http://localhost:54612/mydir/40399 worked just fine.

After further research we found that it was number at the end with 404 in it that was breaking us.  http://localhost:54612/mydir/30404 also broke.

The code we were using was

RouteTable.Routes.Add(new RegexRoute(@"^/mydir/invoice/(?\d+)/?$", new PathRouteHandler("~/myotherdir/file.aspx")));

Once we changed it to

RouteTable.Routes.Add(new Route(@"mydir/invoice", new PathRouteHandler("~/myotherdir/file.aspx")));

it worked.

We had to change the catching code to check the query string instead of the route path, but it worked.

We have yet to discover why it was behaving badly with invoice numbers containing 404.  I would love to read your thoughts if you have run across such a thing.

Friday, April 12, 2013

There is already an open DataReader associated with this Command which must be closed first

Every so often in our ASP.Net website we would get the error, "There is already an open DataReader associated with this Command which must be closed first" referring to a SqlDataReader.  We would tweak code here and there and get it to go away.  Later another code tweak would bring it back.  We have no idea what is causing it.  


It is in a block of code that creates a SQLCommand, creates a SQLDataReader, and destroys the SQLDataReader and SQLCommand.  We are not sure how it is possible that another reader is executing on that command.


As a work around until we can find the issue we have added this attribute

MultipleActiveResultSets=True

to our connection string and it has seemed to have bypassed the problem.  I know it likely causes other problems, but due to the environment we work it that's what we have to do.

Installing Spring...



Installing Spring...

50% ready...

! Installation failed.  Error 404 Spring not found.  Spring is not available in your state.  Please try Florida.

ReportViewer Control ASP.Net Disabled When Routing

I was experimenting with possibly using Microsoft's Report Builder tool to create reports and then use the ReportViewer WebForms control to display them on a web page.

When I would create a small test site everything was great.  When I would add a report to our existing site it would show me a disabled ReportViewer task bar and no data from the report.

It took me forever to figure out why this was happening and longer to track down solutions.

Everywhere I went I saw people saying that it was something in my web config.  They sited that SQL Server 6 needed a different section in the web config than SQL Server 7 needs.  I saw that my web config had both and at one point I removed the older declaration and things started to work.

Then it happened.  The other day I was adding controls and experimenting with the page and all of a sudden I was back to square one.  I did ctrl-Z until I had removed all the changes I had been making on the page and got everything back to the way they were in code.  It didn't fix the display of the page.

This was horrible.  I was so close to delivering something and I had even told my superiors it was just about done and now I was stuck with a broken page I had no idea how to fix.  Nothing logically made sense.

I knew that one of the big differences with our site and a quick and dirty site with one page was routing.  We have a file filled with different routings.  I decided I would try disabling them and see what happened.  Sure enough it worked.  The problem was that the rest of the site was broken without the routings being turned on.

I searched and searched and kept finding the same old things about the web config.  Then I found a block of code like this.

  <handlers>
    <remove name="WebServiceHandlerFactory-Integrated"/>
    <remove name="ScriptHandlerFactory"/>
    <remove name="ScriptHandlerFactoryAppServices"/>
    <remove name="ScriptResource"/>
    <add name=": Reserved-ReportViewerWebControl-axd" path="Reserved.ReportViewerWebControl.axd" verb="*" type="Microsoft.Reporting.WebForms.HttpHandler" resourceType="Unspecified" preCondition="integratedMode" />
    <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
  </handlers>
This is much like the web config stuff I had seen elsewhere, but it had a bunch of other stuff around it. I have no idea if they relate, but I plugged them all in wholesale and decided I would yank out what didn't compile.
I also noticed that the line starting with <add name=": Reserved-ReportViewerWebControl-axd" had more attributes assigned than what the ones in my code had.

Everything worked. No compile errors. The control displayed the report and was not disabled.

I had no time to figure out if it was the extra attributes or the extra lines of code. All I know is it works. I hope this post will help someone else climb out of what they are struggling with because this was horrendously frustrating.

Update:
After adding all that and getting ready to deploy, I moved the site to a different location on the same machine. Not even a different machine. The original location continued to work fine, but the new location gave the disable ReportViewer control. I searched and search again.

When I had the problem previously I tried disabling routing for the control with the follow 2 lines of code:
RouteTable.Routes.Add(new Route("{resource}.axd/{*pathInfo}", new StopRoutingHandler()));
RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");
Neither worked.  When I ran into the problem again I seemed to recall one post saying that the order of routes mattered.  Previously I had tried to remove the routes with these lines at the end of all the routing, thinking it would remove whatever got added.  It appears that it is the opposite.  If you tell it not to route from the start then nothing gets applied to it in the other routes.

I moved the lines to the top of the routing code and tested each line.  I found that either of them worked.

Monday, March 25, 2013

Abstract Class vs Interface

Conceptually, abstract classes are very similar to interfaces with a few differences.  One way to think of the two is like this:  An abstract class can be defined as "Is a".  An interface can be defined as "Can do".

When you create an abstract class you are creating a thing that something else would be.  For example, "car" could be an abstract class and everything that inherits from it is a car.  When you create an interface you are defining what something can do.  If you define an interface of "drive", anything that implements that is saying that their object can drive.  The interface doesn't say how to drive it just says your object needs to be able to drive and it defines what things something can do to be able to drive, just not how they do it.

Interface
Interfaces cannot implement method implementations.  They can contain abstract methods.

An abstract method defines a method signature (types of parameters it takes and the type it returns), but does not define the implementation or how the method does what it does.  The implementation will be coded in the class that uses the interface.  Many classes can use an interface and each of them may implement a certain method of the interface entirely different.

Interfaces do not have constructors or destructors (special methods that fire upon creation or disposal of an object to allow the class to initialize things or clean up things)

A class can implement multiple interfaces.

An interface is sometimes called a contract or promise.

An interface cannot extend classes, but they can extend other interfaces.


Interfaces can be used as bridges across classes inherited from different base classes. They can also be used to make it easier for third parties to communicate with your classes. 



Abstract Class
Abstract classes must contain at least one abstract method.  Abstract classes can also contain concrete methods or methods that already have an implementation defined.

Just like any other class abstract classes contain constructors and destructors.

A class can not inherit from multiple classes, not even multiple abstract classes.

Abstract classes cannot be instantiated directly.  They must be inherited from and then the class that inherits from them can be implemented.  The abstract keyword indicates that the class is defined for inheritance. 

To create an abstract class you use the abstract keyword:


public abstract class MyAbstractClass {}


Abstract classes can use interfaces, but every class that inherits from the abstract class will be bound by the interface, which means they must implement every method and property in the interface.

An abstract class is used for creating a class hierarchy. 


Friday, March 22, 2013

Array vs ArrayList vs Generic List vs LinkedList in .Net

Array vs ArrayList vs Generic List vs LinkedList in .Net

Arrays

Arrays cannot shrink or grow unless you copy the array to an entirely new array of a different size.  Once the size of an array is declared that is the size it must remain without heavy overhead.

Arrays can contain objects or primitives.


ArrayLists
An ArrayList uses a dynamically expanding Array internally, so there can be a performance hit when expanding past the size of its internal Array.  The size of the internal array of an array list does not change, in order to increase performance.  When an element is added beyond the capacity of the ArrayList the internal array is copied and a new array of twice the number of elements is created.  Thus reducing the need to expand the internal array for a while.  This uses more memory, but can make it perform more quickly.  Array lists also start with an internal Array with ten elements, also to reduce the need to increase its size.

ArrayLists can only contain objects.

List
List is a generic implementation of ArrayList.  ArrayList appears to be being deprecated.

LinkedList
LinkedList can have performance issues since it can cause memory fragmentation.  There is no set bounds for a LinkedList, so data in the list can end up anywhere in memory.  This can be confusing, since we also said that ArrayLists can have performance issues due to recreating the internal Array on inserts.

You have to determine when you need to gain.  Do you need to free up memory or need to have fast inserts and deletions, then LinkedList.  Do you need fast access to items and will be doing very few inserts, then perhaps Array or List is what you want.

Memory
ArrayLists can use 100s of percent more memory than List.

Types

Under the covers ArrayList is an array of type object[].  List is an array of whatever specific type T you make it.  This can allow for better memory usage and a more precise implementation in code.

Performance

Arrays and Lists allow for very fast read since they are a fix size making each piece of data stored right next to each other in memory.

LinkedList can have performance issues since it can cause memory fragmentation.  There is no set bounds for a LinkedList, so data in the list can end up anywhere in memory.


Friday, February 22, 2013

Recursive and Nested Triggers in TSQL

We would get this error message "Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)".

I was told that turning off recursive triggers would fix it.  Likely the problem could better be solved by redesigning the triggers and such, but not authorized for that right now.

Recursive Triggers is an Option that can be set by going into SQL Management Studio and right clicking on the database and clicking Properties.  In the left pane click Options.  Sort the properties alphabetically and set the option Recursive Triggers Enabled = false.

You can also set this option by:
ALTER DATABASE databasenameSET RECURSIVE_TRIGGERS OFF

The option can also be set like this:

EXEC sp_dboption 'database-name', 'recursive triggers', 'FALSE'


It appears that in different places you may see the values OFF, false, and 0, which all mean the same thing.  The inverse would be ON, true, and 1.

Once I set this option it did not fix the problem.  I ended up finding that there is another setting similar to Recursive Triggers called Nested Triggers.  It is not in the Options section with Recursive Triggers.

Nested Triggers are turned off like this:

sp_CONFIGURE 'nested_triggers',0
GO
RECONFIGURE
GO

Make sure you are logged into the database for which you need to set the setting.

I don't entirely understand the difference between these two settings yet, but my guess is that Recursive Triggers controls whether a trigger is allowed to fire itself and that Nested Triggers controls whether a trigger can fire other triggers.