Fear and Loathing
Gonzo blogging from the Annie Leibovitz of the software development world.
-
A new toy
Been a pretty busy week and here in Canada we have a long weekend (still can't remember what we get the day off for but hey, who's to argue). I picked up a Compaq Presario R4000 yesterday in light of needed something to take with me to PDC and the MVP Summit coming up in September. I was originally going to get a different model but this one just looked that much better. The Athlon 64 processor and an ATI Radeon XPRESS 200M graphics card just blows away the lightweight Centrinos IMHO. It's a great machine for development as well as presentations so I'll be blogging like a madman with it down at PDC (and getting my kicks with a few rounds of Unreal Tournament 2005). Anyways, back to the grind...
-
AddFieldAsXml... I wish this monkey would go away
Oh the horror of it all. You would think that XML is XML is XML. For whatever reason unknown to mankind, the order of CAML (and what combinations go with what) just don't add up. Some things make sense (like allowing multiple values for text fields doesn't make sense) but the order? I still have to wonder if Microsoft is using ordinal values to extract attributes from the schema as all I've done is moved an attribute to the front of the CAML statement instead of the end and BOOM! I've given up on any kind of validation tool for CAML right now because the permutations of what works and (more importantly) what doesn't is way too consuming. I am however putting together a spreadsheet with all the <Field> attributes with a cross reference against types. It goes something like this:
Attribute Attachments Boolean Choice Computed Counter etc. Aggregation No No No Yes Yes etc. AllowHyperlink No Yes Yes No No etc. You get the idea. A matrix of what attributes are valid with what types you can define for a <Field> tag in CAML. This was put together out of frustration with what attributes I should/could use for any given type. I'll publish this for anyone who's been scratching their heads on these properties as a cheat sheet of sorts when I get it completed, hopefully by the end of the week (barring any more distractions).
-
Cracking the code... err, sequence
Sorry, been reading the Da Vinci code too much lately (don't ask me how anyone could make a movie out of this, maybe with Dan Brown sitting in a chair counting his money for 2 hours?).
Anyways, as a follow-up to my AddFieldAsXml post there's a problem with this silly method that has provoked me to build a tool. On top of the issue with the whole Name vs. DisplayName thing, the Field CAML you pass it has to be in a certain order. Do not pass Go. Do not Collect $200. The kicker is that certain combinations of CAML make it throw a lovely exception that says (drumroll kids...) "An Error has occurred." Yup. No message (that is the message). No inner exception. A cryptic error number that couldn't possibly be a lookup into anything (especially since it's a negative number). No recovery. No hope.
What a PITA. So it prompted me to build a mini-SCHEMA.XML parser and validator. I'm just going through the matrix of combinations of attributes you can and can't use and what order they can (or cannot) be in to work. So the tool is just a silly desktop thingy. Paste in the <Field> CAML and it'll tell you if it's valid based on the rules I'm coming up with now. Like I said, there seem to be a never ending myriad of combinations that work but just as many that don't. It's very very odd, as if Microsquishy is looking for certain attributes based on ordinal position or something. So a few more hours of screwing around, digging through Reflector as far as I can go into the SharePoint libs and I'll have a tool for you to use. I'll leave it to someone to blow it out to a full blown SCHEMA.XML validator as I don't have the patience after todays SharePoint Episode from Hell. Back later with screenshots and source code.
-
Some days this is exactly how I feel...
And of course now I can't get this freakin' image out of my head. It's going to be playing all day long on my desktop.
-
AddFieldAsXml cannot be used to set the InternalName correctly
All fields in SharePoint lists (and doclibs which are specialized lists) have two names. An Internal Name that's used by SharePoint and the Object Model (among other things) and an Display Name which is what you see in your Browser. There are four ways you can create a new field on a list in SharePoint.
- Simply use the Web Interface and add a new column. When you add the column, the name you give it at creation time is set as both the Internal Name and the Display Name. Anytime after that when you change the name you're only changing the Display Name.
- Create a custom site definition with SCHEMA.XML. Here you can set both the Internal Name and Display Name but the user would be able (with the right privledges) to change the Display Name.
- Create a field using the AddField method of the SPFieldCollection class. Here you can only set the Display Name. The Internal Name will get autogenerated by SharePoint so you have no control over it. There are rules around what that Internal Name will be and you could write your own routine to figure that out, but that's beyond the scope of this posting.
- Create a field using the AddFieldAsXml method of the SPFieldCollection class. Here it's the same thing as the previous method but you specify the CAML for the field (same CAML as you would specify in a SCHEMA.XML file). This has the most flexiblity but also has a bug which is the point of this post.
The Problem
So you decide you're going to dynamically update a list using a snippet of CAML and make a call to the AddFieldAsXml method. Let's say your CAML looks something like this:
string newField = "<Field Type=\"Text\" "DisplayName=\"New_Field_Display_Name\" "Name=\"New_Field_Internal_Name\"/>";
myFieldCollection.AddFieldAsXml(newField);So you expect to create a field with a Display Name of "New_Field_Display_Name" and an internal name of "New_Field_Internal_Name" right? Wrong. After the method call you take a look at the field. Lo and behold, SharePoint has basically ignored your request to make the internal name "New_Field_Internal_Name" and instead set it to "New_Field_Display_Name". Blech! That's NOT what I asked for.
The Fix
The fix is a little two-step that you have to do with SharePoint to get the desired result when using the AddFieldAsXml method:
- Define your CAML so that the Internal Name you want to use is actually set as the Display Name
- Create the field with the call to AddFieldAsXml
- After the field is created, retrieve it using the internal name and set the Title property to the real Display Name you wanted it to be in the first place
So a simple little snippet to do this would be (this assumes you have some CAML and a SPFieldCollection first):
/// <summary>
/// Adds a field as XML to a SharePoint field collection. This fixes the AddFieldAsXml bug SharePoint has.
/// </summary>
/// <param name="fields">Field collection to add the new field to.</param>
private void AddFieldAsXml(SPFieldCollection fields)
{
// Declare our intent for our names here
string internalName = "New_Field_Internal_Name";
string displayName = "New_Field_Display_Name";
// Our definition for the CAML. Note that DisplayName is really our internal name here
string newField = "<Field Type=\"Text\" DisplayName=\"New_Field_Internal_Name\" Name=\"New_Field_Internal_Name\"/>";
// Call the SharePoint method to create the field.
fields.AddFieldAsXml(newField);
// Retrieve the newly created field using the internal name
SPField field = fields[internalName];
// Reset the title to the name we want it to be (after AddFieldAsXml the display name will be the internal name)
field.Title = displayName;
// Finally commit the updates to the field
field.Update();
}
Feel free to use this and update it (maybe passing in the field names or even put it into a class). Hope that helps. Many thanks to Brian on our team for coming up with a solution.
-
ReSharper for Visual Studio 2005
I'm all for blogging about blogs that blog about blogs just so I can get in a blog post. Got that? So via Roy Osherove and his blog about ReSharper, the public beta is out for you to try it with Visual Studio 2005. Roy's blog came via a post by Peter Provost. Anyways, go get the new version here. ReSharper Rocks!
Update: According to Steve Eichert he uninstalled it until a more stable version comes along. YMMV.
-
Opening Files in Their Native Programs With SharePoint
When you click on a file in a SharePoint document library, it launches the file. Most often you'll be prompted as to what you want to do with the file (Open, Save, etc.). In some cases (like Office documents) it will open the file but the program that is doing the client side work on it, renders it in the browser. How many times have you clicked on a Word document and have it launch in the browser so you're looking at IE with an embedded Word control rendering your document. Half the time the user doesn't know what happened and when they close the browser the site is gone when really they wanted to hit the Back button to get back to their doclib. How frustrating.
Unfortunately the answer isn't an easy one, at least if you have a large deployment of users you need this to happen with. It involves setting up a property with the associated file. The setting is in the web browser, not SharePoint. The technique varies based on different environments (version of browser, version of OS, version of Office) so there’s no golden rule but the default is generally to browse in the same window (at least it has been for me on all the setups I've seen) so it will open up inside of the IE when you're accessing it through your browser. This has the effect of embedding the Microsoft Word control in the browser and hence the problem. Here’s the instructions for reconfiguring the file association in XP:
- Go to Explorer (not Internet Explorer) (or My Computer)
- Under the Tools menu choose Folder Options
- Click on the File Types tab
- Find the file extension you want to modify (say DOC for Microsoft Word Document)
- Click on the Advanced Button
- In the Edit File Type deselect “Browse in same window” for the Edit or Open actions (or all of them if you prefer)
Here's a screenie of what you should see:
This will force it to launch a new (Word) window no matter where the source of the document comes from (say a doclib in a browser). I'm pretty sure there’s a blog out on this that someone wrote but can’t find it so hence this posting (feel free to link to it in the comments if someone knows of one).
Note that there are some files that doesn't work (TXT and XML files for example). For those you may use something like the example that comes with SharePad, a GotDotNet Community Project, however it will take more than a second configuring a machine to get this to work. Also if you need to deploy this, I don't know if it's something you can include in a GPO or not so check with your network guys.
-
Pumped up for PDC and still 9 weeks to go
September is going to be a busy month. I'm all pumped up for PDC and spent an hour or so screwing around on Expedia.ca getting my flights and hotel and all that jazz setup. While I was booking PDC, the MVP Global Summit was 2 weeks after it so I figured I would snag my flights for that as well. At the end it was happy pills for Bil staring at my completed itinerary for the trips. Okay, so maybe you don't get so excited booking a trip but I've been locked up on a project for the last 7 months barely seeing the light of day so taking a week to geek out in L.A. is just plain refreshing. I'm staying at the Miyako Hotel, a cool looking Japanese hotel that offers shiatsu treatment rooms among other things (and
freecomplimentary high-speed internet which is a must so I can blog madly about the events). I also decided to hang around for the Saturday after the conference so I could soak in the L.A. gang wars and whatever else is going on so if you want to hook up let me know.Fitz came back from the dead after being busy for a month or so and slams in with a note on Windows SharePoint Services and SQL Server 2005, Reading between the lines for the PDC Sessions, and a product called Longitude (which not only sounds cool but is great than we'll hopefully see some more documentation from the SPS Search team).
-
A Poor Man's Google for SharePoint
Snapped this up from one of the SharePoint mailing lists. It's a super cheap way to get a Google search on your site:
- Navigate to C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE
- Create a new folder called "external"
- Inside the folder create a single HTML page with the following contents:
<FORM method=GET action="http://www.google.com/search"
target="_blank">
<A HREF="http://www.google.com/" target="_blank">
<IMG SRC="http://www.google.com/logos/Logo_40wht.gif" border="0"
align="absmiddle"></A>
<INPUT TYPE=text name=q size=30 maxlength=255 value="">
<INPUT type=submit name=btnG VALUE="Google Search" style="font-
size:10">
</FORM> - Save the file as "google.htm"
- Next drop a Page Viewer Web Part onto your page and point it to the page you created. The url to the page will be http://servername/_layouts/external/google.htm
Simple, easy, fast, and free. No web part installations required. If you want something more sophisticated you can check out Mark Wagner's real Google Web Part (with full source code) here.
Thanks to Chris Dimarco for the information above.
-
SharePoint with Flickr
I'm getting more and more impressed with Flickr, an online photo managment system, no only with the service itself but more so what people are doing with it. Roy Osherove pointed me to a service that a photographer named kaster created. You input a line of text and spell anything you want using Flickr images. Of course I had to do the obvious:
It does stir up some ideas in my head around enhancing the photo library templates in SharePoint to be more like a Flickr type interface. Better to use from a gallery perspective and you could be able to serve up images through web services, have Web Parts feed off images (like the example above). Lots of potential. Who says SharePoint is just for documents?
Check out the Flickr mod here and start creating your own unique banners or something with it.