Wednesday, December 31, 2008

Accessing a list using SpWeb.Lists["listname"]

Recently, I tried deploying some code to production that opened up a list and added items into it. Sounds simple, and it worked great in my Test environment.
Simplified, the code looked something like this:

SPList myNewList = currentWeb.Lists["my list"];

Should work fine right?

After releasing to production, it would not work. I was getting:
"Value does not fall within the expected range."
(Wouldn't it be nice, if it told you what value did not fall within what range? That would make my life so much easier...)

Turns out, the list I was trying to open: "my list", wasn't originally named "my list". Someone had created the list as: "my list" (notice the two spaces), and then renamed it back. I checked the MSFT documentation on accessing a list using web.lists["name"], which is really the SPListCollection class ( http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistcollection.aspx )

It says:
"Use an indexer to return a single list from the collection. For example, assuming the collection is assigned to a variable named collLists, use collLists[index] in C#, or collLists(index) in Visual Basic, where index is the index number of the list in the collection, the display name of the list, or the GUID of the list."

WRONG! The display name, which I assume is the name that is listed on the list's Settings page as "Title", is not what it uses to look up the item. It uses the name that it is originally created as, the name that is in the URL.

I suppose this is good if you write code that uses the list name to get the list, and then later a user renames the list. Your code will still work.
It is a little odd that something like:
SPList myListCopy = myWeb.Lists[mylist.Title];
may not actually work.



EDIT:

The "Web Address:" on the List Settings page suffers from the List rename bug too. It will show the list using the List's title, and not the List's URL. If you rename the List, this web address will be wrong.

Monday, December 29, 2008

Email Enabling Custom Lists in MOSS

I was working with a list based on a Custon List definition today, and I wanted to email enable it. After playing around for a while and wondering why the link to email enable the list was not appearing on the settings page, I turned to google.

For some reason, you cannot email enable a list that is based on the custom list definition.

Solution: Use a different list type. I used Announcements because it's simple and doesn't have lots of extra columns that I don't want to use.

Monday, April 7, 2008

Workflows on Surveys in Moss? Nope!

Recently, I was trying to create a public facing survey on a public facing MOSS site. My solution was to create two survey's. One that was public and one that was private. The user would fill out the public survey, and workflow would move the response to the private survey.
This would allow for anonymous submission, but the responses would not be public.

After some testing I found that surveys do not support workflow. You will get "Failed to Start" as the result of your workflow. Searching the web a bit, i found:
http://support.microsoft.com/kb/926370
which basically says workflow does not work on a survey list. It's a known bug, and there is no fix.

Monday, March 10, 2008

Moss and Virtual IP's

If I remember correctly, there was an issue with SPS 2003 and using Virtual IP's in IIS. This is still the case.

I've run into this a few times in different ways, if you assign an IP to an IIS virual server, some of SharePoint's features won't quite work correctly.
Virtual IP's are extra IP's you have added to your computer, and then set each IIS virtual server to only watch for traffic on the specified IP. These are sometimes used for load balancing, or if you don't trust host headers to forward traffic to the correct web application in IIS.

1: Using a dedicated search index machine. When you use central admin to pick a machine that should be dedicated for search, it will change your hosts file to point all requests for www.mysharepointSite.com to the IP assigned to that machine. You won't be able to change this, since SharePoint will wipe out any changes that you make. This fine, unless you assign a virtual IP in IIS to the web application that is running your site. SharePoint will set the hosts file to use the physical IP of the machine, not the virtual IP. This will break search since IIS will not pick up the request since it is setup to only watch for traffic on a different IP.
The solution is to edit the hosts file yourself, and tell SharePoint to use all servers for indexing. It is convenient to use the central Admin UI to setup which machine will be used to search, but it does nothing more than change the hosts file. You can do this manually and have more control.

The hosts file allows you to override what DNS says. If your DNS server is setup to point www.mysharepointsite.com to 123.123.123.123, you can add a line in your hosts file to look somewhere else. This is especially useful for testing. The hosts file is located at:
C:\windows\system32\drivers\etc\hosts. It does not have an extension and can be edited using notepad.




2: Alternate access mappings. If you are using Virtual IP's for your IIS virtual servers, setting up an alternate access mapping in CA is not enough to get it to work. You will also have to go into IIS and manually add the host header to the virtual server.

Thursday, March 6, 2008

Infopath and Site columns

When publishing a form in infopath, you are given the ability to match fields in your form to site columns.
Be careful not to create two site columns with the same name in the same category. Infopath has a bug in that it will let you see that you have two columns with the same name, but will only let you pick the first one. It seems that it matches by name, and not by the internal name. You can pick the second field, but if you go back to edit it again, you'll see that it goes back to the first field.

This is only an issue when publishing to a sharepoint site.

Admin Deployed Forms VS. Content Type Deployed Forms

There are a few Gotcha's around form deployment. Here are some Pro's and Con's of each:

Document Library:
Limited to one document library.

Content Type:
Limited to one site.
Infopath May timeout on upgrades if you have too many fields. I ran into this error around 25 fields. During the publishing process you will receive an error "Updating site content type failed." This is due to the fact that Infopath has a 30 second time out. If it does not finish it just gives up. I worked through this with premier support. It was suggested I use admin deployed forms.


Admin deployed forms:
More complex publishing process. Has effects on content deployment due to it being a feature.
Does not update content types. If you change the number of published fields, you will have to wipe out the content type and re-deploy. This is not possible after it has gone live since you will have to delete all the forms that have been created.

Turn Off Hover Over Screen Tips on Browser form

The easiest way to make a field required on an infopath form is to check the 'cannot be blank' box. The user must fill in data on the field to be able to submit the form. This also adds a red star to the field so the user knows they must enter data.

The problem is that it also adds a hover box which says 'Required' or something like that. This box is annoying to users because it often hovers over another field, blocking the user from entering data into the other field.

Here's how to get rid of it:

Edit the Core.JS file(12\template\layouts\inc)
Find the function called ErrorVisualization_ShowShortMessage, around line 5125.

You want to change this function to do nothing. the easiest way is to add: return; as the first line of code that it runs.
It should look something like:

function ErrorVisualization_ShowShortMessage(objControl,boolIsSticky){;
;
return;


The hover boxes won't appear anymore.

You could get a little fancier and have it check the error string. Then, in infopath, set the ones you don't want to show to be 'xxxx' or something. Have the function check the string. If is your 'xxxx' string, then return, else show the message.
For example, I added:
if(strErrorString=="Required" strErrorString=="Cannot be blank" strErrorString =="Only date allowed (example: 2001-03-14)") return;
after:
var strErrorString = objDatum.GetErrorMessage();

Now, my custom messages appear, but the default ones do not.