SharePoint "Service Unavailable" Error

Today I experienced an error on a VM “server unavailable” when I tried to navigate to any page on a web application. It turned out that the app pool under which the web application ran had crashed. To correct this I simply restarted the app pool in iismanager. Note that an iisreset or reboot of the vm did not restart the app pool.

 

I found this related article for wss2, but this seems to apply to all versions of sharepoint: http://support.microsoft.com/kb/823552

ASP.NET: Writing a Custom DataControlField

I recently needed to display data in a tabular form, where all rows could be edited at once (e.g. not using the DataControlRowState.Edit functionality normally used in a gridview) If you are creating the gridview directly on an aspx page or ascx control, you can simply setup the itemtemplate for a field (e.g. to contain your custom controls):

<asp:GridView ID=”GridView1″ runat=”server” AutoGenerateColumns=”false”>
    <Columns>
        <asp:TemplateField HeaderText=”Name”>
            <ItemTemplate>
                <asp:TextBox Runat=”server” Text='<%# Bind(“name”) %>’ ID=”TextBox1″></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

This is only appropriate if you have a design surface (i.e. on an ascx or aspx page) and there are many cases where you need to create controls via code (e.g. when creating a control library, or a webpart). To create custom template fields programmatically, you must create a class deriving from System.Web.UI.WebControls.DataControlField. The code below gives an example (note that this also works with SPGridView):

public class DropDownTest : DataControlField
{
    #region Properties
    /// <summary>
    /// The name of the DataField that will be bound
    /// </summary>
    public string DataField
    {
        get
        {
            object dataField = ViewState[“DataField”];
            if  (dataField != null)
            {
                return dataField.ToString();
            }
            return string.Empty;
        }
        set
        {
            this.ViewState[“DataField”] = value;
        }
    }
    #endregion

    #region Overidden methods
    /// <summary>
    /// Returns and instance of this field
    /// </summary>
    /// <returns>DropDownTest</returns>
    protected override DataControlField CreateField()
    {
        return new DropDownTest();
    }

    /// <summary>
    /// Initialise the cell and setup binding event
    /// </summary>
    /// <param name=”cell”>Container cell</param>
    /// <param name=”cellType”>Type of cell</param>
    /// <param name=”rowState”>Row state</param>
    /// <param name=”rowIndex”>Row index</param>
    public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
    {
        base.InitializeCell(cell, cellType, rowState, rowIndex);
        if (cellType == DataControlCellType.DataCell)
        {
            DropDownList dropDown = new DropDownList();
            dropDown.Items.Add(“Not Visible”);
            dropDown.Items.Add(“Date”);
            dropDown.Items.Add(“Text”);
            dropDown.Items.Add(“Select”);
            cell.Controls.Add(dropDown);

            if (!string.IsNullOrEmpty(this.DataField) && this.Visible)
            {
                dropDown.DataBinding += new EventHandler(dropDown_DataBinding);
            }
        }
    }

    /// <summary>
    /// Stores the cells values
    /// </summary>
    /// <param name=”dictionary”></param>
    /// <param name=”cell”></param>
    /// <param name=”rowState”></param>
    /// <param name=”includeReadOnly”></param>
    public override void ExtractValuesFromCell(System.Collections.Specialized.IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
    {
        base.ExtractValuesFromCell(dictionary, cell, rowState, includeReadOnly);
        string value = null;

        if (cell.Controls.Count > 0)
        {
            value = ((DropDownList)cell.Controls[0]).SelectedValue;
        }

        //If the key exists, update the value
        if (dictionary.Contains(this.DataField))
        {
            dictionary[this.DataField] = value;
        }
        //Add a new entry to the dictionary
        else
        {
            dictionary.Add(this.DataField, value);
        }
    }
    #endregion

    #region Event Handlers
    /// <summary>
    /// Perform the databinding
    /// </summary>
    /// <param name=”sender”>Sender object</param>
    /// <param name=”e”>Event args</param>
    private void dropDown_DataBinding(object sender, EventArgs e)
    {
        if (sender is DropDownList)
        {
            DropDownList dropDown = (DropDownList)sender;
            object dataItem = DataBinder.GetDataItem(dropDown.NamingContainer);
            dropDown.SelectedValue = DataBinder.GetPropertyValue(dataItem, this.DataField, null);
        }
    }
    #endregion
}

To add a custom column your gridview, simple do the following:

DropDownTest dropDownBound = new DropDownTest();
dropDownBound.DataField = “displayType”;
GridView1.Columns.Add(dropDownBound);

Note that you can obtain values by doing the following on a button click event or similar:

foreach (GridViewRow row in GridView1.Rows)
{
    string test = ((DropDownList)row.Cells[0].Controls[0]).SelectedValue;
    this.Context.Response.Write(test);
}

C#: Custom Serializable Class That Inherits From DataTable

To allow a custom type that inherits from System.Data.DataTable to be serializable,  you must do the following:

  1. Add the serializable attribute to the class.
  2. Include a namespace reference to System.Runtime.Serialization.
  3. Implement the “GetObjectData” method for the ISerializable interface.
  4. Add a constructor that takes parameters for SerializationInfo and StreamingContext (in addition to the normal constructor).

The code below illustrates.

namespace TestProject
{
    [Serializable]
    public class MyCustomDataTable : DataTable, ISerializable
    {
        #region Constructors
        public MyCustomDataTable() : base()
        {
        }

        public MyCustomDataTable(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
        #endregion

        …
        // Additions to datatable etc go here

        …
        #region ISerializable Members
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
        }
        #endregion
    }
}

Note that my reason for requiring serialization was that webparts require saved properties to be serializable (i.e. properties decorated with attributes such as[WebBrowsable(false),  Personalizable(PersonalizationScope.Shared)]).

Note: TFS Status Search

To view all checked out files on your TFS search, open as VS2005/8 command prompt and run the following command:

tf status /s:MyTFSServerName /u:*

Unless I’m missing something, there doesn’t seem to be a way of doing this through the Team Explorer (previously, you could just click “view->search->status search” in SourceSafe 6).