Can a method of a webservice class be access from VB.NET client interface?

A

Andy

Make the story short, I have a VB.NET client interface calling .NET
webservice, written in VB.NET as well.

I am trying to make the client as thin as possible so I let the
webservice part to handle most of the things.

Currently I have a class called "Product" sitting my webserivce like
the following:

Code:
Imports System.Xml.Serialization

<XmlInclude(GetType(Properties)), XmlInclude(GetType(Product))> Public
Class Product
' Product properties
Public masterQty As Int32
Public cost As Double ' temperary cost, will use config costs to
replace
Public PropertyList As New ArrayList

' ArrayList stores it's component product
Public optionCondition As Int16 ' 1 = OR, 2 = AND
Public componentProduct As New ArrayList

Public Function ProductCost() As Double
Dim myCost As Double
myCost = Me.cost

' Get cost in the product ArrayList
Dim i As Int32
For i = 0 To componentProduct.Count - 1
myCost = myCost + componentProduct.Item(i).ProductCost
Next
Return myCost
End Function

Public Sub AddProduct(ByVal inputProduct As Product)
If inputProduct.GetType Is GetType(Product) Then
componentProduct.Add(inputProduct)
Else
Throw New ArgumentException("inputProduct must be of type
Product.", "inputProduct")
End If
End Sub

Public Sub AddProperty(ByVal inputProperty As Properties)
PropertyList.Add(inputProperty)
End Sub

End Class
As you can see I have 2 methods in the class let me add something call
"Product Property" and "Component Product" into the "Product" object.
And having ArrayList "PropertyList" and "componentProduct" to store
those objects

In my VB.NET Client interface, after I add the webreference, I just
realised I can declare an instance of the WebService's classes object
in my client interface like the following:

Assuming my Web Ref named "ProjectInit"
Code:
Dim myProduct As New ProjectInit.Product
Now here we go the PROBLEM!! When I try to declare a few more
webservice's Product object in my client side interface and try to
call the AddProduct methods in the Product class, it doesn't show in
the Intellsense menu I can't even call the ArrayList's Add method to
add my product object into it.

My original thought is to create and initialize an instance of the
webservice class object, with all it's component properties and
products, then I can just throw this product object to my webservice
and let the webservice to do whatever it wants with it.

Is it that you cannot call a WebService's method in a Class/Type (if
my Client side interface just Web Referenced it)? I wish I just doing
something wrong so it cause the problem. But If it's not the case,
what is the work around?

Thanks in advance.
 
A

Andy

That's the webmethod I have currently have now.

Both my webservice part and my user interface part is not complete.
The webmethod I showed you, which is not completed (that's why I
didn't posted it out). What it suppose to do is initialize the Project
object by adding Product object into the Project and jigging around
the Product object a little inside the Project.

All I really care now is: If I can call the methods I have in my
Product class from my client side UI.

<WebMethod()> Public Function ProjectInitial(ByVal inputProduct as
Project) As Project
' Webmethod for Project Initialization with inputted Product
object
Dim myProject As New Project

myProject = InitialProject(inputProduct)

Return myProject
End Function
 
C

Cor Ligthert

Andy,

You did refresh the webclass everytime that you made additions in your
client solution?

Cor
 
A

Andy

Hi Cor,

Yes I did. You mean the update web reference thingy right. I do it
everytime when I change something in WebService.
 
C

Cor Ligthert

Andy,

I have no direct answer, what I should do in your situation is creating the
smallest possible webfunction in that and see how that acts. (and that is
the hello world).

Cor

..
 
A

Andy

Hi Cor,

I just discover that:

A: A class in webservice cannot be access by the client if the class
is not used to output to the client.
B: Even you can dim a class from the client side, you cannot access to
it's method.

Sigh....

Anyway, I change my approach and I am trying to populate everything in
a ArrayList at the client side. So the webmethod in the webservice
will need to ByVal a ArrayList... but when I do that, I got this
error:

Value of type 'System.Collections.ArrayList' cannot be converted to
'1-dimensional array of System.Object

How nice :(

So I try to work around it and change the ByVal type in the webmethod
to accept an Object instead of an ArrayList... the client do
compile... but I got this error this time!!

An unhandled exception of type 'System.InvalidOperationException'
occurred in system.xml.dll
Additional information: There was an error generating the XML
document.

I am so frustrated and hope you can shed some light on me
 
C

Cor Ligthert

Andy,

Does this sample I once made help you, when not, I will make it more
particular for your situation.

\\\needs a picturebox and 4 buttons on a windowform
Private ds As New DataSet
Private abyt() As Byte
Private fo As New OpenFileDialog
Private sf As New SaveFileDialog
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'Reading a picture from disk and put it in a bytearray
If fo.ShowDialog = DialogResult.OK Then
Dim fs As New IO.FileStream(fo.FileName, _
IO.FileMode.Open)
Dim br As New IO.BinaryReader(fs)
abyt = br.ReadBytes(CInt(fs.Length))
br.Close()
'just to show the sample without a fileread error
Dim ms As New IO.MemoryStream(abyt)
Me.PictureBox1.Image = Image.FromStream(ms)
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal _
e As System.EventArgs) Handles Button2.Click
'writing a picture from a bytearray to disk
If sf.ShowDialog = DialogResult.OK Then
Dim fs As New IO.FileStream(sf.FileName, _
IO.FileMode.CreateNew)
Dim bw As New IO.BinaryWriter(fs)
bw.Write(abyt)
bw.Close()
End If
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal _
e As System.EventArgs) Handles Button3.Click
'writing a bytearray to a webservice dataset
Dim ws As New localhost.DataBaseUpdate
ws.SetDataset(abyt)
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button4.Click
'reading a picture from a webservice dataset
Dim ws As New localhost.DataBaseUpdate
abyt = ws.GetByte
Dim ms As New IO.MemoryStream(abyt)
Me.PictureBox1.Image = Image.FromStream(ms)
End Sub
End Class
////
\\\\Webservice
<WebMethod()> _
Public Function GetByte() As Byte()
Dim ds As New DataSet
ds.ReadXml("C:\wsblob.xml")
Return CType(ds.Tables(0).Rows(0)(0), Byte())
End Function
<WebMethod()> _
Public Sub SetDataset(ByVal abyte As Byte())
Dim ds As New DataSet
ds.Tables.Add(New DataTable("Photo"))
ds.Tables(0).Columns.Add(New DataColumn("Sample"))
ds.Tables(0).Columns(0).DataType = GetType(System.Byte())
ds.Tables(0).Rows.Add(ds.Tables(0).NewRow)
ds.Tables(0).Rows(0)(0) = abyte
ds.WriteXml("C:\wsblob.xml", XmlWriteMode.WriteSchema)
End Sub
////

