Unable to generate code for a value of type 'System.Data.DataSet' exception
Messages   Related Types
This message was discovered on ASPFriends.com 'aspngcontrolscs' list.


Michael
Well... I've posted a couple of pretty simple (dare I say dumb) questions
recently, thanks Vandana for answering the last one.
Hopefully this one is a little less of a flop !!

I've created a control with a property of type DataSet. It compiles fine.
It works fine in the designer. ie when added to a web page, after creating a
dataset, I can select the dataset for my DataSource property.

However when the web application is run I'm getting an exception which I'm
unable to determine the cause of. I've tested using this same dataset with
a datagrid and it ran as expected, so I'm positive it's something to do with
my control and not the page. The exception seems to be occuring during the
compilation stage of my web application. Can anyone help me out here ?

My control's code and the exception are as follows:-

MyText.cs:-

using System;
using System.Data;
using System.ComponentModel;

namespace TestControl
{
/// <summary>
/// Test Textbox
/// </summary>
public class MyText : System.Web.UI.WebControls.TextBox
{
private DataSet _myDataSet = null;

/// <summary>
/// DataSource
/// </summary>
[Bindable(false),
Category("Data"),
DefaultValue("")]
public DataSet DataSource
{
get
{
return _myDataSet;
}

set
{
_myDataSet = value;
}
}

public void DataBind()
{
Text = _myDataSet.GetXml();
}
}
}

Exception:-

Unable to generate code for a value of type 'System.Data.DataSet'. This
error occurred while trying to generate the property value for DataSource.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Unable to generate code for a
value of type 'System.Data.DataSet'. This error occurred while trying to
generate the property value for DataSource.

Source Error:

An unhandled exception was generated during the execution of the current web
request. Information regarding the origin and location of the exception can
be identified using the exception stack trace below.

Stack Trace:

[HttpException (0x80004005): Unable to generate code for a value of type
'System.Data.DataSet'. This error occurred while trying to generate the
property value for DataSource.]

System.Web.Compilation.CodeDomUtility.GenerateExpressionForValue(PropertyInf
o propertyInfo, Object value, Type valueType)

System.Web.Compilation.TemplateControlCompiler.BuildBuildMethod(ControlBuild
er builder, Boolean fTemplate, PropertySetterEntry pse)

System.Web.Compilation.TemplateControlCompiler.BuildSourceDataTreeFromBuilde
r(ControlBuilder builder, Boolean fInTemplate, PropertySetterEntry pse)

System.Web.Compilation.TemplateControlCompiler.BuildSourceDataTreeFromBuilde
r(ControlBuilder builder, Boolean fInTemplate, PropertySetterEntry pse)

System.Web.Compilation.TemplateControlCompiler.BuildSourceDataTreeFromBuilde
r(ControlBuilder builder, Boolean fInTemplate, PropertySetterEntry pse)
System.Web.Compilation.TemplateControlCompiler.BuildMiscClassMembers()
System.Web.Compilation.PageCompiler.BuildMiscClassMembers()
System.Web.Compilation.BaseCompiler.BuildSourceDataTree()
System.Web.Compilation.BaseCompiler.GetCompiledType()
System.Web.Compilation.PageCompiler.CompilePageType(PageParser
pageParser)
System.Web.UI.PageParser.CompileIntoType()
System.Web.UI.TemplateParser.GetParserCacheItemThroughCompilation()

[HttpException (0x80004005): Unable to generate code for a value of type
'System.Data.DataSet'. This error occurred while trying to generate the
property value for DataSource.]
System.Web.UI.TemplateParser.GetParserCacheItemInternal(Boolean
fCreateIfNotFound)
System.Web.UI.TemplateParser.GetParserCacheItemWithNewConfigPath()
System.Web.UI.TemplateParser.GetParserCacheItem()
System.Web.UI.TemplateControlParser.CompileAndGetParserCacheItem(String
virtualPath, String inputFile, HttpContext context)
System.Web.UI.TemplateControlParser.GetCompiledInstance(String
virtualPath, String inputFile, HttpContext context)
System.Web.UI.PageParser.GetCompiledPageInstance(String virtualPath,
String inputFile, HttpContext context)
System.Web.UI.PageHandlerFactory.GetHandler(HttpContext context, String
requestType, String url, String path)
System.Web.HttpApplication.MapHttpHandler(HttpContext context, String
requestType, String path, String pathTranslated, Boolean useAppConfig)
System.Web.MapHandlerExecutionStep.Execute()
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&
completedSynchronously)
Reply to this message...
 
    
Dennis McCarthy
Michael,

