Archive for December, 2009

Asset Picker field type

In one of my project, I had to create a field type in MOSS with Asset picker functionality. Custom field types are very useful when you are creating custom functionality in MOSS 2007. The following example shows how to provide a functionality to select the document/list item/ from the site. The would be helpful to the user selecting the URL rather typing everything (there is a possibility of typos 🙂 ). We are going to use ‘AssetUrlSelector‘ class from Microsoft.SharePoint.Publishing.WebControls namespace for the purpose.

Create a custom field class by inheriting from SPFieldText class.

public class RelationshipField : SPFieldText {
// Methods
public RelationshipField(SPFieldCollection fields, string fieldName) : base(fields, fieldName) {}

public RelationshipField(SPFieldCollection fields, string typeName, string displayName) : base(fields, typeName, displayName)
{}

// Properties
public override BaseFieldControl FieldRenderingControl
{
get
{
BaseFieldControl control = new RelationshipFieldControl();
control.FieldName = base.InternalName;
return control;
}
}
}

Create a control class by inherting from BaseFieldControl class. and also need to include the following namespaces.

using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing.WebControls;
using Microsoft.SharePoint.WebControls;

Here is how the control creation goes:

public class RelationshipFieldControl : BaseFieldControl
{
protected AssetUrlSelector urlSelector;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Set the value if this is a postback.

if (this.Page.IsPostBack && base.ControlMode == SPControlMode.Edit)
{
this.ListItemFieldValue = urlSelector.AssetUrl;
}
}
protected override void CreateChildControls()
{
base.CreateChildControls();
// Add the asset picker when in edit mode.
if (base.ControlMode == SPControlMode.Edit)
{
urlSelector = new AssetUrlSelector();
this.Controls.Add(urlSelector);
}
}

protected override void Render(HtmlTextWriter output)
{
// If this is edit mode and has a value, set the picker.
if (base.ControlMode.Equals(SPControlMode.Edit)
&& this.ListItemFieldValue != null)
{
this.urlSelector.AssetUrl = this.ListItemFieldValue.ToString();
}
base.Render(output);
}
}

To register the custom field created above, you need to create a field type definition file as show below. And this xml file needs to be copied to 12\TEMPLATE\XML directory to recognize by MOSS.

The AssetUrlSelector control provides much of the functionality that is necessary for the user to browse and select a document in an Office SharePoint Server library. When you add an instance of this control, a text box and browse button are displayed on the page.
Asset Selector
When users click the Browse button, the Asset Picker dialog box appears and lets the user browse the SharePoint Server libraries and select the related file. The URL to the selected file is automatically set on the AssetUrl property file and appears in the text box.

You might want to scope the URL that is selected with the AssetUrlSelector. To allow users to select a document or item only within the current site collection, you can set the AllowExternalUrls property of the AssetUrlSelector class to false. To narrow the scope even more so that users can only select an item within the current web or a specific list or library, you can implement custom code to validate the selected URL.
The end result of this example is that the path of the related file is stored in the custom RelationshipField. However, the relationship remains unknown to the related file because its metadata is never updated. You can use event handlers to ensure that the related file is updated appropriately when a relationship is created or modified; however, this can become complex. There may be scenarios in which the related file cannot immediately be updated, such as if the user does not have edit permissions on the related file, or the related file is checked out by another user.
At this point, the example is basically a reimplementation of the Hyperlink column functionality. However, by using the AssetURLSelector control (or Asset Picker) in Office SharePoint Server, you can add a UI for selecting the corresponding document in the relationship.
This example is intended to highlight the Asset Picker and the fact that you can use it in custom field controls. You can extend the example to provide additional useful functionality, such as letting users specify multiple-link relationships.

Happy Coding ..!!

~ Gangadhar Kotu

Advertisements

Best Practices for Handling Exceptions

