Technical findings, ideas, thoughts and news directly from me.

PAGES

17

Dec 08

SSRS Export Feature Causes an "Object Moved" Error



I ran into the following issue with SSRS 2005 where some users would run a report and then try to export it into a different format (Excel, PDF, etc) using the SSRS web site tool bar resulting in an “Object Moved” error. Some would see the error in a pop-up message box or as an ASP.Net Server Error page after clicking the Open or Save As button on the download dialog (depending on what IE browser version they were using).

After some investigating a lot of things (including spending a lot of time looking at server logs) it was discovered that this isn't a server problem at all. Instead it is an error that occurs for some users based on their IE settings. Since the SSRS site was being run under an SSL certificate when the following IE setting is enabled it can cause the “object moved” error when a user tries to download the report: “Do not save encrypted pages to disk”. Go to the advanced tab in IE settings and uncheck this option if you are experiencing the error when exporting reports in an SSL protected SSRS web site.

0 comments , permalink


29

Jun 08

Microsoft Synchronization Framework – Worth a Look



At TechEd earlier this month I attended some sessions on the new Microsoft Sync Framework that was just released as CTP2. Synchronizing data to a mobile device and between home office and remote locations has been a feature of several systems I've worked on in the past. There were always challenges in this type of functionality and no real good 'fit' that you could easily implement out-of-the-box before. In writing my own customized sync features for applications in the past, I can appreciate the complexities involved which is why at first glance I'm impressed by the range of features available in the Microsoft Sync Framework. Here is a list of the primary features of the framework:

- Different sync topologies are supported including hub and spoke (central system sync to remote systems), one-way syncs, and peer to peer.

- Conflict detection and resolution

- Supports sync of database to database, database to SQL CE, file system, feed syncs (Mesh), and you can create your own synchronization custom provider to sync any other special forms of data you may have.

- Supports unreliable networks, interruptions and partial syncs

- Operates over arbitrary protocols

