Question

I've created a BCS service and created an external list from the BCS content-type. I have then tried to add a SPGridView control to a webpart. I am getting an exception as soon as I call my SPGridview's DataBind() method, here is what the code looks like:

namespace BCSService.CustomWebPart
{
    [ToolboxItemAttribute(false)]
    public class CustomWebPart : WebPart
    {
        // Visual Studio might automatically update this path when you change the Visual Web Part project item.
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/BCSShims/CustomWorkEstimateWebPart/CustomWorkEstimateWebPartUserControl.ascx";
        private SPGridView gv;
        private SPDataSource spdata;
        private SPSite site;
        private SPWeb web;
        private SPList we_list;


    protected override void CreateChildControls()
    {
        base.CreateChildControls();
        Control control = Page.LoadControl(_ascxPath);
        Controls.Add(control);

        this.site = SPContext.Current.Site;
        this.web = this.site.OpenWeb();
        this.we_list = this.web.Lists["BCSList"];

        this.spdata = new SPDataSource();
        Controls.Add(this.spdata);

        this.gv = new SPGridView();
        this.gv.AutoGenerateColumns = false;

        Controls.Add(this.gv);            
    }

    protected void BindColumns()
    {
        this.spdata.DataSourceMode = SPDataSourceMode.List;
        this.spdata.List = this.we_list;
        this.spdata.UseInternalName = true;
        this.spdata.DataBind();

        this.gv.AllowSorting = false;
        this.gv.PageSize = 200;
        this.gv.DataSource = this.spdata;

        Dictionary<string, string> listFields = new Dictionary<string, string>();
        listFields.Add("CompanyName", "Company Name");
        listFields.Add("ContactDetails", "Contact Details");
        listFields.Add("ProjectDescription", "Description");

        foreach (var row in listFields)
        {
            SPBoundField boundField = new SPBoundField();
            boundField.HeaderText = row.Value;
            boundField.DataField = row.Key;
            this.gv.Columns.Add(boundField);
        }
    }


    protected override void RenderContents(HtmlTextWriter writer)
    {

        if (!Page.IsPostBack)
        {
            this.BindColumns();
            this.gv.DataBind();
        }

        this.gv.RenderControl(writer);
    }
}

}

The DataBind() method is throwing the following exception:

Object reference not set to an instance of an object.
   at Microsoft.SharePoint.WebControls.SPDataSourceViewResultItem.System.ComponentModel.ICustomTypeDescriptor.GetProperties()
   at System.ComponentModel.TypeDescriptor.MergedTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetProperties()
   at System.ComponentModel.TypeDescriptor.GetPropertiesImpl(Object component, Attribute[] attributes, Boolean noCustomTypeDesc, Boolean noAttributes)
   at System.ComponentModel.TypeDescriptor.GetProperties(Object component)
   at Microsoft.SharePoint.WebControls.SPBoundField.DataBindingEventHandler(Object sender, EventArgs e)
   at System.Web.UI.Control.OnDataBinding(EventArgs e)
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBindChildren()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBindChildren()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.WebControls.GridView.CreateRow(Int32 rowIndex, Int32 dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState, Boolean dataBind, Object dataItem, DataControlField[] fields, TableRowCollection rows, PagedDataSource pagedDataSource)
   at System.Web.UI.WebControls.GridView.CreateChildControls(IEnumerable dataSource, Boolean dataBinding)
   at Microsoft.SharePoint.WebControls.SPGridView.CreateChildControls(IEnumerable dataSource, Boolean dataBinding)
   at System.Web.UI.WebControls.CompositeDataBoundControl.PerformDataBinding(IEnumerable data)
   at System.Web.UI.WebControls.GridView.PerformDataBinding(IEnumerable data)
   at System.Web.UI.WebControls.DataBoundControl.OnDataSourceViewSelectCallback(IEnumerable data)
   at System.Web.UI.WebControls.DataBoundControl.PerformSelect()
   at BCSService.CustomWebPart.CustomWorkEstimateWebPart.RenderContents(HtmlTextWriter writer)

I have verified that this.we_list is not empty (In Visual Studio debugger's locals tab, I can see this.we_list.Items.Count is set to 99, although this.we_list.ItemCount is set to 0.)

Also, that all seems to work okay against non-external lists, but I see nothing in the docs about external lists not being supported in SPGridView or SPDataSource, and the exception makes no mention of external lists not being supported. Has anyone run into this issue?

Was it helpful?

Solution

This seems to be a possible Sharepoint Server 2010 bug (I'm using Sharepoint Server 2010 Enterprise Edition). Ultimately, I solved the problem by adding a to_datatable() conversion method to my BCS service entity that simply uses the statis ReadList() method, collects its output, and inserts the data into a DataTable object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top