I hope this helps?

Cor
 
A

Andy

Hi Cor,

Thanks for the example, but it's not quite what I wanted.

How about passing a type ArrayList to the webserivce?

Or, a class that's defined by me like the following:

Imports System.Xml.Serialization

<XmlInclude(GetType(ComponentProduct))> Public Class ComponentProduct
' Component General Info
Dim ComponentName As String

' Component Properties
Dim PaperGSM As Int32
Dim PaperColour As Int32
Dim PaperType As Int32
Dim PaperWidth As Int32
Dim PaperDepth As Int32
Dim Onesided As Boolean
Dim PaperThickness As Int32
Dim PaperGrainDirection As Int32
Dim NumStandardColourFront As Int32
Dim NumSpecialColourFront As Int32
Dim NumStandardColourBack As Int32
Dim NumSpecialColourBack As Int32
Dim InkCoverageScaleFront As Int32
Dim InkCoverageScaleBack As Int32
Dim ImageBleed As Boolean
Dim SpecificFrontColour1 As String
Dim SpecificFrontColour2 As String
Dim SpecificFrontColour3 As String
Dim SpecificFrontColour4 As String
Dim SpecificFrontColour5 As String
Dim SpecificFrontColour6 As String
Dim SpecificFrontColour7 As String
Dim SpecificFrontColour8 As String
Dim SpecificFrontColour9 As String
Dim SpecificFrontColour10 As String
Dim SpecificFrontColorCoverageScale1 As Int32
Dim SpecificFrontColorCoverageScale2 As Int32
Dim SpecificFrontColorCoverageScale3 As Int32
Dim SpecificFrontColorCoverageScale4 As Int32
Dim SpecificFrontColorCoverageScale5 As Int32
Dim SpecificFrontColorCoverageScale6 As Int32
Dim SpecificFrontColorCoverageScale7 As Int32
Dim SpecificFrontColorCoverageScale8 As Int32
Dim SpecificFrontColorCoverageScale9 As Int32
Dim SpecificFrontColorCoverageScale10 As Int32
Dim SpecificBackColour1 As String
Dim SpecificBackColour2 As String
Dim SpecificBackColour3 As String
Dim SpecificBackColour4 As String
Dim SpecificBackColour5 As String
Dim SpecificBackColour6 As String
Dim SpecificBackColour7 As String
Dim SpecificBackColour8 As String
Dim SpecificBackColour9 As String
Dim SpecificBackColour10 As String
Dim SpecificBackColorCoverageScale1 As Int32
Dim SpecificBackColorCoverageScale2 As Int32
Dim SpecificBackColorCoverageScale3 As Int32
Dim SpecificBackColorCoverageScale4 As Int32
Dim SpecificBackColorCoverageScale5 As Int32
Dim SpecificBackColorCoverageScale6 As Int32
Dim SpecificBackColorCoverageScale7 As Int32
Dim SpecificBackColorCoverageScale8 As Int32
Dim SpecificBackColorCoverageScale9 As Int32
Dim SpecificBackColorCoverageScale10 As Int32
Dim WorkingMethod As Int32
Dim NumberUp As Int32
Dim PageNumber As Int32
Dim FoldType As Int32
Dim FrontLaminatingType As Int32
Dim BackLaminatingType As Int32
Dim FrontVarnishType As Int32
Dim FrontVarnishCoverage As Int32
Dim BackVarnishType As Int32
Dim BackVarnishCoverage As Int32
Dim NumberOfHoles As Int32
Dim SizeOfHoles As Int32
Dim HoleCentres As Int32
Dim NumOfHorizontalPerfs As Int32
Dim NumerOfVerticalPerfs As Int32
Dim NumOfBoxes As Int32
Dim NumStartsFrom As Int32
Dim NumHorizontalCreases As Int32
Dim NumVerticalCreases As Int32
Dim PackType As Int32
Dim NumPerPack As Int32
Dim WeightEachPack As Int32
Dim DieCuttingReq As Boolean
Dim BindingType As Int32
Dim PaddingType As Int32
Dim GlueEdge As Int32
Dim TypeOfProof As Int32
Dim DesignComplexity As Int32
Dim PageMakeupComplexity As Int32
Dim ColourScanSize As Int32
Dim MonoScanSize As Int32
Dim DataType As Int32
Dim Location As String
End Class


