.Net 2.0
I deployed a site today that has some code in the Global.asax event handlers. I let Visual Studio 2008 add the file to my project when I created it, and it put the code directly in the file inside <script runat="server"> tags. I went with it. So when I deployed the file, none of the events fired. Ever. The lesson is: Don't put your code in the global.asax file. Apparently this problem is by design. There is a vague KB Article on this problem, but the solutions aren't all that helpful, I didn't want to pre-compile, and the first solution made no sense at all. A little searching and I found one good solution: put a class that inherits HttpApplication in the App_Code folder as described here. What I don't understand is why Visual Studio adds the file that way if it isn't going to work on an xcopy deployment. Microsoft seems to go out of their way to protect us from ourselves so often that I am surprised the IDE does something intentionally that won't work.
In Reporting Services reports, page breaks occur when the size of the body exceeds the page size. The crux of the lesson I learned is that the size of a sub-report cannot exceed the size of the parent containing it. Funny page breaks occur in the PDF output if this is the case.
Brian Welcker posted some terrific details on how page breaks work in Reporting Services, this post is essential if you are creating reports.
I have a web project (the original 2005 web project type, not a web application project) and had a problem getting files copied to the bin directory. Essentially, one of the library projects referenced by the web project has an XML file in the project output, but when the solution is built, the XML file in the bin directory of the library project is not pulled into to the bin directory of the web project. Of course, a post-build event seemed like the thing to do, but web projects don't have support for that.
A little digging and I found this post by Scott Guthrie that describes a "Build Helper Project". You simply add an empty class library project to your solution. You then use the build events in the empty project use to add build events to your web project. You just make sure the project build order is correct so the events get called when you need them.
I've seen it many times in the past,
now it has a name
I kept getting an error when trying to use
CopySourceAsHTML in Visual Studio 2005. The error was that CopySourceAsHTML was unable to access the clipboard. Turns out the problem is when using it in a VPC, and
the answer is here.
I have a pipe-delimited text file that I am parsing and using to fill a collection
of custom business objects. Instead of hard-coding the bits of each pipe-delimited
line, I am using an XML file to map data items in the file to object members, like
this XML fragment:
<Field>
<Name>NAMID</Name>
<Location>0</Location>
<MapsTo>MemberId</MapsTo>
<IsRole>false</IsRole>
</Field>
After parsing and matching the data element to the proper member name, I call this
function:
public void SetDataMemberValue(string memberName, Member member, string data)
{
// get an instance
// of that object's type.
Type objectType = member.GetType();
PropertyInfo[] properties = objectType.GetProperties();
foreach (PropertyInfo property in properties)
{
if (string.Equals(property.Name, memberName, StringComparison.OrdinalIgnoreCase))
{
object[] args = new object[1];
args[0] = data;
object result = null;
if (property.PropertyType == data.GetType())
{
//The type of the property matches the data's type
result = data;
}
else
{
result = property.PropertyType.InvokeMember("Parse", BindingFlags.InvokeMethod, null, result, args);
}
if (result != null)
{
property.SetValue(member, result, null);
}
}
}
}
The tricky bit is the InvokeMember call, which is casting my string to the
appropriate type for the property. Of course this is they stylized version of the
function, I removed the try-catch bits to make it smaller and readable for the acutal
function. You should wrap the InvokeMember call with a try-catch as Parse
methods can fail quite hard.
OK, now that would seem like a pretty straightforward problem, but really it was something else altogehter.
Currently I am writing a helper app for MCMS (Microsoft Content Management Server) 2002 to migrate files from another CMS to MCMS. I am using C# and PAPI calls. Everything was fine on the development server. When I moved the app to the staging (QA) server to perform the migration there (you can't use PAPI remotely), the app got an exception the moment it tried to connect to MCMS: "The CMS Server license has expired". Of course immediately I thought the obvious. After a little digging I found this information in the FAQ implying that I didn't have the proper permissions. I had the server admin elevate my permissions and immediately the problem was solved.
The lesson here: "Develop with least privledges!" It will save you headaches later.
I will be presenting sessions at the
Speaking at the Visual Studio 2005 Experience on July 28th. My sessions will be on
Visual Studio 2005 – New Features inside the Microsoft Across America truck. There are still spots available for some of the sessions that day. Sign up before it is too late!
An
excellent post by Pablo Castro of the ADO.NET team explaining the mechanics of how batch updates work with ADO.NET 2.0 and Sql Server 2005.
Learn how to leverage Active Directory in your .Net apps:
The .NET Developer's Guide to Identity
When creating VSTO documents that use an Action Pane, the Action Pane gets "lost" if you open another non-VSTO document. The Action Pane is hidden by the different document (as it should), but when you switch back to the original VSTO document, the Action Pane does not automatically re-open itself. This can be fixed by handling the ThisWorkbook_WindowActivate event. In this event we can check the state of the Actions Pane and re-display it if necessary:
private void ThisWorkbook_WindowActivate(Microsoft.Office.Interop.Excel.Window Wn)
{
if (!Globals.ThisWorkbook.ActionsPane.Visible)
{
Globals.ThisWorkbook.ActionsPane.Visible = true;
}
if (!ThisApplication.DisplayDocumentActionTaskPane)
{
ThisApplication.DisplayDocumentActionTaskPane = true;
}
}
An awesome post by Jessica Fosler about
finding memory leaks.
With extensive use of the ListObject in an Excel VSTO project, I have identified a
second actual bug in the ListObject. This one also has to do with pasting data like the
previous bug I posted about, but this time data is being lost instead of created erroneously.
I just learned about a FREE .Net training event being held in Ann Arbor, MI on May 13th, 2006: Day of .Net! Check out the agenda at the site.
It is a one-day event advertised as a One Day Conference on all things .NET by Developers for Developers. Lots of great speakers, starting with Mark Miller of Mondays fame, and lots of great local .Net experts, including great guys like Aydin Akcasu, Nino Benvenuti, Dustin Campbell, Jason Follas, Dave Giard, Charles Stacy Harris III, Darrell Hawley, Jim Holmes, Josh Holmes, John Hopkins, Greg Huber, Paul Kimmel, Alex Lowe, Drew Robbins, Martin Shoemaker, and Bill Wagner.
I am working on an ASP.Net app that usesWindows authentication for users. I have a certain section of the app, the "Administration" set of pages that I want to exclude from certain roles of users. This is easy using a web.config file, but the unauthorized users get an ugly default 401.2 error page. I would like to have a custom page for that, and surpisingly there was not a ton of information out there on how to do it. In fact, more often than not the answer was "It can't be done."
I did find an acceptable answer in the forums at aspfree.com. Essentially the solution is to handle the Application_EndRequest event in the global.asax and check the status code and authentication of the user. Here is my version:
void Application_EndRequest(object sender, EventArgs e)
{
if (Response.StatusCode == 401 && Request.IsAuthenticated && Request.Url.AbsoluteUri.Contains("Administration"))
{
Response.ClearContent();
Server.Execute("../NoAccess.aspx?id=Administration");
}
}
I don't believe this method will work with Forms Authentication, I ran across plenty of posts saying that it works differently.
Thinktecture has released a Visual Studio 2005 compatible version of their free
WSCF tool. WSCF is a Schema-Based Contract-First Web Services code generator. It allows you to design the messages, interfaces and data for contract-first style web services, acting as a replacement for XSD.exe and WSDL.exe. We have been using
XSDObjectGen to do something similarly, but WSCF looks like it is much more flexible. For one thing, it generates collections using generics as List<T> instead of the non-type specific ArrayList that XSDObjectGen creates or the even more simplistic arrays that WSDL.exe creates. If you are using .Net 2.0, this is a great step forward for contract-first tools.
My copy of MSDN magazine arrived last night, and I read the article Practical Tips For Boosting The Performance Of Windows Forms Apps. Good read. Anyway, I was shocked to find out that I have been databinding lists improperly ever since I have been using .Net. I frequently wrote my code like this:
//Bad Code
combobox.DataSource = datatable;
combobox.DisplayMember = "State";
combobox.ValueMember = "Id";
//Good Code
combobox.DisplayMember = "State";
combobox.ValueMember = "Id";
combobox.DataSource = datatable;
Apparenly, order matters very much. In the first example, the combobox binds using the DisplayMember, then rebinds when updated with the ValueMember. In the second example, the binding only happens once.
In our current app, we have two lists that contain thousands of items that need to be bound, so we are binding them during the startup process so the user won't wait when requesting that data. The startup time was reduced by just under 40% by changing the order of the code for binding.
An
old VSTO 2003 post by Kathleen McGrath about how to add images to a CommandBarButton. It still works in VSTO 2005. The example uses the AxHost object to convert bitmaps to stdole.IPictureDisp types for Office toolbars.
I will be giving a presentation at a
Microsoft Developer Care event at their offices in Southfield, MI on January 20th. The event is sponsored by
New Horizons and I will be talking about
What's New in ADO.Net 2.0. There will be two other talks as well, see the
agenda for details.