A well-designed set of error handling code blocks can make a program more robust and less prone to crashing because the application handles such errors. The following list contains suggestions on best practices for handling exceptions:
  1. Know when to set up a try/catch block. For example, you can programmatically check for a condition that is likely to occur without using exception handling. In other situations, using exception handling to catch an error condition is appropriate.
  2. Use try/finally blocks around code that can potentially generate an exception and centralize your catch statements in one location. In this way, the try statement generates the exception, the finally statement closes or deallocates resources, and the catch statement handles the exception from a central location.
  3. Always order exceptions in catch blocks from the most specific to the least specific. This technique handles the specific exception before it is passed to a more general catch block.
  4. End exception class names with the word “Exception”. For example:
    public class MyFileNotFoundException : Exception {
    }
  5. In C#, use at least the three common constructors when creating your own exception classes. For an example, see How to: Create User-Defined Exceptions.
  6. In most cases, use the predefined exceptions types. Define new exception types only for programmatic scenarios. Introduce a new exception class to enable a programmer to take a different action in code based on the exception class.
  7. For most applications, derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value.
  8. Include a localized description string in every exception. When the user sees an error message, it is derived from the description string of the exception that was thrown, rather than from the exception class.
  9. Use grammatically correct error messages, including ending punctuation. Each sentence in a description string of an exception should end in a period.
  10. Provide Exception properties for programmatic access. Include extra information in an exception (in addition to the description string) only when there is a programmatic scenario where the additional information is useful.
  11. Return null for extremely common error cases. For example, Open returns null if the file is not found, but throws an exception if the file is locked.
  12. Design classes so that an exception is never thrown in normal use. For example, a FileStream class exposes another way of determining whether the end of the file has been reached. This avoids the exception that is thrown if you read past the end of the file. The following example shows how to read to the end of the file.class FileRead {
    public void Open(FileStream fileToRead)
    {
    // This if statement is optional
    // as it is very unlikely that
    // the stream would ever be null.
    if (fileToRead == null)
    {
    throw new System.ArgumentNullException();
    }

    int b;

    // Set the stream position to the beginning of the file.
    fileToRead.Seek(0, SeekOrigin.Begin);

    // Read each byte to the end of the file.
    for (int i = 0; i < fileToRead.Length; i++)
    {
    b = fileToRead.ReadByte();
    Console.Write(b.ToString());
    // Or do something else with the byte.
    }
    }
    }

  13. Throw an InvalidOperationException if a property set or method call is not appropriate given the object’s current state.
  14. Throw an ArgumentException or a class derived from ArgumentException if invalid parameters are passed.
  15. The stack trace begins at the statement where the exception is thrown and ends at the catch statement that catches the exception. Be aware of this fact when deciding where to place a throw statement.
  16. Use exception builder methods. It is common for a class to throw the same exception from different places in its implementation. To avoid excessive code, use helper methods that create the exception and return it.
Source: MSDN, CodeProject
~ Gangadhar Kotu

Configuring MOSS 2007 to search pdf documents – install and configure pdf ifilters

 

    1. Download Adobe PDF IFilters 6.0

 

    1. Start –>Run–> Services.msc and stop the IIS Admin service. The reason we need to do this is, the IFilters configuration needs an update to DOCICON.XML.

 

    1. Run the IFilters installer on the Indexing Server

 

    1. Download the pdf icon image pdficon of size 17X17 from the following location and save it as “icpdf.gif” somewhere to the local hard disk http://www.adobe.com/misc/linking.html

 

    1. Copy the icpdf.gif to the following location

 

    1. C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Template\Images”

 

    1. Go the C:\Program Files\Common Files\Microsoft Shared\Web server extensions\12\Template\Xml\

 

    1. Edit the DOCICON.XML by adding the following entry<MAPPING onclick=AtD.suggest(this); pre=”” hiddenSpellError? Key=”pdf” Value=”icpdf.gif”/>

 

    1. Perform an IIS RESET

 

    1. Go to Search Settings under Central Administration and add the pdf as the new file type

 

  1. Perform the crawl again

Now MOSS is supposed to search pdf documents properly. This is what said in so many Articles and Blogs. It did not work for me that easily. After some analysis, I’ve learnt that I need to apply a Microsoft Hot fix to make this work for MOSS 2007. The Microsoft Hot fix mentions the following steps to be performed to make the pdf search work for MOSS 2007

 

    1. Add the following registry entry, and then set the registry entry value to pdf:

 

    1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Search\Applications\<GUID>\Gather\Search\Extensions\ExtensionList\38

 

    1. To do this, follow these steps: a. Click Start, click Run, type regedit, and then click OK.

 

    1. Locate and then click the following registry subkey:

 

    1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Search\Applications\GUID\Gather\Search\Extensions\ExtensionList

 

    1. On the Edit menu, point to New, and then click String Value.

 

    1. Type 38, and then press ENTER.

 

    1. Right-click the registry entry that you created, and then click Modify.

 

    1. In the Value data box, type pdf, and then click OK.

 

  1. Verify that the following two registry subkeys are present and that they contain the appropriate values.

Note these registry subkeys and the values that they contain are created when you installed the Adobe PDF IFilter on the server.

 

    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Search\Setup\ContentIndexCommon\Filters\Extension\.pdf
      This registry subkey must contain the following registry entry:
      Name: Default
      Type: REG_MULTI_SZ
      Data: {4C904448-74A9-11D0-AF6E-00C04FD8DC02}

 

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Search\Setup\Filters\.pdfThis registry subkey must contain the following registry entries:
    • Name: Default
      Type: REG_SZ
      Data: (value not set)
    • Name: Extension
      Type: REG_SZ
      Data: pdf
    • Name: FileTypeBucket
      Type: REG_DWORD
      Data: 0x00000001 (1)
    • Name: MimeTypes
      Type: REG_SZ
      Data: application/pdf
    1. Upload the PDF documents to the Windows SharePoint Services 3.0 Web site.

 

    1. Stop and then start the Windows SharePoint Services Search service. To do this, follow these steps:a. Click Start, click Run, type cmd, and then click OK.

 

    1. Stop the Windows SharePoint Services Search service. To do this, type net stop spsearch at the command prompt, and then press ENTER.

 

    1. Start the Windows SharePoint Services Search service. To do this, type net start spsearch at the command prompt, and then press ENTER.

 

    1. Type exit to exit the command prompt.

 

Now MOSS is ready to search pdf documents. 🙂

~ Gangadhar Kotu