views:

241

answers:

4

I have this really random problem with is bugging me. It works at the end of the day but the problem took some time to figure out and was wondering why this happens so if anyone shed some light on the subject I would be really grateful. Here is the problem

I have the following two columns on my datagrid

<asp:boundcolumn
datafield="contentsection.Id"
headerstyle-cssclass="dgHead"
headertext="Section"
itemstyle-cssclass="dgItem" />

and

<asp:templatecolumn>
<itemtemplate><%#Eval("contentsection.Id") %></itemtemplate>
</asp:templatecolumn>

The first column gives me the error of:

A field or property with the name 'contentsection.Id' was not found on the selected data source

but the second on runs fine. Any ideas or theories as to why this is happening ?

The way that I call and bind my data is like so:

Page Load Code Behind

ContentList.DataSource = ContentBlockManager.GetList();
ContentList.DataBind();

The GetList() function it is overloaded and by default passed a 0

public static List<ContentBlockMini> GetList(int SectionId)
{
    List<ContentBlockMini> myList = null;

    SqlParameter[] parameters = { new SqlParameter("@ContentSectionId", SectionId) };

    using (DataTableReader DataReader = DataAccess.GetDataTableReader("dbo.contentblock_get", parameters))
    {
        if (DataReader.HasRows)
        {
            myList = new List<ContentBlockMini>();
        }
        while (DataReader.Read())
        {
            myList.Add(FillMiniDataRecord(DataReader));
        }
    }

    return myList;
}

and my filling of the data record. The ContentSection is another Object Which is a property of the ContentBlock object

private static ContentBlockMini FillMiniDataRecord(IDataRecord DataRecord)
        {
            ContentBlockMini contentblock = new ContentBlockMini();

            contentblock.Id = DataRecord.GetInt32(DataRecord.GetOrdinal("Id"));
            contentblock.Name = DataRecord.GetString(DataRecord.GetOrdinal("Name"));
            contentblock.SEOKeywords = DataRecord.IsDBNull(DataRecord.GetOrdinal("SEOKeywords")) ? string.Empty : DataRecord.GetString(DataRecord.GetOrdinal("SEOKeywords"));
            contentblock.SEODescription = DataRecord.IsDBNull(DataRecord.GetOrdinal("SEODescription")) ? string.Empty : DataRecord.GetString(DataRecord.GetOrdinal("SEODescription"));
            if (DataRecord.GetInt32(DataRecord.GetOrdinal("ContentSectionId")) > 0)
            {
                ContentSection cs = new ContentSection();
                cs.Id = DataRecord.GetInt32(DataRecord.GetOrdinal("ContentSectionId"));
                cs.Name = DataRecord.IsDBNull(DataRecord.GetOrdinal("ContentSectionName")) ? string.Empty : DataRecord.GetString(DataRecord.GetOrdinal("ContentSectionName"));
                contentblock.contentsection = cs;

            }
            return contentblock;
        }

There you go that is pretty much the start to end.

+1  A: 

Hey,

The DataField property approach isn't complicated enough to support dot notation; it expects a direct reference in your underlying data source; it takes that field and checks the data source, which it can't find it by the exact string.

The second approach, eval, is more dynamic, but actually I wasn't sure if it supported dot notation... learn something everyday.

HTH.

Brian
+1  A: 

Databinding can only access "top level" properties on an object. For example, if my object is Company with simple properties CompanyId and Name and a child object for Address, databinding can only access CompanyId and Name, not Company.Address.City.

Eval can access child object properties if you import the namespace using an @Import page directive.

Jamie Ide
+1  A: 

The "Bind" marker is a two-way bind and is made using the default namespace attached to the datasource of the object. This can't be overridden, and because of this tightly coupled connection the namespace should be left off as assumed (since it's dynamically pulled from the datasource).

Eval is a one-way binding that can be used with any namespace that will fulfill a proper evaluation. Dates, strings, method calls, etc. The namespace provided in your example just provides eval with a marker on where to get the data relevant.

The key here is the nature of the binding. Eval is a "fire and forget" sort of binding where as Bind is more rigid to facilitate the two-way.

Joel Etherton
A: 

It's necessary take a look to your DataSource, but you can do a simple test: convert the first column to a template column a try to Run.

In EntityFramework is possible Eval Properties using code like this: <%#Eval("Customer.Address.PostalCode") %>.

I dont know if it is your case, but if you provide more details about how to retrieve the DataSource we can help you.

Ewerton