By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,012 Members | 1,278 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,012 IT Pros & Developers. It's quick & easy.

public function from class in other namespace inaccessible

P: n/a
I have a little problem with a webservice. I reproduced the problem in the
following simplified example.

I just create a new C# ASP.NET webservice and a c# console application.
I added a new class test to the namespace of the webservice which I try to
access from the console
application.
//Service1.asmx.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;

namespace WebService2
{

public class Service1 : System.Web.Services.WebService
{
public Service1()
{
InitializeComponent();
}

#region Component Designer generated code

private IContainer components = null;

private void InitializeComponent()
{
}

protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}

#endregion

[WebMethod]
public string HelloWorld(test t)
{
return "Hello World";
}
}
public class test
{
public test(){}
public int someInt;
private int anotherInt;
public int TheInt
{
get
{
return anotherInt;
}
set
{
anotherInt=value;
}
}
public int returnInt()
{
return 4;
}

}
}


//Class1.cs
using System;
// I added Webservice2 as web reference ws1
using ConsoleApplication1.ws1;

namespace ConsoleApplication1
{

class Class1
{
static void Main(string[] args)
{
test t=new test();
int a=t.someInt;
int b=t.returnInt(); //this produces an error CS0117
Console.WriteLine("Returned value="+b.ToString());
}
}
}

2 things are bugging me:

First: it does not compile! It gives me the following error:

Class1.cs(21): error CS0117: 'ConsoleApplication1.ws1.test' does not contain
a definition for 'returnInt'

The console application does not seem to have access to the public functions
of the class test, but it does have
access to the public properties.

Is this how it is supposed to be or am I doing something wrong?
Does anyone have a solution?

Pleas don't just point me to http://support.microsoft.com/?id=821175 since I
already saw this, I
only don't see how this fits in here.

Second: why can the console application only see the class test when I use
it as a parameter
in a [webmethod]? If I remove
"test t"
from
public string HelloWorld(test t),
I get:
Class1.cs(20): The type or namespace name 'test' could not be found (are you
missing a using directive or an assembly reference?)

Nov 17 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Hello Peter,

Visual studio has written some code for you, and you are getting confused by
it.

First off, if you want to use a class to pass data to a web service, you
need to put that class into a seperate assembly and reference the assembly
from both the web service code and the client code. Do not assume that you
can define it in one and use it in the other.

A web reference is not the same as a referenced assembly. A web reference
will look at the WSDL file that was generated when the web service was
compiled. It will then WRITE CODE for you in your project. If you want to
see that code, go to the solution explorer, select the project and take a
look at the two unlabeled icons just above the treeview itself. Hover over
them to see the tooltip. One will say "Show all" or something like that.
Click it. A little "+" sign will appear next to the web reference. Expand
it and you will see the code that the web reference wrote for you.

In that code, you will see that any class that is used in a parameter, and
therefore defined in the WSDL, is described, again, in the generated code.
Note that the properties will be reproduced, but not the methods. This is
why you cannot count on the code that is generated by the web service if you
want to use an actual class to pass data.

First bit of advice: when passing data through a web service, use a
serializable object that holds data but doesn't have many methods (except
those used to access the data).

Second bit of advice: define your class in a seperate assembly and reference
it from both places.

Third bit of advice, if you want the deserializer to put data back into the
correct class, you need to study up on the correct attributes to associate
with the class itself that you use to pass data. This will allow the
serializer and deserializer to use your class without having to recode it
from the description in the WSDL file.

I hope this helps you to understand what you are seeing.

--- Nick

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
"Peter Speybrouck" <Peter Sp********@discussions.microsoft.com> wrote in
message news:A3**********************************@microsof t.com...
I have a little problem with a webservice. I reproduced the problem in the
following simplified example.

I just create a new C# ASP.NET webservice and a c# console application.
I added a new class test to the namespace of the webservice which I try to
access from the console
application.
//Service1.asmx.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;

namespace WebService2
{

public class Service1 : System.Web.Services.WebService
{
public Service1()
{
InitializeComponent();
}

#region Component Designer generated code

private IContainer components = null;

private void InitializeComponent()
{
}

protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}

#endregion

[WebMethod]
public string HelloWorld(test t)
{
return "Hello World";
}
}
public class test
{
public test(){}
public int someInt;
private int anotherInt;
public int TheInt
{
get
{
return anotherInt;
}
set
{
anotherInt=value;
}
}
public int returnInt()
{
return 4;
}

}
}


//Class1.cs
using System;
// I added Webservice2 as web reference ws1
using ConsoleApplication1.ws1;

namespace ConsoleApplication1
{

class Class1
{
static void Main(string[] args)
{
test t=new test();
int a=t.someInt;
int b=t.returnInt(); //this produces an error CS0117
Console.WriteLine("Returned value="+b.ToString());
}
}
}

