30 December 2010

Crystal Reports: The maximum report processing jobs limit configured by your system administrator has been reached.

This exception is produced by Crystal Reports when the maximum number of concurrent report processes have been initiated. I have had troubles with this exception in my asp.net application, but at first it seemed almost to occur at random. Recycling the app pool solved the problem when it occurred. After a while (when the application was used more intensively) this became a real problem, as it began to occur more and more often.

My application does not use a ReportViewer, but rather generates a pdf file and sends it to the client as a download, using the following code:
ReportDocument repDoc = new ReportDocument();

repDoc.Load(filename);
// update the crystal report database connection
repDoc.SetCrystalReportDatabase("ConnectionString");

// send the resulting document to the user (as PDF).
Response.ClearContent();
Response.ClearHeaders();

repDoc.ExportToHttpResponse(formatType, Response, true, "Report");

repDoc.Dispose();

At first, I fixed this problem quite easily, by altering one value in the registry:

An error occurred while validating. HRESULT = '80004005'

I was having trouble with this error today, when I was trying to build a Deployment package. I also noticed that my deployment package showed no Detected References anymore.
The weird thing was, that my solution build properly and I could even run the software. It was just the deployment package that was producing errors.

As I found, the first thing to check is missing references. If they are not in use in the code, debugging the project will not produce any errors, building the deployment will. This also includes references to other projects, which are not included in the solution. If not pointing directly to the pre-built dll, these will produce problems.

For me though, this did not solve my problem, but I did find something else that caught my eye;

22 December 2010

ASP Menu leaving empty space above menu items

Today I was having trouble with an ASP.Net Menu control that kept a bit of empty space above, which made it render too low in the div element it was supposed to stay inside of:
This problem just came out of nowhere, one day my menu is showing as it should, the next day, it is not. I even tried rolling back to the older version of the files, but somehow this didn't change a thing. It might have been an update to Visual Studio 2010, which got automatically installed or something.

After looking into the rendered html with IE8 and its developer tools (press F12 to get these, then CTRL-B to click an element in the page and have its tag selected in the developer tool), I discoverd an a-element above my Menu:
(The div with class Menu is my own div, in it you see the table with class ct100_Menu1_2 which is the actual menu, with 2 a elements around it)

21 December 2010

Reseed a table in SQL Server

In Microsoft SQL Server, it is possible to reseed an identity column of a table. If you want to start an identity column at a different value (for instance, after clearing it), you can use the following syntax:
DBCC CHECKIDENT (myTable, reseed, 0)
The next row that is added to the table will have 1 in its identity column. If we would use
DBCC CHECKIDENT (myTable, reseed, 41)
the next row would get 42 in its identity column.

Be careful when using this on tables with rows in them, if the new seed is lower than the highest currently in the table, you will encounter problems before long. When the new seed is already in use, you will get a unique key restriction violation on insert!

20 December 2010

Convert objects to string and back without culture problems

After storing various values as strings in a database, I had some troubles with parsing these values back to their original types (doubles, datetimes, etc.) on various clients.
As it seems, the most commonly used ways (such as ToString(), Convert.ToString(), Convert.ToDecimal() and DateTime.Parse()) perform these conversions based on the current culture. This means that the whole format of a datetime can differ on different clients, but also the thousands separator in numbers and also their decimal mark as all of these are culture dependent.

The best way I have found to convert values to strings and back, independent of the current culture, is with the use of the FormatterConverter class. This class converts objects to other objects, independent of any culture (probably using the InvariantCulture).

It can be used as follows:

FormatterConverter fConverter = new FormatterConverter();
double d = fConverter.ToDouble(stringValue);
string s = fConverter.ToString(datetimeValue);


It can be used for other types, by using its following method:
object Convert(object obj, Type t)

For instance, to convert a string to a Car object, you can use the following:
Car myCar = fConverter.Convert(stringValue, typeof(Car)) as Car;
you have to cast the result to Car, as the Convert method returns an object.

17 December 2010

Could not load file or assembly 'System.Data' or one of its dependencies

The full exception is:
Could not load file or assembly 'System.Data' or one of its dependencies. An attempt was made to load a program with an incorrect format.

This problem seems to occur rather a lot and it seems there are different causes for it to occur. I have had this problem today and the information I found on the internet did not help at all. I have tried setting System.Data to not copy local, but then it just started with other libraries. I have also changed the .net version in my web.config, but that did not solve my problem either.
The only real difference that I could find between the old and new server was the fact that the new server was 64-bits. So looked into that and found an option in the advanced settings of an app pool in IIS7, named "Enable 32-Bit Applications".


After setting it to true, everything worked as before.

16 December 2010

Getting the ISO weeknumber in SQL Server 2005 (and earlier)

I just discovered that SQL Server often returns the wrong week number when using DatePart(wk, @date).
For instance, SELECT DatePart(wk, '2010-12-17') returns 47 while it should be 46.
This is because SQL Server starts counting weeks from 1 Jan, so 1 Jan is always in week 1 of the year.
The ISO standard states that week 1 is the first week with 4 days in it.
The following code can be used (with @date being the datetime) to return the ISO week

CREATE FUNCTION GetISOWeek(@date DateTime)
RETURNS INTEGER
AS
BEGIN

  declare @ISOweek INTEGER;
  select @ISOweek = datepart(wk ,@date) + 1 - 

    datepart(wk, 'Jan 4,' CAST(datepart(yy, @date) as CHAR(4)));
  if (@ISOweek = 0)
    select @ISOweek = datepart(wk, 'Dec ' + CAST(24 + 

      datepart(day, @date) AS CHAR(2)) + ','
      CAST(datepart(yy, @date) - 1 as CHAR(4))) + 1
  RETURN @ISOweek
END
GO

(From windowsitpro.com)

Since SQL2008, DatePart supports the ISO Week, by calling:
DatePart(isowk, @date) or  DatePart(isoww, @date)

Get the date of the Nth day of a given year and weeknumber

Given a year and a weeknumber, you can calculate the date of the Nth day of that week. The best way to do this as far as I have been able to come up with is this:


public static DateTime GetNthDayOfWeek(int year, int weeknumber, int n, CultureInfo culture)
{
  // Get 1st jan of given year
  DateTime date = new DateTime(year, 1, 1);


  // Get the weeknumber of this 1st jan
  int beginWeek = GetWeekNumber(date, culture);
  if (beginWeek >= 52) beginWeek = 0;


  // determine how many weeks to jump ahead for the requested week
  int weeksToProgress = weeknumber - beginWeek;


  // Add this number of weeks
  date = culture.Calendar.AddWeeks(date, weeksToProgress);


  // move to nth day and return
  int dayOfWeek(int)culture.Calendar.GetDayOfWeek(date) - 
    (int)culture.DateTimeFormat.FirstDayOfWeek + 1;
  if(dayOfWeek <= 0) dayOfWeek += 7;
  return date.AddDays(n - dayOfWeek);
}


The GetWeekNumber method is of course the one as described in the post before this one.

Get the culture specific weeknumber in .NET

The easiest way to get a culture specific weeknumber is the following:
culture.Calendar.GetWeekOfYear(inputDate, 
    culture.DateTimeFormat.CalendarWeekRule, 
    culture.DateTimeFormat.FirstDayOfWeek);

Where culture is the culture you wish to use for determining the weeknumber. To use the current culture, you can use the following:
CultureInfo culture = CultureInfo.CurrentCulture;