SharePoint "Service Unavailable" Error
24 April 2008
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
(currently 0 comments)
Passed MCTS 70-631
08 April 2008
I have passed exam 70-631: Windows SharePoint Services 3.0, Configuration, with a score of 1000.
_529_thumb.jpg)
(currently 0 comments)
ASP.NET: Writing a Custom DataControlField
03 April 2008
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);
}
(currently 0 comments)
C#: Custom Serializable Class That Inherits From DataTable
03 April 2008
To allow a custom type that inherits from System.Data.DataTable to be serializable, you must do the following:
- Add the serializable attribute to the class.
- Include a namespace reference to System.Runtime.Serialization.
- Implement the "GetObjectData" method for the ISerializable interface.
- 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)]).
(currently 0 comments)
Quicknote: Easy way to debug assemblies in the GAC
02 April 2008
When developing assemblies that are deployed to the GAC before you can test them (as is often the case with SharePoint), simply add the location of the associated pdb file(s) to the "Symbol File (.pdb) Locations" in Tools->Options->Debugging->Symbols within VS2005. (See attached screenshot)

(currently 0 comments)