Friday, April 12, 2013

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.

Wednesday, December 5, 2012

Sorting For Non Programmers With Report Builder

I have one primary user of the system I work on.  There are several user, but this one drives it and has a lot of need for various different reports.  It takes a long time to gather the requirements for each one, write a program to get it up on our web site, test, and deploy each one.

I have been looking for a way that he can gather and aggregate the data himself.  He can play with the data and turn it this way and that way with out getting a developer involved, other than training and supporting the product.

Another developer mentioned that he had heard about SQL Reporting Services (SSRS).  I looked into it and it still seemed like there would have to have a developer involved, since the tools are so complicated.

As I looked into SSRS I came across Report Builder.  It appeared as though each iteration of this product got a lot better.  I downloaded version 3.

It has a wizard for creating the report.  All of that is pretty straight forward, except two things.  I couldn't find a way to do sorting of the report through the wizard and the adding fields to the report seemed a little odd, but they said it is like a pivot table in Excel.  I don't know anything about pivot tables, but my user uses Excel a lot.

I searched and searched online for how to change the sorting and nothing was steering me into something simple for the user.  The best thing I found in my exploration was just adding an Order By clause to the SQL it generates.  That didn't seem great for a user, but I was almost willing to deal with the training for that.

Then I went through the program right clicking on things.  I found that I could pop up the properties window for the table that was the report and in there was a property called Sort Expression.  I had to right click on the grid and choose to select the grid and then I had to go to the View menu and select the properties check box.  Then that brought up the properties box.

It appears to be done in the report itself and not the SQL, because it doesn't appear to change the underlying SQL.

Saturday, November 10, 2012

Authentication Popup When Trying to Access Files In Reports Folder

We are in the process of upgrading to a new server.  Our old one was a Go Daddy dedicated server, which we managed ourselves.  We are having Go Daddy migrate our web site to a newer, faster dedicated server.

As we went through the testing of the new server we found that pages that were in a directory called reports were popping up an authentication box in the browser whenever we would try to browse to them.

We tried checking the permissions on that folder and files and everything seemed fine.  We added permissions to try to help, but it did not fix it.

We tried moving the files to another existing folder and that worked, but we didn't want those files there.

We tried creating a new folder, moving the files there, deleting the old folder, and renaming the new one to reports.  We thought that perhaps the directory had gotten corrupted or something, but it didn't fix it.

We renamed the folder to report and that fixed it.  At first we thought the server didn't like the folder name reports.  They we got to thinking maybe it doesn't like the routing.  We are routing requests that come into server/reports/ReportName to server/reports/ReportName.aspx.

We tried just changing the routing, but that did not work.

We have now left it alone, but our newest theory is that maybe the new server has Reporting Services installed on it and it grabs requests to server/reports for itself.

Update 1-29-2013
I started getting the Windows Authentication popup again today.  This time what I had done was copy our website to another fold, create a new web site, and point the new site to the copy.  When I tried to bring up the home page I got the Window log in box.  I tried various different settings in IIS and also security settings on the folder with not luck.

I finally looked at the Authentication section of the website in IIS.  You get to this by clicking on the website in the left pain of IIS Manager, then clicking Authentication under the IIS section in the right pain.

I looked and saw that Anonymous Authentication was enabled, which seemed like the right value, so I left it alone for a while.  I went back to it later and right clicked on it.  Turns out there is an edit sub menu.  I clicked it and it gave me a screen to pick which user's identity to run under.  It was set to specific user and had a user name selected.  I'm guessing I could've picked another user or went somewhere else and given that user more rights.

Instead what I did was told it to use the application pool identity.  Once I did that I tried my website again and no more being asked for login credentials.  Not sure what the ramifications of this are, so if you find that it is insecure to do that, then maybe the picking a specific user or giving the default user sufficient rights is what you want to do.