The Musings and Findings of Software Consultant David Klein (Sydney, Australia)
Thursday, 14 February 2008
ASP.NET double-postback bug strikes again!
THE BUG:
An example of this bug is detailed here:
http://www.velocityreviews.com/forums/t119525-repost-gridview-imagebutton-causes-double-postback.html
It is also detailed here:
http://www.dotnetspider.com/qa/Question8706.aspx
The issue occurs if you have any image tags rendered by your controls which have an empty source. As soon as the browser hits that <img src=""/> tag it does a refresh of the page. The main problem with this double postback is that the second run is NOT a postback - the Page.IsPostBack property is false - but I still have all my viewstate values. This issue is incredibly frustrating as the natural inclination is to look at controls causing partial postbacks - but you'd be looking in the wrong place. I had this issue in IE 6,7 and Firefox 2.
When I have some spare time, I'll look into how the problem occurs with Lutz Roeder's handy Reflector and find out who to tell to fix this reocurring issue :o)
THE FIX:
To stop the double post-backs, just make sure all your ASP.NET controls (Image Buttons, Image Columns in grids, normal Images), all have a src attribute filled in - or otherwise, make them invisible. Otherwise, you will have phantom postbacks coming to haunt you when you least need it!
Monday, 11 February 2008
Visual Studio 2008 Freezing Problem fixed!
See http://weblogs.asp.net/scottgu/archive/2008/02/08/vs-2008-web-development-hot-fix-roll-up-available.aspx for the hotfix and download details. Thanks to Scott Guthrie and his team. Bring on the MVC framework & VS2008 SP1!
Tuesday, 5 February 2008
Rehash: Dave's simple SQL Workbench/Query Analyzer Code Generator
Here is one I just made today to avoid having to create a CodeSmith template (which we don't have licences for) or doing the monkey work of manually typing in these attributes. Just set the output mode in isqlw/SQL Workbench to text and generate away! (minus the chimps..)
SELECT
'[EntityPropertyMapping("' + column_name + '")]' + CHAR(10) +
'public ' + CASE data_type
WHEN 'nvarchar' THEN 'string'
WHEN 'int' THEN 'int'
WHEN 'datetime' THEN 'DateTime'
END
+ ' ' + column_name + ' { get; set; }' + CHAR(10) + CHAR(10)
FROM information_schema.columns
WHERE table_name = 'Asset'
Output is:
[EntityPropertyMapping("AssetName")]
public string AssetName { get; set; }
[EntityPropertyMapping("Description")]
public string Description { get; set; }
[EntityPropertyMapping("Comments")]
public string Comments { get; set; }
Fixing the Compile-Time Exception "'MethodName' is is not supported by the language"
Today I got a few cryptic errors when trying to compile a project in which I had updated some referenced dlls:
Error 2 'GetImages' is not supported by the language D:\DataSourceControl\Global\ddkonline.IM\dev\ddkonline.InvestmentManagement\CodeBase\Modules\AssetMaintenance\Services\AssetService.cs 301 55 AssetMaintenance (Modules\AssetMaintenance\AssetMaintenance)
At first glance, this error doesn't make sense. Did they remove a feature of the language when I wasn't looking :o). The cause and solution of this problem is simple. At Lend Lease, we have a common .NET framework that all projects reference by dll. I updated the reference Dlls for some of the projects - but not the whole set. When you update a dll that other referenced dlls depend on, you will get the cryptic error above (reminds me of binary/project compatability problems in the non-.NET days!). To fix, just get the current version of all related dlls.
This fix didn't help me much though, as I needed features from 2 separate branches of the same project - BOTH the old version of the dlls (which had updates to the Business objects) the new version of the dlls (which had updates to the Sharepoint Integration components). Looks like I've got some subversion merging to do :o)
Sunday, 3 February 2008
Downloading YouTube videos via Google Cache
e.g. to download the number 1 video on Google at the moment ( a Russel Peters comedy clip) , you can enter:
http://cache.googlevideo.com/get_video?video_id=24Ryj1ywoqw&origin=youtube.com
Note that the cache only works for videos uploaded after YouTube was acquired by Google.
Alternatively, you can go to http://keepvid.com/ - which handles many other sites as well.
Thanks again Google! :o)
Wednesday, 30 January 2008
Uploading Files to MOSS 2007 via the Copy.asmx Web Service
You can upload files into your Sharepoint repository in one hit along with metadata (ie custom column information and values). You just have to Reference the SharepointSite/_vti_bin/copy.asmx (e.g. http://dev-moss/sites/home/PropertySharePoint/_vti_bin/copy.asmx) to get access to the Copy.CopyIntoItems() method. You then simply pass in the stream and Array of FileInfo objects (which have your metadata) into this method. I have seen several examples around that use the Http PUT method (e.g. http://www.sharepointblogs.com/ssa/archive/2006/11/30/wsuploadservice-web-service-for-uploading-documents-into-sharepoint.aspx)and and then grab the file back and update it with the meta data. My code sample below shows a much simpler way. I have not seen this technique is some of the larger Development guides such as SAMs MOSS 2007 Development Unleashed - they only give a passing mention to the copy service. MSDN also brushes over this service - http://msdn2.microsoft.com/en-us/copy.copy.copyintoitems.aspx
/// <summary>
///
/// </summary>
/// <param name="listName"></param>
/// <param name="destinationfolderPath"></param>
/// <param name="sourceFileSteam"></param>
/// <param name="fileName"></param>
/// <param name="fields"></param>
/// <returns>String with the destination Uri</returns>
public uint UploadFile(string listName, string destinationfolderPath, Stream sourceFileSteam, string fileName, SharepointCopyProxy.FieldInformation[] fields )
{
//Create folder if it doesn't exist
CreateFolder(listName, destinationfolderPath);
byte[] fileBytes = new byte[sourceFileSteam.Length];
sourceFileSteam.Read(fileBytes, 0, (int)sourceFileSteam.Length);
string[] destinationUri = {string.Format("{0}/{1}/{2}/{3}",_urlSiteRoot, listName, destinationfolderPath, fileName)}; //This may have issues as the listname may be different to the full path - may need to get value from folder path
SharepointCopyProxy.CopyResult[] result;
uint documentId = _copyWebService.CopyIntoItems("http://null", destinationUri, fields, fileBytes, out result);
if (result[0].ErrorMessage != null)
{
throw new System.ApplicationException("An error occurred uploading the file to Sharepoint.", new System.Exception(result[0].ErrorMessage));
}
return documentId;
}
Thursday, 17 January 2008
The simplest way to upload documents and files to MOSS with the ASP.NET System.Net.WebClient class
//e.g. destinationFullURI = "http://dev-moss/sites/home/PropertySharePoint/DocumentLibrary/0/tmp167.tmp"
//sourceFullPath = "c:\\temp\myfiletoupload.tmp"
WebClient webClient = new WebClient();
webClient.Credentials = _credential;
webClient.UploadFile(destinationFullURI, "PUT", sourceFullPath);
Make sure you include the "PUT" method so it doesn't attempt an HTTP post (which is the default behaviour).
Tuesday, 15 January 2008
MOSS - Getting items in a particular subfolder of a Picture Library via Sharepoint Web Service
http://[server]/[site]/_vti_bin/imaging.asmx.
An excellent chapter on this web service can be found in Sams Microsoft SharePoint 2007 Development Unleashed
[/UPDATE 2007/01/16]
It appears that you cannot filter a Picture Library by Folders using the QueryOptions parameter for .GetListItems(). I consider this to be a bug in the MOSS Web Service querying engine.
You can download a very handy tool from here to demonstrate the issue easily http://www.u2u.info/Blogs/karine/Lists/Posts/Post.aspx?List=d35935e0%2D8c0e%2D4176%2Da7e8%2D2ee90b3c8e5a&ID=12
To reproduce the bug:
- Make a photo library with 2 subfolders
- Make a normal document library with 2 subfolders
- Adding several photos to this photo library
- Adding several photos to the document library
- Opening up the tool, right-clicking on your list and selecting "GetItems" from the context menu
- Go to the View Options tab and entering your document path (e.g. MyListName/MySubfolderName)
- You will get the whole list from the picture library regardless of this parameter..... BUG!
- Try the same thing on the document library - and the Folder option works as expected.
FIGURE: The filter not working properly on Photo Library (returns whole list including folders) when a subfolder is specified in the filter.
FIGURE: The filter working correctly on Document Library as expected (returns subset of data)
In particular, this CAML will not work on a Photo Library where my List Name is 'PhotoLibrary' and my subfolder is '1':
<Query />
<ViewFields />
<QueryOptions>
<Folder>PhotoLibrary/1</Folder>
</QueryOptions>