How do you serialize and deserialize an enum? - vb.net

I am trying to create an enum with commands for motor control in VB.NET. I want to set the command on one computer, serialize it, send it to another computer over a TCP connection, deserialize, and interpret the command. I know how to use the TCP connection, but I'm missing conceptual knowledge about the enum. I am using Protobuf-net to serialize and have the following description of commands.
Public Class RemoteControl
<ProtoContract>
Public Class Command
<ProtoContract>
Enum CommandAction
<ProtoMember(2)>
HOME_MOTOR
<ProtoMember(1)>
MOVE_ABS
End Enum
End Class
End Class
My question is, how do I set the instance of a RemoteControl object to the action I want? I know enums use integers, so to send a MOVE_ABS (which has a tag of 1), I tried
Dim myAction As New RemoteControl
myAction.Command.CommandAction = 1
This returned an error saying "CommandAction is a type and cannot be used as an expression".
Also, once I do manage to figure out how to send this command, how would I interpret it on the other computer? Would the deserialized value of something like RemoteControl.Command.CommandAction be equal to 1 if the command sent was MOVE_ABS?

As usual, I spent days on this then figured it out immediately after making this post.
What I ended up doing was:
SERVER SIDE
Dim realProto As New RemoteControl.Command.CommandAction
realProto = RemoteControl.Command.CommandAction.MOVE_ABS
ProtoBuf.Serializer.SerializeWithLengthPrefix(myStream, realProto, ProtoBuf.PrefixStyle.Fixed32)
CLIENT SIDE
Dim readProto As New RemoteControl.Command.CommandAction
readProto = Protobuf.Serializer.DeserializeWithLengthPrefix(Of RemoteControl.Command.CommandAction)(myStream, Protobuf.PrefixStyle.Fixed32)
This then sets readProto as a RemoteControl.Command.CommandAction whose value is an integer corresponding to the action tag, or I can do readProto.ToString to view the name of the action.

Related

How do make an object (with custom data types) serializable in VB.net such that it can be converted to JSON?

I have an object that has custom data types in it. When I try to pass that object through my REST API, I get an error that says: The 'ObjectContent'1' type failed to serialize the response body for content type 'application/json; charset=utf-8'. I am assuming that the API is attempting to serialize my custom object (with custom data types) in order to convert it to JSON. Is there a way I can make this possible? I am coding in visual basic.
EDIT: I am using ASP.NET Framework 4.6.1. My object is involved with connecting to a database. Because of that, I have created custom datatypes such as databasePointer which is simply a long value. This is so I don't mix up numbers when connecting to the database. I simply need to find out how to convert those custom data types back to primitive data types before I pass my object to be serialized.
I ended up simply taking the object, running an iteration of properties (that I chose so they were primitive values), and copying them over to another object. I then passed that through and it worked fine. I had to write a class to make the conversion for the specific object, but it works well and didn't take long.
Example class:
Public Class Converter
Dim propertyKeys As New ArrayList
Private Sub InitiateKeys()
'add keys here for property names
End Sub
Public Function convertToString(ByVal order As ShopOrder) As
InitiateKeys()
Dim json As ShopOrderJSON = New ShopOrderJSON
If (IsDBNull(order)) Then
Return json
End If
Try
For Each key As String In shopOrderKeys
json.GetType.GetField(key).SetValue(json, order.GetType.GetField(key).GetValue(order).ToString)
Next
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Return json
End Function
End Class

VB.Net class property specifying an object?

I'm currently writing a HMI for an automated machine in VB.Net 2010. I have a custom class that turns a Border green or red depending on the value of an input on a remote I/O module.
The connection to the remote I/O module is through a COM object provided by the manufacturer. I have three remote connections, lets' call them g1, g2, and g3. They're of type Manufacturer.ConnectionObject.
I would like to specify, using a property that I can set in XAML, that instances of MyCustomBorder use g1, g2, or g3. Unfortunately, setting up a Property called g and typing 'g1' into the property field results in the message "Property value is not valid. Details: Property 'g' does not support String to Value conversion."
So, instead, I am left to manually set (during program startup), every single instance of MyCustomBorder:
CustomBorder1.g = g1
CustomBorder2.g = g3
CustomBorder73.g = g1
... and so on.
I am told I need to implement a converter between String and the custom class, Manufacturer.ConnectionObject, but I have no idea how to accomplish this, especially since Manufacturer.ConnectionObject is part of a closed-to-me COM object.
Help, anyone? Thanks!
Trying to directly bind a COM object into WPF is likely just going to cause you a lot of headaches. As a first step I would define a WPF friendly class which wraps instances of Manufacturer.ConnectionObject and bind that instead to WPF
Class MyConnectionObject
Public Manufacturer.ConnectionObject _connection
Public Property Value As String
Get
' Return _connection as a String
End Get
End Property
End Class
http://msdn.microsoft.com/en-us/library/aa970913.aspx

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.

Different ways to declare/define variables?

This is a VB.Net newbie question. I'm confused at the different ways to declare and define variables.
Here's an example:
Dim URL As String = http://www.c-sharpcorner.com/default.asp
Dim request As HttpWebRequest = WebRequest.Create(URL)
Dim response As HttpWebResponse = request.GetResponse()
Dim reader As StreamReader = New StreamReader(response.GetResponseStream())
When should I use 1. nothing, 2. call the Create() method, 3. Call another method of the object besides Create(), and 4. use the New word?
Most primitive types (Int32, String etc) in .Net have a literal syntax that allows to you declare a new instance. Where this is available, it should probably be your first choice. Your URL variable from above would be an example of this.
Your next choice would probably be the New keyword. This is good where the type that you are trying to instantiate is known at design time. This might not be appropriate for example if you are just trying to instantiate an instance of a type that implements an interface but do not care about the concrete type of the object that is returned.
A design pattern that you can use in this case (the type is not known at design time) is the Factory Method. The way that the Factory Method is initialized, can influence the type of the object that it returns.
If a class does not have an externally visible constructor then it is probably because the developer of that class wanted to reserve the right to decide at runtime which type he will return. In this case, he will generally provide a Factory Method (prefixed with the Create keyword by convention). The method will not necessarily be on the class that you are trying to instantiate but might be added to some other class in the API that has the context required to firstly make the decision as to which concrete class to return and secondly has the ability to provide the necessary dependencies to create the object.
In summary your decision path should probably be..
Literal
Constructor
Factory Method
As an interesting aside - the DateTime data type is a case where VB.Net has a literal syntax and C# does not. The 31st of May 1999 can be instantiated as a DateTime object in VB.Net using the syntax #5/31/1993#. To instantiate the same date value in C# would require the use of the constructor new DateTime(1999, 5, 31).

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.