The functionality is pretty baked at this point as it has entered a CTP2 version and will be released in conjunction with SQL Server 2008 later this year. With the proliferation of smart mobile devices I can only see good things for having this kind of tool in your coding tool kit to easily give LOB applications offline and remote capabilities that can easily sync up with a central system when they come back online. For a download of the framework and detailed documentation on how the sync process works (the concept of “Knowledge” between the sync'ing systems) see the MSDN home site for the Microsoft Sync Framework.

1 comment , permalink


28

May 08

SQL Server Reporting Services Subscriptions with custom security



I ran into an interesting ”gotcha” when working with an SSRS site that has a custom security extension implemented (instead of using the built in Windows authentication model, see the MSDN security extension example). The problem was that when users had set up a subscription through the SSRS web site that requested a copy of the report (such as in pdf or excel format), the subscription would fail to run. Looking in the SSRS I”d see error entries similar to the following:

ReportingServicesService!library!13!05/27/2008-14:00:16:: i INFO: Call to RenderFirst( ”/Financial Reports/Virtual Bookstore Sales By Term” )

ReportingServicesService!library!13!05/27/2008-14:00:16:: e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.InternalCatalogException: An internal error occurred on the report server. See the error log for more details., ;

Info: Microsoft.ReportingServices.Diagnostics.Utilities.InternalCatalogException: An internal error occurred on the report server. See the error log for more details. —> System.TypeInitializationException: The type initializer for ”Framework.SystemConfiguration” threw an exception. —> System.ApplicationException: Can not find applicationConfigurationManagement section in app.config.

at Framework.ConfigurationManagement.ConfigurationManager.Read(String sectionName, String qualifierName)
at Framework.SystemConfiguration.LoadConnectionStrings()
at Framework.SystemConfiguration.Initialize()
at Framework.SystemConfiguration..cctor()
— End of inner exception stack trace —
at customReporting.Authorization.CheckAccess(String userName, IntPtr userToken, Byte[] secDesc, ReportOperation requiredOperation)

at Microsoft.ReportingServices.Library.Security.CheckAccess(ItemType catItemType, Byte[] secDesc, ReportOperation rptOper, String reportPath)

at Microsoft.ReportingServices.Library.RSService._GetReportParameterDefinitionFromCatalog(CatalogItemContext reportContext, String historyID,Boolean forRendering,Guid& reportID, Int32& executionOption, String& savedParametersXml, ReportSnapshot& compiledDefinition, ReportSnapshot& snapshotData, Guid& linkID, DateTime& historyOrSnapshotDate, Byte[]& secDesc)

at Microsoft.ReportingServices.Library.RSService._GetReportParameters(ClientRequest session, String report, String historyID, Boolean forRendering, NameValueCollection values, DatasourceCredentialsCollection credentials)

at Microsoft.ReportingServices.Library.RSService.RenderAsLiveOrSnapshot(CatalogItemContext reportContext, ClientRequest session, Warning[]& warnings, ParameterInfoCollection& effectiveParameters)

at Microsoft.ReportingServices.Library.RSService.RenderFirst(CatalogItemContext reportContext, ClientRequest session, Warning[]& warnings, ParameterInfoCollection& effectiveParameters, String[]& secondaryStreamNames)

— End of inner exception stack trace –

The error indicated that my custom security dll (customReporting) which utilizes a common library component for our data access and such (framework.dll) was not able to find a setting section in the app.config file. At first I thought it was something related to the web site configuration for custom security since that is where you have to set everything up to get your custom security extension to work. But, everything looked good there. Looking further I found that it is running the subscription process under the SQL Reporting Services windows service instance so it is actually not using the web configurations when executing the custom extension dll but it runs in the context of the service. So to fix this problem you need to add any configuration settings into the ReportServerbinReportingServicesService.exe.config file. This is the configuration file that the SQL Reporting Services windows service is utilizing. Once I added my config information to that file subscriptions worked like a charm! » Read the rest of this entry «

1 comment , permalink


1

Apr 08

Data Warehousing Resources



I've had a few requests lately for resources I've used related to data warehouse design and performance tips for SSAS and SSRS for SQL Server 2005. I thought if a few people are interest there must be a lot of others out searching the web for similar nuggets of gold. So, here is my list of useful links for others to cash in on:

SSAS Performance tips: http://www.calumo.com/pdf/SSAS2005PerformanceGuide.pdf – this is a great white paper from Microsoft on fine tuning your cube performance from dimension design, through query and server hardware best practices.

Using Indexed Views to increase performance: http://www.microsoft.com/technet/prodtechnol/sql/2005/impprfiv.mspx – this article describes what indexed views are and when you should consider using them in your database.

Designing your data warehouse schema – dimension modeling instruction and best practices: http://www.kimballuniversity.com/ – This site was started by Ralph Kimball, called the father of data warehousing by some, and includes many free articles on dimension modeling for a data warehouse. Understanding the Kimball technique is a must for those just starting out in data warehousing.

Best practices from a practical implementation: http://www.microsoft.com/sql/solutions/bi/projectreal.mspx – Project REAL was an attempt to implement a data warehouse for a real customer (Barnes & Noble) using SQL Server 2005 and a large set of real business data. The result is a collection of the project code and documentation on suggested design approaches, best practices and scripts you can migrate into your own applications.

0 comments , permalink


22

Feb 08

February DevCares Content



Thank you everyone who attended the Chicago DevCares event on Feb. 11. We had some interesting conversations on web site security techniques and the new VS 2008 office applications features. I'm sorry for the delay on posting the slides from the event, I know I promised I'd have it up last week after the Chicago DevCares. You can find the slide content for the event at the following links:

Securing Web Applications (Part 1)

Securing Web Applications (Part 2)

VS 2008 Office Business Applications

Please note, to view the slides you'll need Office 2007 or install the Office Compatibility Pack for 2007 File Formats so you can view the file in an older version of office.

0 comments , permalink


18

Jan 08

Threading model issues when using VB 6 COM components in a .NET Web Service



I recently encountered a very tricky issue with the threading model of .NET when you need to interop with a legacy VB 6 COM component. The web service in question was created to consume components of a third party vendor that still distributed API functionality as a set of VB 6 COM dlls. Each web service method utilized one or more calls into the VB 6 components to perform the desired functionality. Initially everything appeared to be working properly under a light user load, but as soon as load increased on the application the web service response times began to vary drastically and in some instances slow to a crawl. This was very perplexing as the call times varied so much it was hard to discern any sort of pattern. The problem was narrowed down to be coming from the response time of method calls to the VB 6 components. A trend was also noticed that the database connection for the VB 6 components was never exceeding 1 connection, which was odd considering there would be 20 ASP.NET calls in progress simultaneously and they were all utilizing the COM component. To me this indicated some kind of bottleneck that seemed to be single threading the VB 6 COM component usage. Slowly I began to remember my glorious (at the time) VB 6 days back in the late 90s and how VB 6 components are compiled to run in a single threaded apartment (STA). After doing a quick search I found an excellent article from MSDN Magazine that described the exact same issues the problem web service was demonstrating. The article explains how the issue arises from .NET running in a MTA (Multi-threaded apartment) and the way the OS is forced to run the COM components in a seperate STA space causing a queuing effect between the multiple ASP.NET threads trying to access the single COM component thread. The solution is to get ASP.NET running in a STA mode as well so that the COM components can be loaded within each individual thread space of the ASP.NET processing threads removing the need to marshal across apartments. This achieves what was the original desired result for the web service of having multiple seperate instances of the VB 6 component running concurrently for each web request. The article gives a sweet implementation work around for .NET to get a web service running in STA mode instead of the default MTA.

I had to post this for as many people to see as possible because we all know VB 6 lives on and this hidden threading issue of using the legacy components from within a .NET web service is not a very apparent problem when it starts happening. I hope this saves every developer from pulling out hair trying to isolate and resolve this issue!

4 comments , permalink


24

Dec 07

Client side JavaScript optimization techniques



Thanks to everyone that attended the December DevCares event in Chicago last week. One of the topics I presented on was techniques for optimizing client side JavaScript to obtain a better Rich Interactive Internet Application (RIIA) experience. A lot of you gave me feedback that you found the content informative and I wanted to pass along a blog link that contains most of the topics we covered so you can have it for future reference:

http://blogs.msdn.com/ie/archive/2006/11/16/ie-javascript-performance-recommendations-part-2-javascript-code-inefficiencies.aspx

Keep the following points in mind as well when writing your script code to maximize your performance:

Performance implications can be tied to the lookup in the scope chain for the variables you are accessing. Here is the list of scope in order of least to highest performance impact: Local variables, global variables, DOM. The DOM is the most expensive operation you can do so be sure to evaluate whenever you are going to walk the tree to work on an object. If you need access to an object in the tree for multiple operations consider using a pointer so that your code doesn't walk the tree each time and take the performance hit. Example:

var lside = document.body.all.lside.value;

var rside = document.body.all.rside.value;

can be changed to:

var ptrAll = document.body.all;

var lside = ptrAll.lside.value;

var rside = ptrAll.rside.value;

Also, you can use function pointers to reduce the overhead of looking up the entry point in situations where the function may be called numerous times.

var length = myCollection.getItemCOUNT() as Computed;

for (var idx=0; idx<length; idx++){

Work(myCollection[idx]);

}

The above loop will perform symbol resolution for the location of the Work function every iteration of the loop, which depending on the collection could be a large iteration. The following example utilizes a function pointer to perform the symbol resolution once prior to the loop.

var funcWork = Work;

var length = myCollection.getItemCOUNT() as Computed;

for (var idx=0; idx<length; idx++){

funcWork(myCollection[idx]);

}

Look for more great developer tips, examples and overviews coming in the 2008 DevCares sessions!

0 comments , permalink


4

Nov 07

Performing Joins using LINQ to Objects



In last months DevCares LINQ presentations there were some good questions on using joins within LINQ statements when querying a collection of objects similar to how you would write a SQL join statement when querying a database. In this post I'll show a simple example of performing a LINQ to objects join.

In order to be able to perform a join of objects you first must have a property on the object that refers to either a reference to the other object itself or any sort of identifier value (such as a numeric ID). You can then use that property as the join property in the LINQ statement. For example, look at the following class definitions:

public class Person{

public string Name {
get { return _name; }
set { _name = value; }
}
public DateTime? Birthday {
get { return _Birthday; }
set { _Birthday = value; }
}
public int JobID {
get { return _jobID; }
set { _jobID = value; }
}
public Person(string name, DateTime birthday, bool member, int jobID){
this._name = name;
this._Birthday = birthday;
this._jobID = jobID;

}

}

public class Job {
public string Title {
get { return _title; }
set { _title = value; }
}

public string Company {
get { return _company; }
set { _company = value; }
}

public int ID {
get { return _id; }
set { _id = value; }
}

public Region Location {
get { return _location; }
set { _location = value; }
}

public Job(int id, string title, string company, Region location) {
_title = title;
_id = id;
_company = company;
_location = location;
}

}

The Person object has a JobID property which is the identifier of the person's job. We can use this to join to a collection of job objects that has more details on the actual job to return in our shaped LINQ result. If we loaded the following person objects and job objects:

List myPeople = new List();
myPeople.Add(
new Person(“Gerald”, DateTime.Parse(“1/2/2003″), 3));
myPeople.Add(
new Person(“Linda”, DateTime.Parse(“2/2/2002″), 1));
myPeople.Add(
new Person(“Sarah”,DateTime.Parse(“4/2/2002″), 1));
myPeople.Add(
new Person(“Bill”, DateTime.Parse(“4/5/2006″), 2));
List jobs = new List();
jobs.Add(
new Job(1, “Developer”, “Microsoft”, Region.West));
jobs.Add(
new Job(2, “Developer”, “Microsoft”, Region.East));
jobs.Add(
new Job(3, “Technical Account Representative”, “Microsoft”, Region.Central));

We could then perform a LINQ statement to filter person's by specific jobs.
var result = from p in myPeople
from j in jobs
where p.JobID == j.ID
select new{
p.Name, j.Company, j.Title
};

Using an anonymous type as the output we can shape the resulting objects to include the person's name, job title and company. We can then manipulate or display this shaped type as necessary. If you wanted you could have also had a Job property of type Job on the Person object and having a direct object reference on the Job property of every Person. It would still be possible to join the Person.Job property to Job in a LINQ statement to include a filter by an attribute of Job or specific pull out Job property values into the results.

Change the JobID property on Person to:
public Job Job {
get { return _job; }
set { _job = value; }
}

Then after assigning Job object references to the Person objects in the people collection you could use LINQ to join in a query:

var result = from p in myPeople
from j in jobs
where p.Job == j
select new{
p.Name,
j.Company,
j.Title,
j.Location
};

LINQ to objects gives you a lot of flexibility in how you can filter against a collection of objects. With this new VS 2008 feature you can virtually wave good bye to all those previous foreach loops with comparison checks embedded within them!

0 comments , permalink


12

Oct 07

October Microsoft DevCares LINQ Presentation Slides



A few people attending the October DevCares presentation in Chicago earlier this week requested access to the slides. You can find the slide decks for all three LINQ presentations given by myself and Rick Haffey here. Please note, you will need Microsoft Office 2007 or the Office Compatibility Pack to view the slide decks.

If you were unable to attend in Chicago you still have time to sign up for the event taking place at the Microsoft office in Downers Grove on Thursday, Oct. 25.

1 comment , permalink


6

Sep 07

Chicago area September Microsoft events



There are a couple of free Microsoft developer events coming up in the month of September in Chicago that are worth a look.

- In downtown Chicago on Sept. 12th is the ArcREADY session. ArcREADY is an event that is touring the Midwest through the month of September. This is a 3 hour morning presentation and discussion covering the technology aspects related to the industry buzz word “Web 2.0″. The topics cover best practices and architecture options for planning and implementing applications using Web 2.0 technologies such as AJAX in ASP.NET, Sharepoint Server 2007 and Windows Communication Foundation (WCF) in Visual Studio 2008. To read more about the session or to register go to http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032345647&Culture=en-US

- In downtown Chicago on Sept. 18th and then in the Microsoft office in Downers Grove on Sept. 27th, is the monthly DevCares event. The topic is Windows Communication Foundation (WCF). DevCares is an afternoon event consisting of multiple presentation sessions focusing each month on a different technology topic. WCF is available in the .NET 3.0 framework and is a significant architecture feature which becomes fully integrated and available in Visual Studio 2008 (there is limited availability of it in Visual Studio 2005 through add ins). This event consists of three presentation sessions on the details of WCF management features, diagnostics, channels and scalability. I will be presenting several of the sessions so I can guarantee it will dig into technical implementation details. For more information, or to register, go to http://www.devcares.com

0 comments , permalink