The problem is that the web form designer is not using the data binding syntax
for the DataSource attribute of your control in the .aspx file. You need to implement
a custom control designer that "shadows" the DataSource property of your control
with a data binding. My solution to this problem, which was posted on
microsoft.public.dotnet.framework.aspnet.buildingcontrols, is inlcuded below.
(The code is in VB.NET, so you will have to translate to C# syntax.)

Dennis

----------------------------------------------------------------------------------------------------------------------

After much trial and error, along with poking around the .NET documentation,
here is the answer. This is much simpler than the "Web Forms Templated
Data-Bound Control Designer Sample" in the SDK documentation.

As Victor pointed out, you need to set the DesignerSerializationVisibility
attribute of the DataSource property to Hidden, and implement a custom control
designer.

<Designer("WebCustomControls.CustomControlDesigner"), _
ToolboxData("<{0}:DataBoundControl
runat=server></{0}:DataBoundControl>")> _
Public Class DataBoundControl
Inherits System.Web.UI.WebControls.WebControl : Implements
INamingContainer

<Bindable(True), _

DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Property DataSource() As DataSet
...

The control designer class must work with the web forms designer to
(A) write a DataSource attribute using data binding syntax to the .aspx file when the
DataSource property is set using the property window (e.g., DataSource="<%#DataSet1%>"), and
(B) inititialize the DataSource property using the DataSource attribute
value whent the web form designer opens the .aspx file.

To implement (A) you override ControlDesigner.OnComponentChanged method.
In this method you find the dataset component corresponding to the new value
of
the DataSource property, add a data binding for it, and call
OnBindingsCollectionChanged
to tell the web form designer to write the new binding to the .aspx file.

Public Overrides Sub OnComponentChanged(ByVal sender As Object, ByVal e
As System.ComponentModel.Design.ComponentChangedEventArgs)
If Not (e.Member Is Nothing) Then
Dim memberName As String = e.Member.Name
If memberName.Equals("DataSource") Then
If e.NewValue Is Nothing Then
DataBindings.Remove("DataSource")
Else
' Find the component name of the new DataSource value
Dim comp As IComponent
Dim source As String = ""
For Each comp In Me.Component.Site.Container.Components
If comp Is e.NewValue Then
source = comp.Site.Name
End If
Next
' Add a data binding for the new DataSource value
Dim binding As New DataBinding("DataSource",
GetType(AuthorTitles), source)
Me.DataBindings.Add(binding)
End If
Me.OnBindingsCollectionChanged("DataSource")
Me.UpdateDesignTimeHtml()
End If
End If
MyBase.OnComponentChanged(sender, e)
End Sub

To implement (B), you find the component whose name matches the data
binding
expression for the DataSource property, and set the DataSource property to
that
component. The trick is that this cannot be done until the web form
designer has
created both your control and the dataset component. So I put the logic to
do this
in the GetDesignTimeHtml method, and override the
DesignTimeHtmlRequiresLoadComplete
method to ensure that the GetDesignTimeHtml method is not called until after
the
dataset component has been loaded.

Public Overrides ReadOnly Property DesignTimeHtmlRequiresLoadComplete()
As Boolean
Get
' If there is a data binding for the DataSource, then the
dataset component
' must be loaded so that the DataSource property can be set.
If Me.DataBindings("DataSource") Is Nothing Then
Return False
Else
Return True
End If
End Get
End Property

Public Overrides Function GetDesignTimeHtml() As String
' Make sure that the DataSource property has been initialized.
Dim control As DataBoundControl = CType(Component, DataBoundControl)
Dim binding As DataBinding = Me.DataBindings("DataSource")
If (control.DataSource Is Nothing) And (Not binding Is Nothing) Then
Dim comp As IComponent
For Each comp In Me.Component.Site.Container.Components
If comp.Site.Name.Equals(binding.Expression) Then
' Set the DataSource to the dataset component with the
matching name.
control.DataSource = CType(comp.Site.Component, DataSet)
End If
Next
End If
...
Reply to this message...
 
 
System.ComponentModel.Design.ComponentChangedEventArgs
System.ComponentModel.DesignerSerializationVisibility
System.ComponentModel.IComponent
System.Data.DataSet
System.Web.HttpApplication
System.Web.HttpContext
System.Web.HttpException
System.Web.UI.ControlBuilder
System.Web.UI.DataBinding
System.Web.UI.INamingContainer
System.Web.UI.PageParser
System.Web.UI.TemplateControlParser
System.Web.UI.TemplateParser
System.Web.UI.WebControls.TextBox
System.Web.UI.WebControls.WebControl
System.Windows.Forms.Design.ControlDesigner




Ad
MBR BootFX
Best-of-breed application framework for .NET projects, developed by Matthew Baxter-Reynolds and MBR IT
 
 Copyright © Matthew Baxter-Reynolds 2001-2008. '.NET 247 Software Development Services' is a trading style of MBR IT Solutions Ltd.
Contact Us - Terms of Use - Privacy Policy - www.dotnet247.com