Archives
-
Folder taxonomy and path limitations in WSS
There's a path limitation in WSS so when you have a document library with versioning turned on, at some point previous versions of a document will vanish into the ethers of SharePoint. It only happens with past versions so your current version is fine no matter how long the path is. To test this out:
- Create a document library in a WSS site and enable versioning
- Start creating folders inside of folders inside of folders
- Upload a document and do a quick check out/check in to create 2 versions
- Select the version history for that document and view version 1 of the document
- You should get a HTTP 400 Error - Bad Request (if not, create some more folders in folders and try again)
I don't know specifically where the cutoff is but in testing (and from logic) my gut would say after 255 characters which is a typical limit (it's the PATH limit in Windows) and would make sense.
So basically the rule here is to try to stay away from a folder taxonomy to organize information. META data and custom views in document libraries is so powerful as you can have everything living in one "folder" but viewed by category (or whatever makes sense for your organization). It's a hard shift from the file centric way of thinking but you can seed the troops with some tools to get them started, spend some time training them and showing them how a slice through their data is much more informative than the "where did I put that file" approach they currently use. It's a tough sell and you'll get a lot of resistance as people are comfortable with a structured file system to do their organizing for them. In the end there are a lot of benefits to viewing your information with a slightly different twist and you'll avoid problems like the one I described above (although your mileage may vary).
-
Creating a Tabbed Interface for your WSS site
This was asked in the newsgroups about how to build a tabbed UI in a WSS site. Luckily, there's a great FrontPage component you can use for this that makes building it a breeze. First pick a site you want to add the interface to (or create a new one, doesn't matter). Next open up the default.aspx page in FrontPage 2003.
Adding the Tabs
The FrontPage component we want to use is the Interactive Button. Find a place on your page you want the tabs to appear. In this demo we'll put them under the site description. Once you have a place for it and the cursor positioned there, select Insert | Interactive Button from the menu. This will bring up a dialog box to describe the button. Pick a button that works with the design of your site. NOTE: the buttons don't follow the style of your WSS site so you should land on what theme you use up front before adding the tabs. Below I've picked "Soft Tab 6" which matches the default WSS site style pretty closely.
On the Font and Image properties you can alter the button to your hearts content. Click OK to insert the button onto your page. You should now have something like this in FrontPage:
Now select the button on the page and copy it then paste it next to each other as many times as you want a tab for (1 tab for each page). In the example below we're going to have 4 tabs going to 4 different pages.
Each tab (interative button in FP terms) represents a different page in the site. So first save the default.aspx page 3 more times as Tab1.aspx, Tab2.aspx, and Tab3.aspx (or whatever names you want). The reason why we save default.aspx is because we want to preserve all of the parts of the page. We could have created 3 Web Part Pages to hold content, but we would lose the Quick Launch bar and other properties so this just keeps things more consistent. Also you can't copy'n'paste an ASPX page in the folder view so this works for us.
Now load each page up by double clicking on it in the Folder List, select each button on each page and change the properties so that a) the Text property of the button is what you want it to be and b) the Link property points to the file you want the button to take you to. We'll call our tabs Home, Contacts, Tasks, and Documents. After creating the new pages with all the renamed buttons we should have something like this (4 tabs with 4 pages loaded up):
The FrontPage work is done so save all the files and close FP down. Now go back to the site in your browser and select each tab. This will take you to each new page you created (you can check it in the Url). Now drag and drop whatever web parts onto that page that's appropriate for your design. When your users hit the site, they'll click on each tab which will take them to the new ASPX page which contains the new lists. Because we copied the default.aspx page as our original, all the great stuff like the Quick Launch bar is there (and will be updated on all pages when you add new lists) and the tab interface looks seamless! Here's our Task and Document pages showing this off:
Additional things you can do if you want:
- Change the style of the button for the page that's currently selected (so Home for default.aspx) so people know what tab/page they're on
- Rather than making the content static, you can drop it onto a webpart and reuse it (haven't tried this but it should work)
- Create your own style that will change with the style of the website (this involves editing the HTML of the link buttons to make them use the named CSS styles of the WSS site)
- Create some more images as a border to display below the tabs to make them integrate to the site a little better
- Change the title of each tab page (in FP2003)
One note, the technique here of creating all new pages and saving it will end up creating a lot of duplicate buttons. You can take the extra time to go into the HTML code of the page and have the buttons point to the already existing button images rather than creating new ones each time the page is saved.
Additional Links
Microsoft Office Assistance - Using Interactive Buttons -
Coming soon to a user group near you... me!
I just got word that I'm now officially a member of the MSDN Canada Speakers Bureau. The Speakers Bureau is a collection of top Canadian speakers who are dedicated to delivering high quality presentation and demonstrations at MSDN events and at MSDN User Groups across Canada.
I had been accepted into the group a few weeks ago, but the machinations of the internal workings at Microsoft have finally grinded to a halt and settled now. I'm very happy to be inducted into the group which includes some people I've enjoyed listening to and have looked up to like Ryan Storgaard, Kate Gregory, and my fellow Calgary MVPer John Bristowe. I look forward to participating in the group in the coming year (and what's left of 2004) and getting out to User Groups across Canada to spread the good word (whatever that word is).
For more information on the Speakers Bureau, you can check out the link here. For a list of MSDN Canadian User Groups check out this link. Speaking of MSDN events, check out the Deep Dive on building connected systems. Each participant will get a free copy of the new Microsoft book, Enterprise Integrated Systems. Oh, come on now, you're all a flutter right? Check out the event link here for more info.
Anyways, just wanted to toot my own horn here (although I need to get them to update my profile because when I wrote it, I didn't think it was going to be used verbatim on the site and it's a very "I'm this" and "I'm that" blather) so see you on the circuit!
-
Differences with SharePoint View Styles
I was putting together a sampling of views to demonstrate the various view styles in SharePoint and came across a bit of a bug (well, an annoyance really). First just a quick rundown of the various styles you can apply in a view:
View Style is the style you set by selecting it from a list when you create or edit a view. There are 7 styles to choose from, all with different twists to how they present your list or document library. The nice thing is you can get some variations on presenting things to the user without having to resort to a DVWP. Okay, I'll admit there's not a lot of styles out-of-the-box nor are they fabulous in any way. A little variety but definately not a replacement for a custom FrontPage job.
So, without further adieu, here they are:
Basic Table
The Basic Table is pretty much like the Default style. See below for details on what's different but pretty much it renders your view in the typical SharePoint view. Columns with clickable (sortable) headers, etc.Document Details
The Document Details style is probably the most adventurous of the bunch and renders your items 2 across (no matter how wide the page is) with each item in a box. A link to the item itself and whatever columns you enable for the view along with an icon for the item and an icon for editing it.Newsletter
I couldn't quite figure out the Newsletter style at first but the only difference I found from the Basic Table or Default style is that regular text fields were bold. I still don't know why they called it Newsletter?Newsetter, no lines
Same as the Newsletter style but guess what, the lines between each row have been removed. Otherwise identical.Shaded
Shaded is like the Default style but every other row is shaded using the colour of the site, alternating between dark and light. Typical ledger type display and helps break up the monotony when you have a lot of items.Custom
The Custom style is set when you change any of the other styles like doing grouping, totaling or even adding columns. I guess it's there to just indicate that it's not stock.Default
The default is well, the default. When you create a new document library or list you get a view called All Documents (or All Items for lists). This view uses the default style.Now when you actually build a view and apply the Basic Table style you'll notice something. It looks exactly the same. Well it is, almost. The two are the same (ignoring the Guids for the views when compared side-by-side) however the Default style throws two copies of this snippet of code in:
<SCRIPT LANGUAGE="VBSCRIPT">
On Error Resume Next
Set NewDocumentButton = CreateObject("SharePoint.OpenDocuments.2")
If (IsObject(NewDocumentButton)) Then
fNewDoc2 = true
Else
Set NewDocumentButton = CreateObject("SharePoint.OpenDocuments.1")
End If
fNewDoc = IsObject(NewDocumentButton)
</SCRIPT>This VBScript is for rendering the correct button on a toolbar. The Default style puts the code in twice but the Basic Table only puts it in once. No biggie and it's not needed so I would classify it as a bug, but maybe I'm just difficult that way.
Anyways, hope that explains some things about the views and what the differences (and similarities) are.
-
DataGrids, Custom columns and Paging
I had a co-worker who presented a problem today. It was around adding paging to a datagrid (grrr Microsoft for making us do all the work!) and the fact that he had added what looked right, but the grid wasn't rendering on the page change. I went through the typical scenario of setting up paging by adding the Page Index Change event handler then, nothing. Something wasn't right and I surmised that the problem was that he had gone through a few iterations of getting the paging going and taking various approaches (hand coding the event handler, adding it to the web.config, etc.) so my conclusion was that the DataGrid, the code behind, and the aspx page were out of whack somehow. I wasn't happy suggesting the "black magic" approach to rebuilding the DataGrid with a duplicate one on the page (or creating it from scratch again) just because there had to be an easier solution.
Tonight I built a small spike project to test out what was happening. A couple of people have experienced pain and suffering in the past with the DataGrid and how events would just vanish and not fire. One thing I noted in his code was that he had a DataGrid on the page but was then building columns on the fly (to do some custom work with the columns and linking them to subsequent pages). Once I had my spike project up and running, I turned off the auto-generated columns and fed it the datasource (a quick object with a few public properties). Everything was still fine. The problem arose when I added this:
BoundColumn datagridcol =
new BoundColumn();
datagridcol.HeaderText = "ID";
datagridcol.DataField = "Id";
DataGrid1.Columns.Add(datagridcol);I've used this method before but usually when I created a DataGrid completely from scratch and added it to the page controls manually. In my spike project after adding this code, the DataGrid vanished completely. So the question here is this a supported design? Building columns on the fly with a DataGrid control already on the page? Or is this a hybrid that isn't supported (or recommended)? Another interesting thing to note. I now can't get to my event handlers in the Property tab in Visual Studio anymore. The lightning bolt just isn't there now. Hmmm.
Update:
I did find a bit of a solution. I added the following to the DataGrid in the aspx page to fix it:<Columns>
<asp:BoundColumn Visible=False></asp:BoundColumn>
</Columns>Now the paging works and everything shows up.
-
Using localhost for organizing your work
I'm just wondering what people are doing to keep track of their work these days. Sure, Outlook has a good set of tools for this. Calendar, Task list, etc. but information is still disparate and I'm jumping all over the place each time I do something. Doing web development means that we have IIS (or Apache if that's your thing) at our disposal which can serve up your own local work center. With .NET installed, the possibilities are even more plentiful. So rather than having Yahoo or MSN set as my homepage I would use http://localhost and put my collection of links, tasks, documents and other useful tidbits there in some kind of organized fashion. Each time I fired up my browser I could track what I was doing or have a categorized view of resources that I use on a regular basis. I found it was somewhat more effective than using static IE bookmarks and saw it as a next generation PIM, as those have all but vanished from the desktop.
I've grown a little dissatisfied with having a static webpage that I was constantly editing so I looked for an alternative. SharePoint, while having a good collection of features for this, was out becuase it meant I had to run it on my server and I wanted something local (and simpler). After poking around on the web, I thought the current version of DotNetNuke would be a good choice. It's been kicking around for quite sometime, was built on .NET (grown up from the IBuySpy Portal Starter Kit that Microsoft created to show people what was possible with .NET) and the latest version is pretty slick. Lots of free add-ons, private assemblies mean I just upload a zip file and it's available as a new module so no messing with compiling or messy configurations and I can make the content as dynamic as I want it to be. I've been using that for a few days now and it's pretty darn effective. I use it for tracking a list of ongoing projects and tasks, a large collection of categorized links, a document manager, a photo album and there's even an MP3 player,.all organized on tabs (with my main page calling up the Daily Dilbert as you just can't live without that). So it's been my central core for my day to day work.
While I'm not an organization freak (my cluttered office is painful evidence of that) I'm just wondering if anyone else is using something like this and if so, what's their experiences been?
-
Writing SharePoint Web Parts, the painful adventure...
Writing Web Parts for SharePoint is an adventure. The type of adventure that you find yourself in the middle of, realize that you don't have your fedora cap and whip, and the boulder starts rushing towards you and the spiders are crawling all over you with no exit in sight. Not a very pleasant experience for anyone.
Luckily there are some saviors to this story. I've blogged about this before but after a weekend of writing custom web parts the painful way, I've basically given up on the Microsoft way for now and focused on using an alternative. Until VS 2005 comes along, where writing Web Parts is much easier, there is an interim solution. Fons Sonnemans and Jan Tielens got together and put together SmartPart. It's a great little addition to your SharePoint development toolbox and one everyone should have. Don't bother writing Web Parts and going through the 42 steps that Microsoft wants you to in order to get your web part created (although the Web Part Templates does make this easier). Just create a custom user control and drop it into a folder on your SharePoint server. SmartPart will happily render it for you, taking care of all the SharePoint stuff for you. The best part of this (besides not having to jump through hoops built Web Parts) is the fact that you can use the full UI design mode tools in Visual Studio to build your controls. No more RenderWebPart calls with hand building controls. Since your control is running on the SharePoint server, you can easily interface with the object model and do whatever you normally would do like accessing lists and sites and users oh my.
Anyways, check out the GotDotNet workspace here and give it a whirl. Beats the heck out of the fugly way of doing it today.
-
Web Parts without SharePoint, ASP.NET 2.0
I've been watching the classes in ASP.NET 2.0 for quite some time and working with the betas to see how we might build applications today so we're positioned for the changes next year (check out the Visual Studio 2005 Beta Documentation site here for all the gory details on the new classes). Something that intrigued me was the WebPart classes they introduced.
Living in the SharePoint space, web parts are the staple at to how to get information out to the presentation layer. In SharePoint they're a little ugly to write, but none the less are effective because the end consumer of the web part can choose how to display it (based on preferences through SharePoint for that particular instance of the web part). This includes appearance, what options they want to display, where they want it on the web page, etc. All of this fits into a nice framework and even allows you to have multiple copies of the web part with them pointing at different views or data sources. One persons way of using a web part may be different then someone else, either by design or organization. For SharePoint, this was the innovation that allows us to build applications on that platform with little effort and target content to specific audiences.
When I saw the WebPart classes introduced in the 2.0 framework I started salivating. Bringing the capabilities of web parts to regular ASP.NET apps meant that I could introduce things like personalization and customization to apps without having to have to do a lot of work. Web Parts are similar to web user controls but provide the functionality to allow users to customize the website by adding, deleting, and moving controls around the page based on WebPartZones. Any ASP.NET server control can act as a Web Part but by creating a custom control derived from the WebPart class you gain access to advanced features.
You can check out the new MSDN paper on Web Parts here. Something to look forward to with your apps and something to keep in mind on how to design your apps today as these new capabilties roll into the framework and enable you to start leveraging more features with less code. -
Virtual Web Part Development with SharePoint
With all this talk about Virtual User Groups, I somehow got down this path and wanted to say that there is one and only one (IMHO) way to develop web parts for SharePoint (at least that's the conclusion I've come to). Virtual PC 2004 kicks for this. I was able to take the time to get a new Virtual image setup and decided to get a new SharePoint environment setup in it. With the recent update to Virtual PC, Microsoft has made it a little better (and faster) for this.
The install of Windows 2003 Server was smooth and getting Windows SharePoint Services running was a breeze. Basically:
- Create a new Virtual PC image through the wizard
- Pop in a Windows 2003 Server CD (I'm using Enterprise edition but whatever works for you)
- Run the install (takes about an hour on a 2Ghz machine with 2GB of memory). You don't need a domain so just create a workgroup for it.
- Once the install is done, make it a web server through the Manage Your Server setup screen
- Download Windows SharePoint Services from here and run the setup (10 minutes)
- Set your IIS to allow anonymous on the Default Web Site and set SharePoint to allow anonymous users by default as Readers
- Install Visual Studio .NET and optionally MSDN (another hour)
That's about it and Bob's your uncle. I only had to give it 400MB of memory in the settings and it runs well for running, administration, and debugging. The nice thing is that my local machine sees it (even though it's on a different workgroup than my box) and I can ping it and surf to it by name. Makes for great testing and developing because I can come in as a regular user and since it's running in Workgroup mode there's a Sign In button so I can become whoever I want for testing (Contributor, Admin or a user in a custom group). Much easier than when you're running on a domain with integrated authentication and you pretty much have God access to everything. I also don't have to worry about domains and that whole mess. Note that this setup is for WSS, SPS does require a domain to operate on but you can develop web parts on this environment and use them on SharePoint, you just can't use the SharePoint features like search, etc.
Try it out if you've got the resources as it makes for a nice easy development setup. Debugging web parts has to be done on the server but that's what the install of Visual Studio is for and the speed is quite acceptable. Also there's a good site here on what OSes work (and what don't) under Virtual PC if you're looking on setting up different configurations (I have a Debian setup as well for some Linux development, nothing like a disposable machine!)
-
I love the UI, I love the UI, I love...
Well, no. It's all great that you have a nice Domain Object. Grant you, it's now populated with an ugly Id attribute which it slugs around because someone, somewhere decided that it was important enough to save the information into a database and databases need a primary key to find stuff. The problem is when I have to show a list to pick from, one of which is what the user selected previously. My Domain Object has this attribute:
Name: Author; Value: 21
And there's a collection of Roles to pick from:
Name: Reader; Id: 10
Name: Author; Id: 21
Name: Administrator; Id: 321So I have a simple LookupDTO I use in my UI and Service Layer that looks like this:
class LookupDTO
{
string Name;
int Id;
}It's generic (all lookups follow the same pattern). Problem is that if you have a collection of Roles you can't just bind it to a DropDownList like this:
// this returns an array of LookupDTO objects from the service layer
uiName.DataSource = RoleService.FindListForProject(projectId);
uiName.DataTextField = "Name";
uiName.DataValueField = "Id";
uiName.DataBind();Because the values are 10, 21, and 321 and you can't set uiName.SelectedIndex = 21 or else ASP.NET blows it's head up with a boundary problem (it's 0-based). Ugly. I hate the fact that my Domain Object says that it's Id is 21 (because that's the database id that was created when it got saved) but ASP.NET needs a 0 or 1 to let a user pick from. So do I need a mapper for my mapper? And then there's going back that you have to do another mapping. So maybe there's a UI component that has both the "real" value and the UI value? I don't know.
I'm almost thinking that I should use a Guid in the database, but autoincrement is so nice and easy. A Guid would have it's advantage (other than driving my dba nuts) because I can pregenerate it in my Domain when a real object is created so I don't have to do fancy stuff in my SQL to get the ID that was just created. A common problem with using autoincrement in SQL is that you don't get it before the INSERT call. It's unique. I still think I'll have a problem in my UI layer because setting the HTML for a selected item in a dropdown list doesn't like "A04759E3-509C-42c6-BE27-20562B2BA6CA" as a selected value.
I know there's a better solution out there to map "real" values to ASP.NET UI controls like dropdown lists that don't like indices that don't match the 0 based counting that HTML creates. There's a good blog by Steve Eichert here on Hooking your Domain Model to the UI. I think we need a good UI Mapper tool/pattern/something to make this a no-brainer.
There's also a very nice add-in from Manuel Abadia over at CodeProject. It provides two way data binding in ASP.NET and looks pretty simple. You just hook up your collection to the fields on your webpage (through a designer) to set the databindings to your DTOs and call BindToWebForm (or BindFromWebForm). It turns this:
// populate the webform with the customer data
lName.Text = cus.Name;
lSurname.Text = cus.Surname;
lEmail.Text = cus.Email;
lAddress.Text = cus.Address;
lAge.Text = cus.Age.ToString();// get the customer data from the webform
cus.Name = lName.Text;
cus.Surname = lSurname.Text;
cus.Email = lEmail.Text;
cus.Address = lAddress.Text;
cus.Age = Int32.Parse(lAge.Text);Into this:
// populate the webform with the customer data
bindingManager1.BindToWebForm(this);// get the customer data from the webform
bindingManager1.BindFromWebForm(this);You can check out here. I need to find some time to look at it because this is nuts (or else I'm so out of it I'm missing the obvious). Maybe I haven't had enough coffee to think correctly. Friends don't let friends blog drunk (or semi-awake) might be a more appropriate title for this entry.
-
SharePoint beyond the Intranet
Okay, let's face it. SharePoint (when appropriately used) kicks as a collaboration tool. I don't know how many times I've been asked about sharing knowledge only to say "well SharePoint can do this". I don't know how many times I've seen teams wanting to cobble together a website with FrontPage or throw up a forum tool or something when "SharePoint can do it" (the struggle with the evil IT empire [our strategy and architecture guys] and how we can't just do what's right vs. correct is a whole 'nuther conversation). Grant you, SharePoint isn't all things to all people, but from a collaboration viewpoint it's pretty nifty.
My fellow SharePoint lover (hmm, that didn't come out quite right) Amanda Murphy (and a Canadian to boot), posed the question of Virtual SharePoint User Groups. While we're all squibbing away building our intranet solutions, it seems that we might be missing the one thing that SharePoint is great for and the one thing that might bring some order to this chaos. The internet is a big ugly place (as I put on all my blueprints, a nasty stormcloud with the words "big bad interweb") and trying to filter information out at the same time balancing what's worthy is just as ugly. I've got I don't know how many bookmarks that I use to hunt down things, a few dozen RSS feeds, countless forum userids and passwords, yet still information fall through the cracks and I'll stumble across a "wow, I didn't know that" each day.
Microsoft is making some headway in building Technical Community Sites where like people with like thoughts can meet and swap good stuff. We all know User Groups are a great thing (the .NET one here in Cowtown has some great events and is very value-added IMHO). So Amanda puts in my head the notion of a more global User Group. Still a special interest group around that thing we call SharePoint (or SPS, WSS, or whatever acronym you want to throw out there) but why not extend the very tool itself we use each day to accomodate this? Exactly how to get things going, I'm not sure. I do have a passion for this though and would like to see where it goes.
Anyways, some food for thought and perhaps an evolution towards a more unified collaboration across virtual boundaries that might make life a little bit easier one day for some of us.
-
Hodgepodge of some (hopefully) useful .NET links and sites
Was doing some research over the weekend and gathed together some links on patterns and practices and other stuff. Hope you guys find these useful.Good site with all kinds of patterns around user interface (both web and other). Lots of good ideas here.I was going through some options of providing online help in web apps and came across this. It's a study done on different techniques applied to providing online help for web application users. Some good ideas and information here on what worked and what didn't.This may seem silly but tables have TH tags for a reason and web readers (the type blind folks use to read webpages for them) rely on it. One of my biggest beef is the fact that the ASP.NET DataGrid doesn't spit out HTML code that's compliant with these readers. This KB article talks about resolving the problem via a hotfix that went out sometime ago. Just information to watch out for and contains a good link to Watchfire, a website that can check your page for accessibility compliance.Sample ApplicationsMicrosoft (and others) have gone to some extents to put together sample applications, reference architecture apps, and other resources to learn from. Some good (some not so good) stuff here if you haven't already seen any of these. That make for great reference when you're looking at how to implement some ideas.ASP.NET 1.0/1.1 Starter Kits
HomeCommerce Starter Kit
Community Starter Kit
Portal Starter Kit
Reports Starter Kit
Time Tracker Starter Kit
Issue Tracker Starter Kit BetaASP.NET 2.0 Starter Kits
HomePeer to Peer - .NET Framework 1.0/1.1
TerrariumServer-Side Applications - .NET Framework 1.0/1.1
Duwamish 7 (.NET)
Fitch and Mathers 7 (.NET)
IBuySpy Portal
IBuySpy Storefront
PetShop 3.0
PetShop 2.0Service Orientation Architecture
GenericoSmart Client - .NET Framework 1.0/1.1
IssueVision
FotoVision
TaskVision -
The dumbness of a Domain Object
I've been mulling over some ideas for the past couple of days as I work on a project and came to a bit of a head with regards to the dumbness of a Domain Object. There are some base principles that I try to follow with application architecture:
- The data access layer only creates or accepts domain objects
- The service layer is responsible for creating or converting data transfer objects to real domain objects
- Only data transfer objects are sent between the service layer and user interface
So first off, maybe some of these principles are not correct. Hey, principles can always be changed (as long as you reapply them everywhere if they do change and adjust accordingly). I'll leave that to the reader to discuss.
Given these norms, there's a problem (or maybe a question). If the DAL only creates Domain Objects, then it needs to know how to assemble them. After all, it's retrieving data from a source and populating *something*. You could hide the creation in an Assembler or maybe a Factory but still, at some point some data needs to be set as an attribute in a Domain Object meaning that the DAL knows something about the contruction of a Domain Object. The other option is that everything gets assembled in the service layer. If this is the case then why do we even need collections in a Domain Object? They can be dumb and just hold properties that relate to themselves and not worry about things like collections of children.
So here's an example to try to make sense of what I'm talking about. Imagine you have a Media Center tool where users can view album information, list tracks on an album and update the track information. This gives us some simple objects like so (C# pseudo-code):
class Album
{
int AlbumId;
string Title;
string Artist;
}class Track
{
int TrackId;
string Title;
int Length;
}In order to know what Track belongs to what Album, I could have Domain Objects that look like this:
class Album
{
int AlbumId;
string Title;
string Artist;
ArrayList Tracks;
}class Track
{
int TrackId;
string Title;
int Length;
}Or maybe this:
class Album
{
int AlbumId;
string Title;
string Artist;
}class Track
{
int TrackId;
int AlbumId;
string Title;
int Length;
}In the case where I have an ArrayList of Tracks in my Album, I don't need the AlbumId to know which Track belongs where. However, if I have to create an Album object out of my DAL, I now know that I have to create Tracks as well. Am I not putting logic of structure of the application in my data layer now? In the last example, I can have some Assembler make calls to the data layer (1 for the album and 1 for the tracks) and put together an object myself. And if the only reason I'm doing this is so that I can show the user at the UI layer an album and it's related tracks, why does my Album Domain Object even need to know about Tracks?
This also brings up the question around using IDs everywhere. Remember we have a principle (right or wrong) that the UI only deals with DTOs and knows nothing about the domain or (gasp) the data access layer. End users don't need to know that "Like a Virgin" has an ID of 4532 in the database. However, if they update the title to a track on the album and want the tool to save that information, it means the UI needs to keep track of all this junk in order to send it back to the system for updating (there's no guarantee that two tracks won't have the same name, even on the same album). So going back to our example where I only want to update one single Track.Title property with a new name the user typed in, do I send back an entire AlbumDTO (with an Array of TrackDTOs). Probably not. I only want to update one track so I only send back one TrackDTO which leads me to the idea that:
- A TrackDTO must be able to exist on its own (for updating the backend from the UI)
- It needs to keep track of the Album it belongs to (otherwise how do we know what Album it's for when we update it)
Given this, why should a Domain Object (Album in this case) even bother to have a collection of children (Tracks). So all assembling should be done somewhere other than in the domain objects or data access layer? While this might not be the rule for all Domain Objects, I thought it was something that didn't seem to have a very clear answer (or maybe there is but I'm just missing it).
-
Happy Thanksgiving Canada!
"As God is my witness, I thought Turkeys could fly!"
- Arthur Carlson, (WKRP Station Manager) 1978 - after a Thanksgiving promotional stunt went horribly wrong -
InstallShield AutoUpdate
I'm not one to usually go non-techie and go down the dark sales path, but I saw something I wanted to mention.
I picked up a copy of Jasc's Paint Shop Pro Studio. It's basically an uber-version of their Paint Shop Pro product. Anyways, after the install, I ran it for the first time and up came what looked like the Windows Installer Update site. I was a little thrown for a sec because I wasn't sure what was going on? Was I missing a critical update? If so, why was Jasc telling me this? Then I realized that it wasn't Studio but an Install Shield feature. Install Shield Corp has a nice Update Service. It basically gives you a nice web-based interface (like WUS) to check for components of your application and an integration piece to install them. They offer both an Install Shield-Hosted service or you can host it on your own infrastructure. Pretty nifty (although when they don't talk about how much it is online, I'm sure it's a big-ticket item).
Here's to more installers (especially the free ones like Inno Setup that I highly recommend) to combining these concepts. It would be nice if products built in more updaters themselves like Visual Studio (there is a "Check for Service Updates" but I've never got it to work and you have to go through the Add/Remove Programs to access it). Of course here's an opportunity to maybe build a component that does this easily for people.
-
SharePoint Service Architecture and site updates
Found this on TheServerSide.NET and felt it was worthy to post:
A new paper on MSDN looks at the architecture of SharePoint Services beginning with a high level overview of the web server and drilling down to using managed and unmanaged code. This paper is a “must read” for anybody looking to develop applications built using SharePoint Services.
There’s quite a bit going on under the covers of SharePoint services. SharePoint Services is implemented primarily through an ISAPI filter installed in IIS which accesses unmanaged DLLs installed on the web server. The ASPX pages that make up a SharePoint site are actually a relatively thin veneer over those same DLLs. All of the data is then stored in an MSDE or SQL Server Database. And this is the high level view!
To read more about SharePoint Services Architecture look here.For this site, a few new links in the SharePoint and Scrum sections. The site is filling out nicely since I started it 6 months ago, although I wish I could post everyday as there's a lot of great stuff to share. Please feel free to let me know if I've missed anything important or you have something to share.
Also I've taken a couple of blogs and turned them into articles so you can find them in the sidebar. These were ones where I got some feedback and people were asking a lot of questions so there was interest to keep it around and to the forefront (migration of sites, branding SPS, etc.) I'll add more as they become a reality.
-
Defeated by CVS, Windows, and IIS
Okay, I'll admit it. I've come up against a techno-combo that just has drained me (and bugs the crap out of me). I'm throwing in the towel and picking up a new one.
We setup CVSNT at work for team source control in order to adapt to a more agile development lifecycle (PVCS just doesn't work when everyone is refactoring and checking in all the time). We're still using PVCS for our enteprise SCM and when things are ready, they're labeled at checked into our corporate repository (well, that's the plan anyways). It's a nice setup and works well.
I've been struggling with getting some kind of web interface for CVS working with IIS. Yes, I'm tied down to IIS as our corporate web servers which is fine. So I went out to hunt down all the tools I could find and make work (the ultimate goal is to turn our Projects Portal running on SharePoint into something like SourceForge where you can access the source code from a project website). Talk about painful.
CVSWebNT was the first stop. After installing ActivePerl I was okay burning through the setup. However Perl really isn't a friendly thing to debug, especially when it's an out-of-process cgi-bin script. So after many tries at hanging IIS and rebooting the server, I gave up. Next seemed like a nice gem called CVS4IIS. VB, ASP, and COM (blech) but okay let's give it a try. Not bad but didn't seem to work and it can't support multiple repositories. Finally I took at look at ViewCVS for Windows. Well, not really official but Russ is doing a good job of getting things going there. Problem is that now I would have to install Python, and the Python for Windows extensions and whatever else is thrown in there. In a corporate environment when you're somewhat limited to using a core set of technologies (Python is not one of them) it's tricky. Pain and suffering all before my 2nd cup of coffee this morning.
So why isn't there a nice project out there that does this easily? I mean, CVSNT is great. Works well, actually has an installer, and doesn't seem to fall over when you look at it. I'm throwing in the towel on trying to get these things working in our environment but there might be hope. Now I'm charged with looking at writing what should hopefully be a fairly simple ASP.NET application to do this. I mean, how frickin' hard can it be? (famous last words). Here comes NCVSWeb coming soon to a SourceForge site near you.
I so wish for a Linux server at work. Just one. Just a little one. A copy of Debian and a call to apt install cvs and I'm done.
-
The Mysteries of SharePoint Search
There's a myth in town. SharePoint searches documents. While the search feature of the SharePoint products is a key element, it's not entirely true that it actually does any searching. Walk with me on this one.
SharePoint, like a conductor in an orchestra, really just orchestrates a search request. As a conductor doesn't play an instrument, SharePoint doesn't actually do the mechanics of a search, it just makes the request. It's really all about IFilters and the search capabilities they provide. The SharePoint search pages, object model and web services are just facades to access the real workers.
This conversation came up because, out of the box, SharePoint only searches the following content types: .txt, .htm, .doc, .xls, and .ppt. And this search is not SharePoint but rather SQL Servers full-text search engine. After all, a binary file type (like PDF) can't really be searched unless the searcher knows how to read the format. SQL Server knows how to read the base types and with the addition of new iFilters, you can extend that. You can get additional IFilters for PDF, RTF, MSG, ZIP and other formats from various sources (Microsoft has a few free ones like for RTF). A good source of commercial IFilters is the IFilterShop.
So next time you try searching for content check to make sure your SQL Server (all content for SharePoint is stored in SQL) has an IFilter that recognizes the format you're looking for. Also a catch is when you do need to add a new search type, make sure you install the IFilter on the SQL Server and not the SharePoint one as it's the mechanic that's actually performing the search and just providing results to SharePoint to present to the user.
-
SPS Customization
I see (and get) a lot of questions about customizing the look and feel of SharePoint Portal Server. More often than not, this leads to an answer of directly modifying the SPS.CSS files on the server. This always leads to the caveat that this file may be updated with a service pack install or software upgrade. There is a much easier and safer way to do this which will never break.
In your SharePoint setup, Microsoft has provided a way to specify your own custom style sheet. If you know how style sheets work when a page is rendered, the last style specified (no matter how many style sheet files get loaded) always wins. This is by design but knowing this, and how SharePoint works, is a powerful combo that will let you cleanly mod your portal as much as you want without having to backup/restore files everytime your do an upgrade.
When SharePoint renders it's portal pages it renders all of it's own internal stylesheets. These are (in order):
- ows.ccs
- menu.css
- sps.css
Next, it renders any stylesheet you specify in the Site Settings page. Finally it renders the page content. Knowing this means that any style you put into your own stylesheet will override those specified in the Microsoft ones. So now you don't have to go modifying the base files to get the effect you want. Here's a simple example.
Create a blank stylesheet. Put a single style in it. Let's override .ms-WPTitle which is the style used to render Web Part titles. Your stylesheet should contain this:
.ms-WPTitle
{
background-color: black;
font-weight: bold;
font-family: verdana, arial, helvetica, sans-serif;
color: white;
padding-left: 6px;
padding-right: 7px;
padding-top: 2px;
padding-bottom: 2px;
font-size: 8pt;
text-transform: uppercase;
}This creates a style for the web part titles that displays a white uppercase title against a black background using Verdana as a font. Save this file as "mystyle.css" (or whatever name you want).
Now you need to tell SharePoint to use this stylesheet.
- Select "Site Settings" from your portal
- Click on "Change portal site properties and SharePoint site creation settings" from the General Settings section
- The last option is for a Custom Cascading Style Sheet. Put in the location of your stylesheet you created above. An additional trick is to use SharePoint to store your own stylesheet so put it in the Document Library of your own portal. That way you don't have to deal with server administrators whenever you want to change your sites look and it gives you a simple document management process to keep tabs on who's working on this file. So our entry would look like this: "/Document%20Library/mystyle.css" (assuming you uploaded it to the site, otherwise use a fully qualilfied UNC to locate the stylesheet, maybe from your corporate web servers)
- Click OK to save the changes
Now refresh the site in your browser. You should see the changes applied to all web parts on your site (Press F5 to refresh or you might have to do a "deep" refresh with Ctrl+F5). Continue to edit this file, making changes with your favorite style sheet editor like TopStyle (or Notepad if you prefer). In no time you'll have a custom stylesheet with the branding you want on your site.
A variation on creating styles from scratch is to take a copy of SPS.CSS and modify the styles you want by changing your copy of this file. This uses the same technique as above (not modifying the file directly) but gives you a list of all the styles that SharePoint uses rather than building up from scratch. Pick whichever method works for you but the important thing to remember is that you don't have to touch the base SharePoint files.
Two more quick tips. There's a list of the styles used with a visual reference in the SDK documentation available here. Also in that file is a short piece of Javascript that you can create and put into a content editor webpart to display the styles on the page when you hover your mouse over them. Both are valuable resources to help you when you're customizing your look.
Here's a full set of MSDN articles published on the subject of customizing SPS:
Part 1 : Introduction
Part 2 : Using Templates and Site Definitions
Part 3: Style Sheet Class Reference Tables -
Migrating SharePoint Sites
One thing that comes up quite often is "How do I keep all the work I've done in development and move it to acceptance/production" with SharePoint? Luckily there's a nice command line tool that's bundled with SharePoint to do this.
SMIGRATE is a tool that can restore sites and move them from SharePoint Team Services (STS) into the new 2003 versions. It can also help you migrate sites from one server to another (or to the same server) in 2003 directly. This blog talks about using it for migration from a development environment to your production one (or test if you prefer).
SMIGRATE works wonders because a) it migrates all your data, including security and subsites b) you can execute it from any SharePoint server and restore to any server (you have to be SPS/WSS admin on both) c) is simple for moving all your hard work in development into acceptance or production. Using SMIGRATE is pretty straight forward.
To backup a website:
- Enter the following at the command line:
smigrate -w http://server[/site] -f filename.fwp -u domain\id -pw * - This will prompt you for your NT password. Enter it at the prompt.
- Grab a coffee and wait.
To restore a site:
- Create a new site through the portal site creation wizard. Note what the site url is.
- When you get to the point of applying a template, stop and close the browser.
- Enter the following at the command line from any SharePoint server (where siteurl is the url you used in step #1):
smigrate -r -w siteurl -f filename.fwp -u domain\id -pw * - Enter your password, grab a coffee, go for lunch or have a siesta.
There are a couple of gotchas you should be aware of.
- When you migrate a site, the new site has to exist. If you've gone through the trouble of creating the site using something like the SPS site creation wizard you'll find you get the site created then try to migrate and it tells you a template has already been applied. The trick is that when you to the screen in SPS where you apply the template to the site, the site is already created. Go ahead and start your migration now and when you're done, the site will be there and ready to use.
- Make sure all your dataview web parts and 3rd party components are on the target server. There's nothing like migrating the site then trying to access it, only to find yourself staring at the maintenance page trying to remove invalid web parts. This is especially true of dataview web parts as they are sometimes picky about the pathing to the datasource, especially if you have it pointing at another list on the same site.
In any case, the tool is a good friend to have so get used to it, try it out and make sure you understand what's going on before you start moving gigabytes of documents and lists onto your production boxes. There's also a good writeup on using the tool here and the online version of the Windows SharePoint Administrators Guide here.
For those that are afflicticted with GUI-Itis and fear the command line, there's a graphical interface that Renauld Comte created. You can download the file directly from here (note, you still have to run this on your SharePoint server).
- Enter the following at the command line:
-
6 degrees of Office separation
As I drift through what seems like an endless rift of links, I stumbled across something fun this morning (okay, I call it fun others would call it a waste of bandwidth)
This Microsoft Office Quiz is for Windows SharePoint Services, the layer deliverying document libraries and team sites for those that dance the SharePoint dance everyday like I do. I managed to score a perfect 10, but not without struggling over question #5 as I don't use meeting workspaces but it seemed the most logical and you can never go wrong with logic (especially with the Chewbacca Defense). There's a whole schwack of quizzes for all the Office products so if you're feeling particularily geeky and want to impress your friends check out this link.
Funny how I got there. An email from someone that Kate Gregory referred me to, which prompted me to google Kate to see what she was blogging about, which led me to this post which pointed me to the quiz site. It's like playing the Six Degrees of Separation game but with geeks. Hmmm. I wonder how far away I am to Bill Gates?
-
Document Libraries vs. Area Document Libraries
Saw something that made my head turn with SharePoint so wanted to throw it out there.
At the portal level you can create document libraries, lists, etc. in an area. The golden rule has been (and a contention of FAQs all over) is that content in an area uses the permissions set from the area. This is in contrast to a WSS site where the permissions can be applied to each document library differently as WSS sites have no concept of an area.
However in the creation page for an area there's a new option. You can create a Document Library AND you can create an Area Document Library. I wondered what the difference was. A quick Google-is-your-friend search turned up a message by someone saying that Area Document Libraries use permissions from the area whereas a document library in an area can have it's own permissions set (if you can follow that logic) . This however is not true because a test creating these things in the same area show the option to set permissions still isn't there for either library (at the portal level).
So the mystery is still unsolved? What's the difference?