Thanks Cor
 
C

Cor Ligthert

Andy,

It was much more work than I thought and I do not know if this is the most
sufficient however it works. (Mostly I say take a dataset however it was a
challenge)

\\\Create a webservice project, paste this.
<System.Web.Services.WebService(Namespace:="http://tempuri.org/WebServiceNew/NewService")>
_
Public Class NewService
Inherits System.Web.Services.WebService
#Region " Web Services Designer Generated Code "
-----------------------------------------------------------
<WebMethod()> _
Public Function GiveArray() As String
Dim Myarray As New ArrayList
Dim myrecord As New Myfields
myrecord.fielda = "Hello"
myrecord.fieldb = "World"
Myarray.Add(myrecord)
Dim bf As New
Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim mem As New IO.MemoryStream
bf.Serialize(mem, Myarray)
Return Convert.ToBase64String(mem.ToArray())
End Function
<Serializable()> Public Class Myfields
Public fielda As String
Public fieldb As String
End Class
End Class
///
\\\Create (Add) a new winform project
'Set in that a reference to the webserviceproject above
'Add a listbox
'Paste this code in
Private Sub Form1_Load(ByVal sender As Object, ByVal e _
As System.EventArgs) Handles MyBase.Load
Dim myservice As New localhost.NewService
Dim bf As New
Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim a As String = myservice.GiveArray
Dim mem As New
IO.MemoryStream(Convert.FromBase64String(myservice.GiveArray))
Dim myarraylist As ArrayList = _
DirectCast(bf.Deserialize(mem), ArrayList)
ListBox1.Items.Add(DirectCast(myarraylist(0), _
WebServiceNew.NewService.Myfields).fielda)
ListBox1.Items.Add(DirectCast(myarraylist(0), _
WebServiceNew.NewService.Myfields).fieldb)
End Sub
///

I hope this helps a little bit?

Cor
 
A

Andy

Hi Cor,

Sorry for troubleing you again... but it's not quite what I wanted. I
have read the reference book about "Serializable" and things like that
but it's not really helping. (Maybe it's the textbox's bad)

What I want to do is like the following... with the class I gave you
above exists in the code of the WebSerice, my WebMethod will want to
be like this:

<WebMethod()> Public Function AddComponentProduct(ByVal
productPropList As ComponentProduct, ByVal projectID As Int32) As
Boolean
' Store product into database 1st
Try
' Get each properties in the productPropList object to
' add into the database
...
...
...
Return True
Catch ex As Exception

End Try
End Function

See I wanted to pass in the class defined in the WebService

For the Client: (I rename my serivce as "ProjectInit")

Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnOK.Click
...
...
...

' post product and it's components and properties to
Webservice
Dim myService As New ProjectInit.Service1
Dim myResult As Boolean
myResult = myService.AddProductProperty(productPropertyList,
1)
if myResult
...
...
...
End if
End Sub

But when I try to passing in object like this, in the client, I can't
even get the class (even after using XmlIncluded thingy)... and in the
webservice, when I do the following:

Dim test As New ComponentProduct

I only get "GetType" as a method to call, not it's properties :(

Any idea?
 
C

Cor Ligthert

Andy,

I get more and more the idea, that you do not want to access a method from a
webservice, however use that method in your program to access clientside
data.

That is in my opinion another question of course and AFAIK always
impossible. Even if it was not a webservice but a normal service.

Cor
 

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

Top