Through some email conversations I’ve got a bit more detail on those pesky created and modified fields. You can set them when you’re adding a new record — and the values hold. However, it doesn’t appear that you can set them on an update… I love wandering around the depths of uncharted (undocumented) SharePoint.
One of the frustrating things about SharePoint 2003 is that the developer documentation is still a bit weak. The way that we see the impact of this is that well meaning folks end up accidentally saying that something is or isn’t supported. I’m quite guilty of it myself — although thankfully I’ve not written down any of these errors that I know of yet.
Bil Simser was noodling on the idea of updating the created and modified fields in a list and mentioned that they’re read only. (ListFormWebPart and Tzuanmi SharePoint Designer). The interesting thing is that I’ve updated these fields in a list. I did it for some technology POC code I was generating around copying list data from one list to another. I didn’t even pay attention to the read only field and I got the results I wanted. I copied the Created By, Created (date), Modified By, and Modified (date) fields.
This wouldn’t be so interesting except Adam Macaulay from CorasWorks and I had a similar discussion on the fields not two weeks ago. Their Data Migrator tool (a great tool by the way) didn’t preserve Created/Modified dates. So, I forwarded him along my POC code so hopefully he’ll be able to figure out why they initially had problems with getting the Created/Modified dates to copy from one list to another.
I wonder how many other things about SharePoint that we collectively have wrong.
I’ve mentioned through the last few posts that I’m working on another custom site definition and that I’m wandering through SCHEMA.XML definitions. Well, one of the things that I decided to do since making changes to Schema definition file is so monotonous is to automate the addition or removal of web parts in all of the appropriate schema.xml files within a site definition.
So I have yet another tool… SPSiteDefUpd — it updates site definitions to add, remove, or enumerate web parts in the various schema.xml files for the list definitions under a site definition. It has a few limitations …
- Right now it only processes the List defintions, it won’t automatically update your ONET.XML file to — that would be handy if you’re adding something like a global header or footer. (but modifing the ONET is substantially quicker than hitting all of the schema.xml files.
- It does removal by title so if you have two web parts with the same name .. it will remove one of them but which one it will remove is a mystery. (Actually, it’s not, it will remove the first one listed in the Schema.xml file.)
- It won’t touch the ListForm or ListView web parts — this is in no small part due to the fact that they don’t actually show up in the web parts section.
OK, now that you know what it won’t do, here’s what it does do:
- Processes every file for the list definition. This includes both views and forms.
- Processes every list definition — you tell it where the site definition is and it will, if you want, go through and do replacements for every list definition — or for only one if you prefer.
- Adds new web parts — it reads the web part zone and web part order to put in the AllUsersWebPart attributes.
- Adds the WebParts node to the XML if it doesn’t exist.
- Enumerates all web parts on every page in every list definition or any subset that you prefer.
- Removes web parts from the site definition by title.
- Consolidates write operations if multiple sections of the file are changed to improve performance.
I think it will be very handy as I work on new site definitions and want to do a quick add of my global header, footer, and navigation. It will be trivial to get these pushed through all of the pages now. It will also be good since I will be able to allow clients to create their own new site definitions based on a site definition that I leave with them.
If anyone else is interested in trying the tool out let me know via feedback or comment, I’ll be looking for a few beta testers by the end of the week. (That will give me time to write the documentation and do a bit more testing.)
At the client I’m at we’re doing some customization of the SCHEMA.XML files for the list templates. Basically, we’re adding some web parts into the pages since our header, footer, and navigation is driven from web parts. I was over with one of the developers and noticed he was looking at the SCHEMA.XML as a text file. When I asked why he showed me, VS.2003 wasn’t able to show a XML view.
So I fired up my copy of Stylus Studio (which tells me why something isn’t valid XML in addition to just blowing up.)… I found that there were a few lines in the schema.xml which look like they were “continued.” They had an exclamation point and a carriage return at the 990th position on a line. I’ve checked through the other SCHEMA.XML files and can’t find the character … so I don’t know how it got there, but if you run into a schema.xml that won’t load, perhaps some utility has decided to add a line continuation character…
STSADM in addition to being a swiss army knife of useful little functions is also one of the most frequently used tools in SharePoint deployments. Being the gatekeeper to easy web part deployment has it’s advantages. However, there are limitations that it has and features that it hasn’t implemented. That’s where one of my latest projects comes in.
First, STSADM is very dependent upon access to the SharePoint content database. If you don’t have enough access the tool doesn’t work. This can be worked around, however, in many environments it represents a barrier to easily using STSADM.
Second, although STSADM allows you to add and remove web parts as trusted assemblies on the server — and deploy default property sets (read as “DWP files“) it does not allow you to add or remove web parts from a web part page from the command line.
However, I’ve been working on a tool the “SharePoint Web Part Administrator” (SPWPADM) that solves both of these two limitations. First, it is entirely based on the web service interface to SharePoint. You can run it from your desk, from the server, or anywhere that you can access the SharePoint built-in web services. Second, it’s exclusive function is to manage web parts on web part pages.
It allows you to enumerate the web parts on a page, add new web parts to a page, delete web parts from a page, export web parts from a page, and even to delete closed web parts on a page. Of all of those, perhaps only the last function needs any explanation…
When people “delete” a web part from SharePoint they’re often times just closing it — suppressing the display. The code is actually still running it’s just that people don’t see the results on the page. That’s really not all that great if you’re doing extensive computations to come up with content that will never be displayed. However, the only way to delete a web part is to enter design mode to delete it. The result is most people close web parts without realizing the impact on their server.
The SPWPADM tool will hunt down these closed web parts and actually delete them for you so they’re no longer running.
So, there are two questions you might ask… 1) “Why did you write the tool?” — The primary reason is because I’m working on an article for DevX.com on how to replace the edit control (ListFormWebPart) for a list. To do that you have to add a new web part to the list pages and remove the existing web part. It’s possible to do but certainly kludgy. So I thought the tool would be a nice thing to offer folks as a trial with the article. It’s turned into slightly more than that as I realized other purposes for it, but at heart it’s designed to facilitate management of a web part page from the command line.
2) “So what is it useful for?” — Thus far I’ve used it for two things… First, deleting closed web parts. You would be amazed at how many of them there are in a typical SharePoint implementation. Second, helping to configure site definitions while building/testing them. When I build a site definition I typically have a page that is composed entirely of web part zones. I don’t have a header, I don’t have a footer, nor menus, nor other parts of the page, those functions are represented by web part zones and by web parts. (Yes, I know this is slightly wasteful from a configuration storage perspective — it does, however, make staying supported while making changes much easier.) So I typically make 20 copies of my default page so I can drop in other content as needed. That means adding half a dozen web parts to each page (header, footer, search, global navigation, site navigation, etc.) So I make a batch file that calls the add web part command for each web part. I nest this in a batch file in one that calls it once for each page. It takes a while but eventually the controls are all placed on every page.
So why am I bringing this up? Well, two reasons, I’m ready to let a few people try it out (send me an email and I’ll send you a copy of it along with a license.) Second, I got someone asking about how to lock web parts in place for 50 or so sales guys on a discussion list I watch. It occurred to me it’s possible to put this in a script that runs every night and deletes and then readds the web parts — the net effect of which is forcing them to be on a page since changes, or removal will be removed each day. Not pretty but an idea that would be easy and effective.
So if you’re interested, drop me a line and I’ll get you a beta/trial copy.
I needed to do some simple how-to documents for some developers I’m working with so I thought I would share with everyone these step-by-step guides for doing some SharePoint (and .NET) fundamentals.
- How to Strong Name an Assembly
- How to Strong Name a Web Part
- How to Create a Deployment CAB Project
- How to Copy a Web Part
I hope they’re helpful.
Perhaps it’s because it’s late while I’m writing this … perhaps I’ve missed some big revolution in software development but I don’t understand…
Why do we need code snipit tools? Shouldn’t we have classes and methods (even if they’re static) rather than fancy tools to do the same copy-paste routine we’ve been telling developers not to do for 30 years?
Why can’t we all make an effort to put our code in reusable “chunks”?
This how to describes the process for copying a web part.
- Open a SharePoint site.
- Make sure you’re in Shared Mode.
- Enter design mode
- On the web part to copy, click the down arrow on the right and select export.
- Save the file on your system
- Go to the site where you want the control added
- Enter Shared Mode
- Select Add Web Parts-Import
- Browse to the file and click import
- Drop the web part on the page.
You’ve now copied a web part from one web page to another. Note that this won’t work for ListViewWebParts or ListFormWebParts.
Strong Naming web parts helps to make sure that they can not be tampered with – just like signing any .NET assembly does. However, because of the nature of SharePoint, there are a few additional steps that are required after the assembly is strong named to ensure that the web part can be deployed and correctly loaded.
The process involves two major steps: Strong Naming the Assembly, Changing the DWP file(s).
Strong Naming the Assembly
Strong naming the assembly is covered in a separate document. Signing the web part assembly itself is no different than any other .NET assembly. See How to Strong Name an Assembly
Changing the DWP File(s)
The DWP file that Visual Studio creates uses the name of the assembly without a strong name. The fully identified assembly name must be used to load all strong named assemblies, so if the DWP file is not modified it will fail to load the assembly – and you’ll get an error message that the control is not marked as safe.
The quickest way to get the correct assembly definition in the DWP file is to use GACUtil – which installs the DLL into the GAC. The process for getting the full assembly name and adding it into the DWP appears below:
- Open a command prompt and navigate to the project’s bin\debug directory.
- Type GACUTIL /I MyAssembly.dll where MyAssembly.DLL is the name of the assembly for the project. You’ll see a message that the Assembly was successfully added to the cache.
- Type GACUTIL /u MyAssembly where MyAssembly is the name of the assembly for the project – without the DLL extension. You will see a set of messages which show the full name of the assembly including it’s publickeytoken.
- Copy the Uninstalled line, including any additional information that appears on the next line to the clip board.
- Go to Visual Studio and open the DWP file.
- Paste the copied text between the and tags replacing what was there.