Passing Objects Between WCFs - vb.net

I have an ASP application, which calls an HTTP WCF service, which calls a TCP WCF service (all on different servers). I'm ultimately trying to pass one class object between the three.
I've discovered that I can't do this directly in the HTTP WCF, even though my class object is defined identically in BOTH WCFs. Like this:
Public Function CallOtherFunction(ByVal ThisClass as MyClass)
Dim RetVal as Boolean
RetVal = CallMyOtherWCFFunction(ThisClass)
End Function
Instead I have to:
Public Function CallOtherFunction(ByVal ThisClass as MyClass)
Dim RetVal as Boolean
Dim MyOutgoingClass as MyOtherWCF.MyClass
MyOutgoingClass.MyString = ThisClass.MyString
RetVal = CallMyOtherWCFFunction(MyOutgoingClass)
End Function
My objects are rather large, to say they have a lot of properties. Any way to not have to declare a new variable in my calling function, so my code can be a little easier (like the first example)?
Thanks,
Jason

You can't pass it directly because those are two diffrent types. You can, however, declare your data contracts in a shared assembly (used by the three projects, or at least by the HTTP and the TCP services), an when adding the service reference to create the proxy in the HTTP service, you specify that you want to "reuse types in referenced assemblies". This way it should use the same type in all projects.

Related

Value of type 'DOOD.ServiceReference1.Search' cannot be converted to 'DOOD.Search'

After adding service reference in web application it created reference.vb class with namespace
service reference1 and when i tried to assign
i created a class same as what web service is returning and assigning the object
Dim obj1 As Search
Dim obj1 = client.Search(date, name)
here i am getting Value of type 'DOOD.ServiceReference1.Search' cannot be converted to 'DOOD.Search'
how to resolve this ...
Once worked at a place where we had an app where you had to go into the Reference.vb file and remove the declaration of the classes (in your case, specifically class Search) entirely from the file -- every time you regenerated the service reference. (generally when you changed the interface to any of the functions).
The service would then return just your DOOD.Search and no typecasting issues.
The alternative is that you have to write an adapter to convert between the two.

WCF - Generic Dictionary Name Problems

So, I'm consuming a WCF service where a colleague has created functions like this:
<OperationContract()>
Function GetRelationshipsGroupedByClass(ByVal objId As Integer, ByVal showDeleted As Boolean) As Dictionary(Of String, List(Of Relationship))
When I create the service reference in my asp.net application the return type is no longer a dictionary but
ArrayOfKeyValueOfstringArrayOfRelationshipQknDUPatKeyValueOfstringArrayOfRelationshipQknDUPat
Is there any way of giving WCF a custom name to call this instead of this crazy name? Or am I going to have to rewrite all the functions that use generic dictionaries to output custom data contracts instead?
Because Dictionaries are not inherently serializable into XML , WCF converts it into an array - the array you see in your service reference. You may choose to create your own serializable dictionary - here's one, or use custom data contracts as you suggested.

Really Struggling with Class Library, How do I Handle Lazy Loading/ConnectionString in Library?

I'm really struggling to get my head around the idea of working with a Class Library and I'm pretty much at the point of just maintaining separate projects with duplicate classes rather than a shared class library.
I've created a solution that contains a single class library project and two web applications. My main problems are the connection strings. These are held/declared in the web projects and I'm having to pass them into the class library every time I perform any kind of data access. I sort of understand why I should do this so I'm going with it for the moment.
This has now led me to a problem/question with lazy loading. I'm using lazy loading for the following property:
Public Property KeyRelationshipManager() As Employee
Get
If _keyRelationshipManager Is Nothing Then
_keyRelationshipManager = Employee.GetEmployee(_keyRelationshipManagerStaffNumber)
Return _keyRelationshipManager
Else
Return _keyRelationshipManager
End If
End Get
Set(ByVal value As AECOM.Employee)
_keyRelationshipManager = value
End Set
End Property
Because this property is using the function:
Employee.GetEmployee
I need to pass in the connection string to that function.
This means I would need to pass the connection string in to the property every time I use it so I could pass it into the function.
Is this correct? It doesn't 'feel' right to me because I'm going to have to adjust a huge number of functions and property and pass through the connections string.
Why are you passing the connection string in to the class library? Use ConfigurationManager.ConnectionStrings["myClassLibraryConnection"] in your class library. As long as you have that connection string in both your host applications' config files, it should be fine. It's the web.config files' jobs to bind the configuration of different class libraries to form a single application.

type conversion from webservice object to class object

i've created bunch of classes. i have webservices which reference these classes and contains the classes as parameters and return objects.
when i call the weservice, i have to convert the class to the webservice object else i can type conversion error.
is there a generic way to convert between these types without having to assign the values by hand?
for example
public class person
fname as string
lname as string
end class
web service method
public getperson() as person
return new person()
end sub
in the client
dim ws as new webservice
dim person = ws.getperson
i would liek ot be able to call the web service and return the data type back and have a generic coversion instead of as above in stead of:
dim wsPerson as wsReference.Person = ws.getperson()
thanks
Since the generated proxy class for a web reference is a copy of the interface of the exposed class, you should be able to use reflection to do such conversions.
However, if your classes are not very large or many, I would suggest to manually create a converter that will handle conversion from web service class types to "internal" class types, and the other way around. If the number of classes is large, and if there will be new classes added regularly, or their design change, I would look into making some sort of code generator that will create the converter functionality for you.
Some of the advanced features are hard to use from vb.net, but AutoMapper will do the basic translation of Person to Person classes nicely for you.

Type casting in VB .NET

I am adding a feature to an existing VB .Net application that involves retrieving data from a .Net web service. The web service returns an array of Locations. A Location is pretty simple, it has 3 properties – an integer and two strings.
So that the rest of my application does not have to be dependent on this web service, I would like to create my own Location type within my application. My thought is I could call a method that returns a generic list of my Location type which internally calls the web service and populates the list I return. That way, if the data source for Locations changes in the future to something other than the web service, I only have to fix the method instead of fixing all the callers.
So I created my own Location that has identical properties as the service Location. But I don’t seem to be able to cast the array of service locations into a generic list of my locations. I also tried casting a single service Location into one of my Locations and that didn’t work either.
So is casting an option or do I have to loop through each service Location and assign each property to a new one of my Locations? Or is there a completely different way to go about this?
By default you will not be able to cast one Location to another. They are completely unrelated types and thus cannot be the subject of casting. You can make it possible to cast though by defining a custom operator for the application version of CType.
' Location for application
Public Class Location
...
Public Shared Operator Widening CType(p1 as Namespace.Of.WebService.Location) As Location
Dim loc = ConvertWebServiceLocationToApplicationLocation
return loc
End Operator
End Class
This allows you to now do a CType operation between a WebService Location the Application Location.
Casting the array though, simply won't be possible. There is no way to define a conversion operator for arrays so they can't use the above trick. But you can write a quick and dirty function for this purpose
Public Shared Function ConvertArray(ByVal arr As Namespace.Of.WebServiec.Location()) As Location()
Dim newArray(arr.Length) As Location
For i as Integer = 0 To arr.Length - 1
newArray(i) = CType(arr(i), Location)
Next
return newArray
End Function
Casting will not work because these are not the same type. Even if two types look exactly the same, you cannot cast from one to the other, unless you define a CType operator which describes how to transform an object from one type into an object from another type.
Even then, you cannot cast a List(of Type1) into a List(Of Type2) directly.
You will have to loop through and create a new object of your class.