2 things are bugging me:

First: it does not compile! It gives me the following error:

Class1.cs(21): error CS0117: 'ConsoleApplication1.ws1.test' does not
contain
a definition for 'returnInt'

The console application does not seem to have access to the public
functions
of the class test, but it does have
access to the public properties.

Is this how it is supposed to be or am I doing something wrong?
Does anyone have a solution?

Pleas don't just point me to http://support.microsoft.com/?id=821175 since
I
already saw this, I
only don't see how this fits in here.

Second: why can the console application only see the class test when I use
it as a parameter
in a [webmethod]? If I remove
"test t"
from
public string HelloWorld(test t),
I get:
Class1.cs(20): The type or namespace name 'test' could not be found (are
you
missing a using directive or an assembly reference?)

Nov 17 '05 #2

P: n/a
Hello,

Thanks for the thorough reply, I understand the problem now.
To solve it, I created a new class library dataLib containing the class test
from above.
I added the dll as a new reference to both projects and both have indeed
access to all properties and method.

But this brings me to a new problem.
If I define the following webmethod:
[WebMethod]
public string HelloWorld(dataLib.test b)
{
return "Hello World";
}

and try to call this webmethod like this:
dataLib.test b=new dataLib.test();
int a = b.returnInt();
Service1 myService=new Service1();
myService.HelloWorld(b);
This fails because HelloWorld is expecting an argument of type ws1.test
instead of dataLib.test.
I can solve this by creating a new object of type ws1.test and copying all
properties seperately from the object b.

Is there an easier way to pass the correct object to the webservice or to
copy all properties at once?

I suppose this is where you meant to use serializable classes, but the only
thing I can think of is to create a serializable class test and use this
class.
Then to pass the object to the webservice: serialize the object to a
SerializationInfo object and deserialize the object with the ws1.test
deserializer.

Is my thinking correct? If so, can someone give me a small example of how
exactly I can serialize and deserialize without writing it to a file?
Nov 17 '05 #3

P: n/a
There are a couple of solutions to this problem. I haven't looked into the
attributes well enough, but I'm willing to bet that there is an attribute
for this that will keep the web service proxy from regenerating the class in
the proxy code.

However, the easier way is to follow this advice that I clipped from a blog
thread:

<clip>
I am in process of solving the same problem. At present, my solution is to
manually modify the VS.NET generated client-side proxy code (Reference.cs).
I have the same assembly on both client and webservice. This assembly has a
class named DictionaryPair, which is returned by a web method. I added a
reference to my assembly to the generated proxy code, left the
[System.Xml.Serialization.XmlIncludeAttribute(typeo f(DictionaryPair))] as
is, but removed the DictionaryPair class definition from the proxy. So far
everything has compiled and my initial tests indicate things are working.

Of course the down side to this is that if (when) I regenerate the proxy due
to additions to the web service (I've really just started coding it), I will
have to manually reapply my changes. Perhaps I'll try to write a VS.NET
macro for this...
</clip>

I hope this helps

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
"Peter Speybrouck" <Pe*************@discussions.microsoft.com> wrote in
message news:D0**********************************@microsof t.com...
Hello,

Thanks for the thorough reply, I understand the problem now.
To solve it, I created a new class library dataLib containing the class
test
from above.
I added the dll as a new reference to both projects and both have indeed
access to all properties and method.

But this brings me to a new problem.
If I define the following webmethod:
[WebMethod]
public string HelloWorld(dataLib.test b)
{
return "Hello World";
}

and try to call this webmethod like this:
dataLib.test b=new dataLib.test();
int a = b.returnInt();
Service1 myService=new Service1();
myService.HelloWorld(b);
This fails because HelloWorld is expecting an argument of type ws1.test
instead of dataLib.test.
I can solve this by creating a new object of type ws1.test and copying all
properties seperately from the object b.

Is there an easier way to pass the correct object to the webservice or to
copy all properties at once?

I suppose this is where you meant to use serializable classes, but the
only
thing I can think of is to create a serializable class test and use this
class.
Then to pass the object to the webservice: serialize the object to a
SerializationInfo object and deserialize the object with the ws1.test
deserializer.

Is my thinking correct? If so, can someone give me a small example of how
exactly I can serialize and deserialize without writing it to a file?

Nov 17 '05 #4

P: n/a
Hello,

I found the blog you quoted, and it seems like I am not the only one with
this problem. I looked into your suggestion and actually got it to work.

I removed the entire occurence of the class in the reference.cs of the
client starting from
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="bla")]
public class test {
//... class properties
}
and modified the type of some arguments of methods in this file to make sure
they could find the wanted type and it works now.

Would there be a way to prevent the service from generating the class? Now I
have to change it manually everytime I update the webservice.
Nov 17 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.