ObjectDataSource, DataObjectTypeName and '...could not find a non-generic method ...'

K

Kernel Bling

Hi Everyone,
This Saturday the stage was set. The problem simply could not go on
existing -- it had to be solved. Many hours, articles, compilations
and frustrations later I still did not find an answer. Even pacing
around my flat until I nearly went into an altered state of reality
proved futile.

So here is the problem...

When I link up the ObjectDataSource UpdateMethod to a method in the
TypeName class that takes individual parameters (using
'<UpdateParameters> ... </UpdateParameters>') all is well. Eg.

<asp:ObjectDataSource ID="ObjectDataSource1"
Runat="server"
EnableCaching="false"
TypeName="RecipeToolUI.MaterialComponent"
SelectMethod="GetMaterials"
UpdateMethod="UpdateMaterial"
OldValuesParameterFormatString="{0}"
<UpdateParameters>
<%-- just a lot of prameters --%>
</UpdateParameters>
</asp:ObjectDataSource>

When I try to link up a method that takes an object (using
DataObjectTypeName) instead of individual value types like this:

...
DataObjectTypeName='RecipeTool.Material'
...

I keep on getting this error:
"""
ObjectDataSource 'ObjectDataSource1' could not find a non-generic
method 'UpdateMaterial' that takes parameters of type
'RecipeTool.Material'.
"""

Things I have tried (besides the pacing):
0. Using only VS 2005 to link things up.

1. Adding attributes to the UpdateMethod method in the
DataObjectTypeName class, as well as to the class itself.

This only resulted in VS seeing the method (in the ObjectDataSource
configuration wizard), but it does not solve the problem.

2. Tried various method signatures.

3. Deleted the Asp.Net temporary files.

4. Changed namespaces, method names, class names. This proved that
the compiler/runtime can find the class, but not the method.

Any suggestions or help will be greatly appreciated.

Regards.
 
M

Muhammad Naveed Yaseen

Are you using OldValuesParameterFormatString?

If so, are you providing a method
RecipeToolUI.MaterialComponent.UpdateMaterial which takes both old and
new values?
 
K

Kernel Bling

Are you using OldValuesParameterFormatString?

If so, are you providing a method
RecipeToolUI.MaterialComponent.UpdateMaterial which takes both old and
new values?

Hi, thanks for responding hey!

I have used OldValuesParameterFormatString="{0}", and left it out
completely, while specifying ConflictDetection="OverwriteChanges".
This should cause the runtime to request a function taking a single
object argument (that specified in DataObjectTypeName) as parameter.

I have also tried setting OldValuesParameterFormatString="{0}", and
leaving it out, while setting ConflictDetection="CompareAllValues" and
then I also provided (in addition to the single object parameter
method) a method taking two objects (just as the docs say, one for the
old, one for the new values).

It seems to me as if the way the runtime looks up methods when you
specify DataObjectTypeName, as apposed to when you provide
'<UpdateParameters> ... </UpdateParameters>' differ.


I have also noticed the following. When trying to configure the
ObjectDataSource in VS, two entries for the business objects appear in
the dropdown lists (eg. when selecting what object the
ObjectDataSource must use for the TypeName, there are two entries for
RecipeTool.Material, and all the other objects in namespace
RecipeTool).

Could it be due to two versions of everything in RecipeTool being
visible to the runtime, and that for some reason, using
DataObjectTypeName (as apposed to specifying UpdateParameters) makes
the ObjectDataSource choose the wrong DataObjectTypeName to look for
while trying to identify the right method to call in class specified
by TypeName?

In other words, the 'public void UpdateMaterial (Material m)' method
in the TypeName class 'MaterialComponent' use one version of the
'Material' class, while the ObjectDataSource's DataObjectTypeName
refers to another version of the 'Material' class?

How can I check this? How can I remove the extra classes (that might
be causing the problem)?

Thanks in advance again!
 
M

Muhammad Naveed Yaseen

Have you ensured that

1) The type 'RecipeTool.Material' is constructible without parameter
(i.e. it's default public parameterless contructor isn't suppressed by
presence of parameter constructors or private parameterless
constructor)

2) The type 'RecipeTool.Material' has matching public get-set
properties for all fields with exact spelling match

3) If InsertMethod or DeleteMethod are being called, those are also
using same type (RecipeTool.Material)

4) The methods SelectMethod, InsertMethod and DeleteMethod are public
and either,,,

a) static
b) OR public parameterless constructor is not suppressed by presence
of parameter constructors or private parameterless constructor.
c) OR an object instance provided in ObjectCreating event

If it is still not working with these conditions being true, I would
be keen to look into the code. Kindly post here or drop at
(e-mail address removed)


Regarding the two types you are seeing in VS, if the leading
namespaces before these two types are same, then that is not a
problem. Sometimes VS does pick up same type more than once during
recursion. However if leading namespaces are different then that is
not right.
 
K

Kernel Bling

Have you ensured that

1) The type 'RecipeTool.Material' is constructible without parameter
(i.e. it's default public parameterless contructor isn't suppressed by
presence of parameter constructors or private parameterless
constructor)

2) The type 'RecipeTool.Material' has matching public get-set
properties for all fields with exact spelling match

3) If InsertMethod or DeleteMethod are being called, those are also
using same type (RecipeTool.Material)

4) The methods SelectMethod, InsertMethod and DeleteMethod are public
and either,,,

a) static
b) OR public parameterless constructor is not suppressed by presence
of parameter constructors or private parameterless constructor.
c) OR an object instance provided in ObjectCreating event

If it is still not working with these conditions being true, I would
be keen to look into the code. Kindly post here or drop at
(e-mail address removed)

Regarding the two types you are seeing in VS, if the leading
namespaces before these two types are same, then that is not a
problem. Sometimes VS does pick up same type more than once during
recursion. However if leading namespaces are different then that is
not right.

