![]() |
|
Spaces home Colin Borrowman's ShareP...ProfileFriendsBlogMore ![]() | ![]() |
Colin Borrowman's SharePoint BlogSome things that took me too long to find or figure out...
|
June 10 Debugging "File Not Found. at System.Reflection.Assembly"Have you ever deployed your application to SharePoint only to have one or more pages start failing to load with the infamous "File Not Found" error? Or even just the blank "Error" if you don't have extended error messages turned on?
It usually means you need to add a page reference to allow the page markup to load and resolve your page (or your binary needs to be somewhere it can find it.) Sometime you can figure out what it might be if you just added a new control or referenced some assembly in the page markup. But sometime you don't know and there aren't any good clues. So it happened to me again today and I decided to document the exact steps required to figure out what blew up. Find a copy of the Fusion Log Viewer "FUSLOGVW.EXE." It probably will not be on your deployment server, I think its only installed with development software. I found two copies on my dev box:
1. Copy the more recent version to the deployment server and run FUSLOGVW.EXE 1. Click Delete All 2. Run IISRESET from a command prompt 3. Refresh or load the page you were getting an error on in your browser 4. Click the Refresh button in the Fusion Log Viewer 5. Start looking (from the bottom up) for log entry for App_Web_error.aspx... This is the error page being loaded to tell you "Error" 6. Start looking at the next few items above it for the first assembly that is part of your project. Double click on each one to look at the log entry and see if any of them failed. In my case, I found the dtSearchNetApi2 was trying to load but could not be found. It was being referenced by one of the assemblies being loaded. I need to put it in a location that is searched for binaries, or simply put it in the GAC. Sometimes just adding a page @Register to the markup is all you need. Fixing the problem is easy once you know what problem you are fixing. May 14 Get the list of Blocked File Extensions (file types)This initially looked more difficult that it really is. I didn't find too many examples of how to do this. There appears to be an approach through the adminitrative SDK, since you maintain these through the central admin pages. I also found some examples of the now obsolete SPGlobalConfig.BlockedFileTypes. Turns out it is rather simple, even for a standard user. You can obtain a reference to the current WebApplication from the current site collection object and the blocked file extensions are available right there via BlockedFileExtensions. Here is a sample test.aspx page that dumps the BlockedFileExtensions. The page itself is handy shell to quickly try out an SDK call or two. Just drop it inside C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS (or a sub folder) and access it with http:\\localhost\_layouts\(optional sub folder)\test.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> Response.Write("Blocked file extensions:<br />"); Response.Write("<br />"); Results: Blocked file extensions: April 02 SharePoint Vista Sidebar GadgetHere's a new CodePlex project I've been working on in my spare time. This is a sample project showing how to create a Windows Vista Sidebar Gadget that communicates with a SharePoint site via web services. http://www.codeplex.com/SharePointSidebar It is in the proof-of-concept phase right now and it currently only works with windows or anonymous authentication. But it will continue to evolve to include basic and forms based authentication as well. March 16 CSS filter DXImageTransform.Microsoft.Gradient has a very specific syntaxWhat's the difference between the following CSS entries? .sample1 .sample2 If you guessed that sample2 wouldn't work AND would break all CSS following it, you would be right. Huh? Notice the space following startColorStr= in sample2? How does one space break everything? Apparently the syntax for DXImageTransform.Microsoft.Gradient is so specific it does here. In IE all CSS following the entry stops working. In Firefox, some of the following CSS works, but isn't perfect. March 05 Trouble using SPContext.Current in an IHttpAsyncHandler based http handler?I have a http handler (ashx) that obtains content from a document library and renders a thumbnail of it, returning a jpeg stream back to the browser. Today while testing it in a deployment scenario, it was unable to get a site reference. (I have a class wrapped around the request to SPConext.Current that allows one mechanism to obtain a site reference whether running in development mode against http://localhost or in deployment mode against a site. It also handles dispose when necessary.) It took too long to figure out what was happening, but apparently what was happening is that the handler got fired asynchronously and the SPContext could not obtain a reference to the current site. In this case my class tells it to go after the root site http://localhost, which on my deployment site didn't exist either. I changed the class back to use IHttpHandler and it started working immediately. There must be some special way to use IHttpAsyncHandler and still be able to use SPContext.Current. I suspect it is possible to get a site reference through a specified URL, but that wouldn't work in my case. I'd prefer to use the async call, but in this case I can't seem to. Perhaps it would be possible to pass in the current site context as a parameter in the BeginProcessRequest... This is one of those back burner projects to figure out... March 03 Internet Explorer Developer Toolbar not working?I had a problem today trying to get the Internet Explorer Developer Toolbar working in my virtual PC. I could get the toolbar button to appear in the toolbar, but clicking on it did nothing. I did the usual search and tried a few things related to other plug-ins, but couldn't get it working. A co-worker pointed me in the right direction: The Internet Explorer Enhanced Security Configuration Un-checking this option and restarting IE got the toolbar working. February 26 Going back in time - Converting a VS2008 csproj to VS2005I had the need to migrate an Ajax project created in VS2008 consisting of several class libraries back into a larger project created and built with VS2005. I'm not ready to convert that project into VS2008 just yet. I preferred to just convert the csproj files back to VS2005 format and add them to the existing VS2005 project. I discovered a few easy steps that can allow you to do this. Note: I had already converted (most) of the project files to use .NET 2.0. If you are using Ajax extensions you will have to make your web.config align with this as well. Do this first in VS2008. Obviously if you are using any .NET 3.0 or .NET 3.5 features, this isn't going to work for you... Next open the csproj file you want to change in Notepad. Near the top is the Project node. If this contains ToolsVersion="3.5" remove this attribute: <Project ToolsVersion="3.5" DefaultTargets=... becomes <Project DefaultTargets=... A few lines down there is a <ProductVersion> node, change the value: <ProductVersion>9.0.21022</ProductVersion> becomes <ProductVersion>8.0.50727</ProductVersion> Near the bottom of the file, look for the <Import node, if it says MSBuildToolsPath, change "Tools" to "Bin" it: <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> becomes <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> If there is another <Import node with an MSBuildExtensionsPath, delete this entire line. Save the file and you should then be able to to open the file in VS2005. Don't double click on the file if you have both versions of Visual Studio installed, you will likely get the default VS2008 to load it. February 12 Weird asmx web service assembly requirement in SharePointI was hit buy this problem again today and after going down the wrong road for too long, I (re)discovered the simple solution. I really don't understand why this is necessary but, when creating an asmx web service that lives under the _Layouts folder (a custom application page really), it is necessary to add an @assembly reference to the .asmx file. This isn't necessary when running in development or under plain old IIS. Note the .asmx sample file below: <%@ WebService Language="C#" CodeBehind="EDVInfo.asmx.cs" Class="MyApp.EDVInfo" %> This generates the following SharePoint error when you try to access the web service definition page:
Adding one line, a reference to the assembly allows the web service to load the asmx and allow it to function. See the addition of the assembly name below: <%@ Assembly Name="MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0000000000000000" %> I came across this trying to get an Ajax 1.0 project running in SharePoint. After tracing the traffic with Fiddler, I could see the asmx/jsdebug calls were failing. returning the same error above. It took me a while to recall this was a standard web service assembly resolution error and not something unique to my Ajax installation on SharePoint. This applies to http handlers as well (.ashx) February 01 Sliced bread is now obsoleteTed Pattison and friends have made an awesome utility available for free on codeplex.com. Not only does it make the creation of SharePoint development projects extremely easy, it encapsulates the best practices for organizing development projects related to SharePoint, provides shortcuts for common development and deployment activities and more. I wish I had this utility a year ago! Visit the codeplex project here: http://www.codeplex.com/stsdev Be sure to watch the screencasts on the releases page to get you up and running. January 18 Javascript using DOM element property hasChildNodesHere's one that surprised me this morning. I was using this syntax a few times attempting to prevent entering a block if the div has no children: // incorrect While debugging I discovered that if you use hasChildNodes without the parentheses, you actually get the function returned, not the boolean value you were expecting, which ends up being evaluated as true, entering the block you did not want to enter. Below is the correct syntax: // correct The more I use Javascript object notation the more it feels like C# and you tend to forget you are not working in type-safe world... I noticed the MS Ajax library has some method to perform type checks on your own function parameters but I miss having it happen everywhere... Lesson learned. January 16 My 3 Favorite Web Dev ToolsI've been doing quite a bit of Ajax and Web UI work the past few weeks and the following tools have proved invaluable. 1. Visual Studio 2008 If you are doing anything with JavaScript, stop everything and install this. This is the development environment to be using for this work. The new debugging features, intellisense and built in Ajax toolkit are tremendously helpful. 2. Fiddler If you ever need to inspect what is crossing the wire, you need fiddler. It will expose everything you need to know about your browser/server communication. See one of my prior posts if you need to watch localhost traffic. www.fiddlertool.com. 3. Internet Explorer Development Toolbar I didn't even know about this until 2 days ago when a co-worker suggested it. We were looking for some kind of tool to inspect the browser DOM as it existed in real time (as opposed to view source.) I wish I had found this a couple years ago, it would have saved me from many "alert" iterations to figure out what was happening in the DOM.
January 08 Fiddler / localhost / VistaHere's an update on the prior fiddler tip if you are using Vista. I couldn't get Fiddler to capture my localhost traffic, even with the period trick on my Vista notebook. Uncheck the IPv6 option in Fiddler and it will work. Below is the link to the site with the answer: January 04 Using Fiddler on localhost
I've taken a short break from hard-core SharePoint over the holidays and have been experimenting with the Microsoft AJAX Library recently, particularly the Scripting library and Scripting Services - pretty cool stuff. I had a need to watch some of the traffic from my test page so naturally I turned to Fiddler (www.fiddlertool.com) but noticed it didn't show traffic from the local ASP.NET Development Server on localhost:portnumber. A quick Google found a couple tips:
December 16 Updated Best Practice DocumentsThe documentation on MSDN has been recently updated with some significant new documentation. http://blogs.msdn.com/sharepointdeveloperdocs/archive/2007/12/11/SharePointSDKsLiveForSP1.aspx One area with new material is some of the best practices documents, especially dealing with disposing of the Site and Web objects. I discovered I was not handling disposal correctly in one instance that required a page redirection. (Thanks to Andrew Connell for directing me to this http://andrewconnell.com/blog/archive/2007/12/15/Both-SharePoint-v3-WSS-v3-and-MOSS-2007-SDKs-have.aspx) There have been other areas updated, including some new documentation (finally) on the external storage mechanism (EBS) available in SharePoint. (Which sounds quite challenging to implement successfully) External Storing of Binary Large Objects (BLOBs) in Windows SharePoint Services November 12 SPQuery with non text fields (Boolean and DateTime)This isn't anything really new or unique but seemed worth bloging to have it one in place. If you want to query on a non-text field such as a Yes/No field (boolean) your query CAML might look like the following: StringBuilder sbQuery = new StringBuilder(); Note the value for the boolean expressed as text. 1 for true, 0 for false. I had a need to query on a DateTime field and locate records that had been updated in the last 15 minutes. It appears the query will not operate using the time portion of the DateTime. It only appears to compare the Date portion. I ended up removing the DateTime from the query and checking each row of the result. It turned out to be ok because I had to access each row anyway and either clear a field or perform some process on the row depending on whether the time stamp was inside a 15 minute window. Here's a link that discusses using DateTime in a CAML query if you go that route: http://net.bloggix.com/PermaLink,guid,d273feb7-bc14-460d-85e1-863cb6db6016.aspx October 26 docSTAR Eclipse ReleasedThis has been my daily life for the past 6-9 months or more... We finally wrapped up and release our first version of docSTAR Eclipse, our newest document imaging/document management offering built upon SharePoint. You can read more about it here: <commercial> It has been an interesting ride going from 0-60 on SharePoint about a year ago and then staying in the passing lane with the pedal to the floor. Our small team has learned a lot about SharePoint during that time and I've shared some of the "challenges" here and at local gatherings. Thanks to all who have offered suggestions and encouragement along the way. FullTextSQLQuery - Keyword search of just documents on one siteI was researching a problem with our search mechanism, which would not return results for certain keywords. It ended up that the number of results being returned for all sites was hitting the RowLimit before the result I wanted appeared. I needed some better filtering. Along the way I discovered a couple tips, one of which appears to be undocumented, to help restrict a search to only documents in a library and only on a given site collection. (I'm also using forms authentication.) I created the test.aspx page (shown below) to diagnose a search problem and to experiment with search results on a live server without having to build/deploy. Just place it under C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS (or inside another sub folder.) Note the IsDocument=1 in the query text. This will restrict this search to only return documents in the results, not the other pages that get indexed, such as: http://xx.xx.xx.xx/My Documents/Forms/DispForm.aspx?ID=29 You can also filter the results to just the site you are currently searching (assuming you want to). If the current user has rights to other sites, those results would be returned as well unless you include the SITE= clause. SearchTest.aspx: <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> SPSite sitecol = SPContext.Current.Site; // create a new full text query FullTextSqlQuery ftQuery = new FullTextSqlQuery(sitecol); ftQuery.ResultTypes |= ResultType.RelevantResults; ResultTableCollection resultTables = ftQuery.Execute(); Response.Write("<br />" + "Site Collection: " + sitecol.Url.ToString() + "<br />");
while (true == resultTable.Read()) Response.Write(columnValue.ToString() + "<br />"); } %></div> The IsDocument=1 tip (which does not appear in the WSS SDK documentation) comes from this question: http://www.developermania.com/newsgroups/item/316475/FullTextSqlQuery_contains_problem.aspx I don't recall where I saw the SITE= being used (sorry.) September 21 WSS 3.0 Search Capabilities - Out of the boxIt has been hard to find information that really describes what does and what does not get indexed, for WSS 3.0. I created the following table from experimentation. The Title and other fields refers to the document name, for example "mydoc.doc", as well as other site columns added to a content type. I didn't test columns added directly to a list, but I'm assuming they would work the same as site columns.
The following Wrox book excerpt has some background information regarding search: This chart refers only to out of the box capabilities. It is possible to install and configure other IFilters, for example to index PDF. For more info on IFilters see www.ifilter.org or www.ifiltershop.com August 24 Fusion Log ViewerI came across an interesting utility while trying to debug a custom login page issue today. I am trying to have a custom login page that is used when my site is hit using forms authentication and multiple sites, for example http://vpc1/sites/site1/_layouts/myapp/main.aspx The web.config in my .../layouts/myapp points to my login page, but it doesn't appear to be used, when I load my I get only the SharePoint login page. At this point I'm thinking something isn't loading in my page, which is failing back to use SharePoint's login page. The fuslogvw.exe shows the binding work that goes on when IIS loads your page, resolves assemblies, etc. This page has some great information and links: http://www.developerfusion.co.uk/show/6753/ Here's an example of the log utility in use. It's showing me that SharePoint is loading and using its own login.aspx and not mine: *** Assembly Binder Log Entry (8/24/2007 @ 9:38:38 AM) *** The operation was successful. Assembly manager loaded from: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll === Pre-bind state information === August 09 List item event handler: ItemDeleted - Is it useless?I'm not sure what the ItemDeleted event handler is useful for. It doesn't appear that you can get any useful information from the properties object, such as identifying about the item that was deleted. I had a need to perform some cleanup on a separate list when a document was deleted from a library, however I was unable to find any way to identify the document that was just deleted inside this event. The ListItem property of the properties was null. There is a ListItemID, but this appears to point to the item that was just deleted. In fact, the ListItem property does a GetItemById lookup (under the hood) on the ListItemId. And guess what, the item isn't found because it was deleted. I wanted to get the ListItem that was deleted, or at least it's UniqueId so I could perform some cleanup but I ended up doing the cleanup in the ItemDeleting event instead. This is potentially problematic because some other handler could be added and it could perform a cancel in the ItemDeleting event, avoiding the deletion on the item. August 07 Debugging Feature Receiver Event HandlerI've got a feature that installs a couple event handlers on a document library. I'm catching ItemUpdated and added the ItemDeleted. I was trying to use the ListItem property of the properties object, and discovered you can't (see next blog entry). This was rather difficult to debug from inside an event handler. I tried writing to the event log, which worked but was cumbersome. Then I found I could use Trace.Write from the System.Diagnostics namespace and use a separate utility called DebugView to view these trace messages (see link below). For example: using System.Diagnostics; ...
I would imagine it is also possible to somehow connect the debugger to the process running the event handler, but the trace command provided the information I needed and allowed me to get it working in short time. DebugView utility: http://www.microsoft.com/technet/sysinternals/utilities/debugview.mspx --------------------------------------------------------------------------------------------------------------------------------------------------- Unrelated but interesting: During the above investigation, I looked at the Sharepoint logs and found this: That's interesting, adding a key to the registry can provide more information about where leaks might be coming from. Hmmm... July 11 Control The CrawlHere's the answer to something I have been seeking for some time. How can you trigger a full crawl on the search engine: Start or stop a full crawl To start a full crawl of the content, use the following syntax: Stsadm -o spsearch -action fullcrawlstart To stop a full crawl of the content, use the following syntax: Stsadm -o spsearch -action fullcrawlstop This is from the technet docs July 03 Best Practices Follow-upHere's a page with a good explanation of the need to dispose your site and web objects (when you open them) and a demonstration of the effects of not following this pattern. http://blogs.msdn.com/jannemattila/archive/2007/06/29/free-the-spweb.aspx June 18 Forms Authentication, SharePoint, and the Event LogHere's an interesting issue, that makes sense once I finally figured out what was going on. I'm using the Microsoft Enterprise Library to handle caching, logging and exception handling. (Was first using version 2.0 and over the course of this issue upgraded to 3.1) Everything was working ju | ||||||||||||||||||||||||||||||||||||||||||||