Hi Muhammad,
Thanks again for your help, I really appreciate it. It would be hard
to give you relevant code samples short of giving you the whole
project because things are tied up a bit.

I have carefully confirmed that all of the above assertions are true.
While reading through a sample of what I want to do, I saw that the
sample place the TypeName class in the App_Code folder, while mine is
in a folder just off the root of the project.

After placing It in App_Code I got an error I had long before (which I
solved back then by taking the code out of App_Code):

"Unable to cast object of type 'RecipeTool.Logic.Material' to type
'RecipeTool.Logic.Material'.".

(I added the 'Logic' namespace a bit earlier, placing all the logic
classes there, but it could just as well not be there -- does not
influence anything.)


This error is thrown from within the method I could not get at before,
(the UpdateMethod), but now the SelectMethod also throws this error at
spots where I try to cast from objects returned by NHibernate -- a
kind of ORM library I am using. Note that the SelectMethod and
UpdateMethod (with value type parameters) both work fine while the
class they are in is not in App_Code.

I strongly suspect there being two versions of Material, but how can I
remove the one?
 
M

Muhammad Naveed Yaseen

One possible place where shadow copy of a type may exist is asp.net
compiler cache (usually C:\windows\Microsoft.NET\Framework
\v2.0.50727\Temporary ASP.NET Files).

If I would be in this situation I would have proceeded like following.

1) Ensure that type 'RecipeTool.Logic.Material' has public scope and
not internal (i.e. ***public*** class Material,,, instead of class
Material)

2) Delete contents of C:\windows\Microsoft.NET\Framework
\v2.0.50727\Temporary ASP.NET Files (may have to stop IIS or restart
computer to delete contents)

3) Now compile again and see if we still get the error.

4) If still getting error, then take the grid and object to a new
temporary working solution (remove all dependancies, as purpose here
is not make it 100% in temporary solution but to find out which
component is causing shadow copy)

5) After ensuring simple most version is working in temporary
solution, would add other components to this solution, and after each
addition see if it is still working. Wherever it stop working, that
component may be the culprit (perhaps an undetected cricular
reference, or too deeply nested types/controls)
 
K

Kernel Bling

One possible place where shadow copy of a type may exist is asp.net
compiler cache (usually C:\windows\Microsoft.NET\Framework
\v2.0.50727\Temporary ASP.NET Files).

If I would be in this situation I would have proceeded like following.

1) Ensure that type 'RecipeTool.Logic.Material' has public scope and
not internal (i.e. ***public*** class Material,,, instead of class
Material)

2) Delete contents of C:\windows\Microsoft.NET\Framework
\v2.0.50727\Temporary ASP.NET Files (may have to stop IIS or restart
computer to delete contents)

3) Now compile again and see if we still get the error.

4) If still getting error, then take the grid and object to a new
temporary working solution (remove all dependancies, as purpose here
is not make it 100% in temporary solution but to find out which
component is causing shadow copy)

5) After ensuring simple most version is working in temporary
solution, would add other components to this solution, and after each
addition see if it is still working. Wherever it stop working, that
component may be the culprit (perhaps an undetected cricular
reference, or too deeply nested types/controls)

I tried deleting the temp files before but will give it a go again,
thanks.
From some debug printouts at the point where the cast fails I saw that
the two objects came from different assemblies.
The one instanciated from within code in App_Code came from a
'App_Code.asdfsd' assembly, and the one loaded from the NHibernate
classes (called in App_Code, but through the NHibernate classes)
belonged to the proper 'RecipeTool' assembly -- will post the details
later -- so I can understand why they can't be casted.

Now my question is how to force code to use the proper 'RecipeTool'
assembly instead of the `on-the-fly` generated assemblies... I would
really like to know which VS solution template to use for what
situation or, better still, how to compile things by use of the
command line tools, or the msbuild tools so that one can have a solid
control of what is compiled and where.

There is a reason why tools like Ant exists: building anything larger
than a couple of files becomes complicated. Have seen NAnt, which I
assume to be a .Net port of Ant?
 
K

Kernel Bling


Good news!! I think I found a solution!

At the point where the cast failed, I managed to get debug output (by
printing 'typeof(Material).AssemblyQualifiedName' and 'q.List()
[0].GetType().AssemblyQualifiedName'):
-----
RecipeTool.Logic.Material, App_Code.-0vbez6p, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
RecipeTool.Logic.Material, RecipeTool, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
----
(the list 'q' contains the loaded objects)

Then I followed these steps:
created a new "C# Web Application Project"
copied everything relevant in
made sure it compiles
"Build" "Publish RecipeTool"
create a virtual directory there where I just published
brows to that virtual directory

and it works!

Now the debug output gives:
----
RecipeTool.Logic.Material, RecipeTool, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
RecipeTool.Logic.Material, RecipeTool, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
----

Still need to test if everything is solved now, but it looks like the
ObjectDataSource now correctly identifies the UpdateMethod.

Thank you very much for the help man!

Until next problem , all the best.
 
G

Guest

I, too have been wrestling with this one for quite some time and finally
found a solution last night.

The problem seems to occur when you create a selection statement in the
table adapter that uses more fields than the update statement uses. When you
update, it is still seeking for the parameter that the select statement uses,
even when you have removed all other references to it.

I tried everything I ever found posted online for this one to no avail.
Finally, I ended up building a stored procedure for my update statement, and
here's the key... I included in the stored procedure a reference to the
parameter that was not used, but then I simply did nothing with that
parameter in my update statement. This way, .NET was happy because it passed
the parameter, and the update statement ran okay because it did nothing with
the parameter other than capture it in the stored procedure.

Hopefully this will save someone all the time that it cost me to figure it
out!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top