I am not new to OOP, but am new to Reflection. I'm sure I'm missing something simple and have experimented for some time before posting.
I have been trying to get access to a field, both get and set, its value. The issue is the field is within property of a class within a property of a class.
The following code gets an existing window and works deeper into the classes until I hit a wall.
Ultimately I want to get and set "k_LineHeight" inside of an existing instance of TreeViewGUI.
The following code is heavily annotated. Thank you for taking the time to look at this. In Unity's Mono Debug.Log() is the equivalent of write to the console.
// Get the assembly
Assembly asm = typeof(UnityEditor.EditorWindow).Assembly;
Debug.Log (asm + "\n"); // returns -> UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// Get the Type of SceneHierarchyWindow from 'asm'
Type wndType = asm.GetType("UnityEditor.SceneHierarchyWindow");
Debug.Log (wndType + "\n"); // returns -> UnityEditor.SceneHierarchyWindow <- Type
// 'GetWindow' retrieves the ACTIVE instance of the windows currently open
EditorWindow wnd = EditorWindow.GetWindow(wndType);
Debug.Log (wnd + "\n"); // returns -> U (UnityEditor.SceneHierarchyWindow) <- Active Object
// Retrieves the ACTIVE TreeView class stored in 'treeView' from 'wnd'
var treeViewVal = wndType.GetProperty("treeView", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(wnd, null);
Debug.Log (treeViewVal + "\n"); // returns -> UnityEditor.TreeView
// Retrieves the property 'state' that is (public TreeViewState state { get; set; }) inside of 'treeViewVal'
var stateVal = treeViewVal.GetType().GetProperty("state").GetValue(treeViewVal, null);
Debug.Log (stateVal + "\n"); // returns UnityEditor.TreeViewState
// Retrive the value of the field 'scrollPos' (public Vector2 scrollPos;) inside of the 'stateVal'
var v2 = (Vector2)stateVal.GetType ().GetField ("scrollPos").GetValue (stateVal);
Debug.Log (v2 + "\n"); // returns -> (0.0, 0.0)
/// ALL OF THE ABOVE WORKS AS EXPECTED THE FOLLOWING IS WHERE IM STUMPED ///
// Retrieves the property 'gui' that is ( internal class GameObjectTreeViewGUI : TreeViewGUI) inside of 'treeViewVal'
var guiVal = treeViewVal.GetType().GetProperty("gui").GetValue(treeViewVal, null);
Debug.Log (guiVal + "\n"); // returns -> UnityEditor.GameObjectTreeViewGUI <- Type but I believe I need the Object
// THIS is where I'm stuck...
// Should retrieve the value of the field 'k_LineHeight' (protected float k_LineHeight = 16f;) inside of 'TreeViewGUI' the
var k_Line = guiVal.GetType().GetField ("k_LineHeight").GetValue (guiVal);
Debug.Log (k_Line + "\n"); // returns -> NullReferenceException: Object reference not set to an instance of an object
// If I attempt to ...
Type testType = guiVal.GetType ();
object test = Activator.CreateInstance(testType);
Debug.Log (test + "\n"); // returns -> Method not found: 'Default constructor not found...ctor() of UnityEditor.GameObjectTreeViewGUI'.
UPDATE :
// ORIGINAL LINE
var k_LineA = guiVal.GetType().GetField ("k_LineHeight").GetValue(guiVal);
Debug.Log (k_LineA + "\n"); // returns-> Object reference not set to an instance of an object.
// SUGGESTED PART ONE
var k_LineB = guiVal.GetType().BaseType;
Debug.Log (k_LineB + "\n"); // returns -> UnityEditor.TreeViewGUI <- This is correct
// SUGGESTED PART TWO - > Have tried with an without various flags
var k_LineC = guiVal.GetType().BaseType.GetField("k_LineHeight", BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.NonPublic |
BindingFlags.Public).GetValue(guiVal);
Debug.Log (k_LineC + "\n"); // returns -> Object reference not set to an instance of an object.
// GetValue wants guiVal to be an object???
// First part of UnityEditor.TreeViewGUI Class
namespace UnityEditor
{
internal abstract class TreeViewGUI : ITreeViewGUI
{
protected PingData m_Ping = new PingData();
private bool m_AnimateScrollBarOnExpandCollapse = true;
protected float k_LineHeight = 16f;
protected float k_BaseIndent = 2f;
protected float k_IndentWidth = 14f;
protected float k_FoldoutWidth = 12f;
protected float k_IconWidth = 16f;
protected float k_SpaceBetweenIconAndText = 2f;
protected float k_HalfDropBetweenHeight = 4f;
protected TreeView m_TreeView;
...
Thanks to your suggestion I am now into the proper class. Feel silly I didn't think of that. Unfortunately its still returning the same during access. GetValue wants guiVal to be an object???
Seems closer, anyone have additional thoughts?
You are trying to log an Object and not a Type.. Type is an attribute of an object defining what kind of type the object is, while Object is the class
k_LineHeight isn't a field in UnityEditor.GameObjectTreeViewGUI.
https://github.com/MattRix/UnityDecompiled/blob/master/UnityEditor/UnityEditor/GameObjectTreeViewGUI.cs
GameObjectTreeViewGUI inherits from TreeViewGUI. I googled and didn't find the source for that. But assuming that it is a field in TreeViewGUI you could do
var k_Line = guiVal.GetType().BaseType.GetField ("k_LineHeight").GetValue (guiVal);
^^^
ANSWER : The "Update" on my side had a typo. The answer to this is the one is a combination of both TheHenny's and Scott's. I was attempting to access a variable only visible in the BaseType. Thank you both!
Final code:
var k_LineC = guiVal.GetType().BaseType.GetField("k_LineHeight", BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.NonPublic |
BindingFlags.Public).GetValue(guiVal);
Debug.Log (k_LineC + "\n"); // <-- returns 16
Related
I'm trying using gRPC dynamically typed values but with the little information about their usefulness, It's almost impossible to do this... So I will show the image/code that I have problems and the questions that are eating my brain
gRPC Method I'm doing:
public override Task<HelloReply2> TestObject(Status request, ServerCallContext context) {
//The part I may have problems
var status = new Status();
//here I want a User that corresponds to my request.Data
//example -> request.Data = User1 (gives me null if User1 don`t exist in db)
// request.Data = 14 (gives me null if 14 don`t exist in db)
// request.Data = true (gives me null if true don`t exist in db)
var a1 = _context.Users_5.FirstOrDefault(x => x.Username.Equals(request.Data));
var b1 = _context.Users_5.FirstOrDefault(x => x.Email.Equals(request.Data));
var c1 = _context.Users_5.FirstOrDefault(x => x.Age.Equals(request.Data));
var d1 = _context.Users_5.FirstOrDefault(x => x.Test.Equals(request.Data));
//is a bool
//here i want too Create dynamic values
status.Data = Value.ForStruct(new Struct {
Fields =
{
["Integer"] = Value.ForNumber(c1!.Age),
["StringName"] = Value.ForString(a1!.Username),
["StringEmail"] = Value.ForString(b1!.Email),
["Boolean"] = Value.ForBool(d1!.Test)
}
});
//Below is just a simple string who gives different string (depending on the
//data Status (also how to read the message from the status.Data ?)
HelloReply2 hello = new();
if(a1 != null)
{
hello.Message = "There is a User with the Username " + request.Data + ". His Email is " + a1.Email;
} else if (b1 != null) {
hello.Message = "There is a User with the Email " + request.Data + ". His Username is " + b1.Username;
}
else if (c1 != null)
{
hello.Message = "There is at least one User with that Age of " + request.Data + ". His Username is " + c1.Username;
}
else if (d1 != null)
{
if(d1.Test == true)
{
hello.Message = "There is at least one User who dislikes chocolate: " + request.Data + ". His Username is " + d1.Username;
} else
{
hello.Message = hello.Message = "There is at least one User who likes chocolate: " + request.Data + ". His Username is " + d1.Username;
}
}
else
{
hello.Message = "We didn't find something with the value that the User put in. Value:" + request.Data;
}
return Task.FromResult(hello);
}
Questions: How to Get the one Value from my gRPC? How to convert a "Object" in c# (one string, one integer or one List) into a ONE value of google.protobuf.Value (so it not give me errors like this Controller from a Web Api below)? Is something wrong with my gRPC Service Method (is something wrong reading the dynamic values? Can I do that calls for getting a User for a DB? How to read dynamic values?)
// I try using Google.Protobuf.WellKnownTypes.Value obj but
//not workings because gives me a lot of values to put
[HttpGet("TypeObject/{obj}")]
public async Task<ActionResult<HelloReply2>> TypeObject([FromRoute] Object obj){
Status objRequest = new Status { Data = (Google.Protobuf.WellKnownTypes.Value)
obj };
//cannot do this (gives me error of casting but the ideia is doing something
//similar to this)
var hello = await _greetClient.TestObjectAsync(objRequest);
return Ok(hello);
}
Any help on how to resolve this error of using Value gRPC or if is something wrong with the code is always welcome.
Edit:
One day after this question I don't have any solutions / progress. I was think of doing Any or OneOf for testing but it also gives me errors (who don't make sense at all). This code from Microsoft (C# Format part is not recognize) doesn't work in my project with the protos reload (the problem is not in the protos)
Link: https://learn.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/protobuf-any-oneof
How I can use Any / OneOf without give me error in the Formating? What is the difference between Value and this two? Can the three (Value, Any, OneOf) be dynamic/Object values (if yes how to convert the types)?
Edit 2:
Still have problems, I'm trying using gRPC Any , and maybe have some progress (not all).
So with Any I have my method in the server gRPC and it is like this
public override Task<HelloReply2> TestObject3(AnyMessage request, ServerCallContext context){
HelloReply2 anyMessageResponse;
var y = request.TypeUrl;
switch (request.TypeUrl)
{
case "type.googleapis.com/any.HelloRequest":
var string_1 = request.Unpack<HelloRequest>();
anyMessageResponse = new HelloReply2{
Message = "You type String: " + $"{string_1.Name}"
};
break;
case "type.googleapis.com/any.TestInteger1":
var integer_1 = request.Unpack<TestInteger1>();
anyMessageResponse = new HelloReply2{
Message = "You type Integer: " + $"{integer_1.Message}"
};
break;
case "type.googleapis.com/any.TestBool1":
var bool_1 = request.Unpack<TestInteger1>();
anyMessageResponse = new HelloReply2{
Message = "You type Bool: " + $"{bool_1.Message}"
};
break;
default:
throw new InvalidOperationException("Unexpected type URL.");}
return Task.FromResult(anyMessageResponse);
}
This ideia comes from here (https://github.com/grpc/grpc-dotnet/issues/917), but the client part their don't have any much info or I don't understand that part
This is what I did in the WebApi (who is my client and the code is similar to the above one)
using AnyMessage = Google.Protobuf.WellKnownTypes.Any;
[HttpGet("TypeObject3/{obj3}")]
public async Task<ActionResult<HelloReply2>> TypeObject3([FromRoute] string obj3)
{
AnyMessage objRequest = new() { TypeUrl = obj3 };
var hello = await _greetClient.TestObject3Async(objRequest);
var l = hello.Message;
return Ok(hello);
}
First I had the variable Any declared in the method instead of string but as you can only put string and stringBytes so I preferred to put it like this (with the string as an obj3 variable) but my goal is to see if the variable is of type TestBool1 or TestInteger1 as I have declared in the protos and not be a string that I will be able to see, and the biggest problem was if I had more variables inside the messages how to proceed? So my secondary question is how to use Any on the client side via the Web-Api? I forgot to say but I'm using .Net 6 Core and for testing I'm using Swagger, where at this moment my error hits the Exception dictated by the Server method.
Questions: Why TypeUrl is a string and not object? How to fix my problem? How to test the object type (or string) for more values if the messages was with 1 more types?
Also I will show my test proto too show how I'm doing this
import "google/protobuf/struct.proto";
import "google/protobuf/any.proto";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayNormalHello (Empty_2) returns (HelloReply);
rpc SayHello (HelloRequest) returns (HelloReply2);
rpc TestInt (TestInteger1) returns (HelloReply2);
rpc TestBoolean (TestBool1) returns (HelloReply2);
rpc TestObject (Status) returns (HelloReply2); //Not working
rpc TestObject2 (Status2) returns (HelloReply2); //Not working
rpc TestObject3 (google.protobuf.Any) returns (HelloReply2); //Also
//Not working
}
message Empty_2{
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
// The response message containing the greetings.
message HelloReply2 {
string message = 1;
}
message TestInteger1 {
int32 message = 1;
}
message TestBool1 {
bool message = 1;
}
message Status {
google.protobuf.Value data = 1;
}
message Status2 {
google.protobuf.Any data = 1;
}
Any help is welcome.
In the project I developed, I needed an infrastructure where I could perform dynamic operations such as REST service using gRPC. As I understand it, what you want is something similar to this.
I have developed a solution for this. It might work for you too.
You can gain some flexibility by making a definition with a single String field for Requests and Responses that you want to be Dynamic, and then using this field to hold JSON data as strings.
For example, instead of defining different responses for different types, you can solve it by making one definition like this.
message HelloReply {
// Stringified JSON Data
string data = 1;
}
e.g. I want to select a character and save his number
private Storage storage;
void Awake()
{
storage = new Storage();
}
public void SelectChar1()
{
numberChar = 1;//byte
storage.Save(DataPlayerSave);//save works fine
}
on awakening, the number is loaded
private DataPlayerSave dataPlayer;
private byte numberChar;
private void Awake()
{
dataPlayer = (DataPlayerSave)storage.Load(new DataPlayerSave());
numberChar = dataPlayer.numerChar;
}
I tried to divide the data into several parts and one large file, the result is almost always the same (sometimes everything works)
public class Storage()
{
public object Load(object saveDataByDefault)
{
filePath = Application.persistentDataPath + "/saves/GameSave.save";
if (!File.Exists(filePath))
{
if (saveDataByDefault != null)
{
Save(saveDataByDefault);
return saveDataByDefault;
}
}
var file = File.Open(filePath, FileMode.Open);
var saveData = formatter.Deserialize(file);
file.Close();
return saveData;
}
}
There are also similar classes that load data at the beginning of the scene. If there are 2 or more of them, then it gives an error, if 1, then everything works. I tried to set the sequence using the Coroutine did not help.
When loading data it gives an error "InvalidCastException: Specified cast is not valid."
dataPlayer = (DataPlayerSave)storage.Load(new DataPlayerSave());
if formatter is BinaryFormatter: please don't do that - it will hurt you; as for the exception: fundamentally, use a debugger and step through the code. In particular, if you say that the exception is coming from:
dataPlayer = (DataPlayerSave)storage.Load(new DataPlayerSave());
then we can assume that Load is not returning a DataPlayerSave. So: what is it? We can't tell you, but: you can find out:
var obj = storage.Load(new DataPlayerSave());
var type = obj.GetType(); // put a break-point here
Log(type.FullName); // or just log it
dataPlayer = (DataPlayerSave)obj;
and investigate what exactly obj is. Note that BinaryFormatter is very brittle as you change types (rename, move, refactor, etc) - but that isn't even the top reason not to use it.
I am using the onNavigate method in windows phone 8.1 and trying to pass a list of navigation objects I have created. When I try and retrieve the list from e.parameters (which seems to work) I cannot iterate through the list and cast them back to the original object types. It works if I send a single object but not a list.
For Example.
From a button_click event on the mainpage I am calling the code below to navigate to page2 and pass a list of objects.
I have a class defined as below.
class NavigationContext
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
For testing I create 3 objects and add it to a list as follows
NavigationContext navobj = new NavigationContext(){ID = 77,Name = "DN", Description = "TD1"};
NavigationContext navobj2 = new NavigationContext(){ID = 22,Name = "JN",Description = "JD1"};
NavigationContext navobj3 = new NavigationContext(){ID = 22,Name = "CN",Description = "CN1"};
I then create the list as below
List<NavigationContext> navlist = new List<NavigationContext>(){navobj,navobj2,navobj3};
I then Make the call below
Frame.Navigate(typeof(Page2), navlist);
If I pass one object the code works and compiles and the new page is navigated too sucessfully*
**If I pass a list as above I get the following error on the foreach iterator in the OnNavigatedTo method
**Example code below*
string myfiller = "";
foreach (NavigationContext navobj in e.Parameter)
{
myfiller += navobj.ID.ToString() + " " + navobj.Name + " " + navobj.Description+ "\n";
}
I get the following error:
foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for GetENumerator.
I have tried to find ways to cast the list back to NavigationContext objects but I think I am doing something stupid because I cann0t get it to work.
Any suggestions?
Try this:
List<NavigationContext> navigationObjects = e.Parameter as List<NavigationContext>;
if(null != navigationObjects)
{
foreach (NavigationContext navobj in navigationObjects)
{
myfiller += navobj.ID.ToString() + " " + navobj.Name + " " + navobj.Description+ "\n";
}
}
Note that if the e.Parameter object cannot be interpreted as the correct type (a List<NavigationContext>) then using the as operator will result in a null value that can be tested to prevent further problems when you try to use the elements of the list as NavigationContext objects.
Update: A fix has now made it's way into mono. This is good news!
Updated: Added logic to fix fragment handling.
I am trying to send a request with an encoded slash on Mono using the Uri class. This is basically the Mono equivalent of this question: GETting a URL with an url-encoded slash
The issue is that Mono similar to .NET will unescape any slashes it finds in the Uri when it is constructed. This logic was originally put in in place in order to remove vulnerabilities that could occur if paths were escape encoded and not detected.
In the previous post there is a hack which shows setting flags on the underlying Uri class via reflection which force the escaped slashes to be left alone. This behavior has been fixed in .NET 4.5 and by default the escaped slashes are allowed (as I mentioned in the comments).
I tried to do the same on Mono, but it fails as the internals of the Uri class are different. I came up with this approach to achieve what I want, which works but it is TERRIBLY hacky.
class Program
{
static void Main(string[] args)
{
var uri = new Uri("http://www.yahoo.com/%2F?Foo=Bar%2F#frag");
UriHelper.ForceCanonicalPathAndQuery(uri);
Console.WriteLine ("uri.ToString() - " + uri.ToString ());
Console.WriteLine ("uri.AbsoluteUri - " + uri.AbsoluteUri);
Console.WriteLine ("uri.Host - " + uri.Host);
Console.WriteLine ("uri.Query - " + uri.Query);
Console.WriteLine ("uri.PathAndQuery - " + uri.PathAndQuery);
Console.WriteLine ("uri.AbsolutePath - " + uri.AbsolutePath);
Console.WriteLine ("uri.Fragment - " + uri.Fragment);
}
public class UriHelper {
private static Type uriType = typeof(Uri);
private static FieldInfo sourceField;
private static FieldInfo queryField;
private static FieldInfo pathField;
private static FieldInfo cachedToStringField;
private static FieldInfo cachedAbsoluteUriField;
static UriHelper ()
{
sourceField = uriType.GetField ("source", BindingFlags.NonPublic | BindingFlags.Instance);
queryField = uriType.GetField ("query", BindingFlags.NonPublic | BindingFlags.Instance);
pathField = uriType.GetField ("path", BindingFlags.NonPublic | BindingFlags.Instance);
cachedToStringField = uriType.GetField ("cachedToString", BindingFlags.NonPublic | BindingFlags.Instance);
cachedAbsoluteUriField = uriType.GetField ("cachedAbsoluteUri", BindingFlags.NonPublic | BindingFlags.Instance);
}
public static void ForceCanonicalPathAndQuery(Uri uri)
{
var source = (string) sourceField.GetValue (uri);
cachedToStringField.SetValue (uri, source);
cachedAbsoluteUriField.SetValue (uri, source);
var fragPos = source.IndexOf ("#");
var queryPos = source.IndexOf ("?");
var start = source.IndexOf (uri.Host) + uri.Host.Length;
var pathEnd = queryPos == -1 ? fragPos : queryPos;
if (pathEnd == -1)
pathEnd = source.Length+1;
var path = queryPos > -1 ? source.Substring (start, pathEnd - start) : source.Substring (start);
pathField.SetValue (uri, path);
queryField.SetValue(uri, fragPos > -1 ? source.Substring(queryPos, fragPos - queryPos) : source.Substring(queryPos));
}
}
}
When you run this, it outputs the following:
uri.ToString() - http://www.yahoo.com/%2F?Foo=Bar%2F#frag
uri.AbsoluteUri - http://www.yahoo.com/%2F?Foo=Bar%2F#frag
uri.Host - www.yahoo.com
uri.Query - ?Foo=Bar%2F
uri.PathAndQuery - /%2F?Foo=Bar%2F
uri.AbsolutePath - /%2F
uri.Fragment - #frag
I don't at all feel good about it, but it does work, at least for the basic scenario of taking a Uri and issuing a query.
I might be missing something in the Uri class, so if you have a better / less hacky way to do what I am doing here, I'd really appreciate it.
From the original question, it looks like the behaviour of MS.NET changed in .NET 4.5 to fix the bug.
Indeed, then, it is a bug in mono for not following the behaviour change in the .NET 4.5 profile. And it seems someone already fixed the bug and proposed a pull request, the problem is that nobody in the Mono team seems to have found the time to review it: https://github.com/mono/mono/pull/619
These are the errors:
Error 1 Cannot implicitly convert type 'Plantool.xRoute.Point' to 'Plantool.xMap.Point'
Error 2 Cannot implicitly convert type 'Plantool.xRoute.Point' to 'Plantool.xMap.Point'
Error 3 Cannot implicitly convert type 'Plantool.xRoute.LineString' to 'Plantool.xMap.LineString'
I have this code which comes with a namespace.
using Plantool; //Contains xMap, xServer, xLocate
And this is the function in question.
/* createMap()
* Input: WaypointDesc[], Route
* Output: string mapURL
* Edited 21/12/12 - Davide Nguyen
*/
private static string createMap(xRoute.WaypointDesc[] waypointDesc, xRoute.Route route)
{
#region boundingBox
// Set boundingBox fand use corners from the calculated route
xMap.BoundingBox boundingBox = new xMap.BoundingBox();
boundingBox.leftTop = route.totalRectangle.rightTop;
boundingBox.rightBottom = route.totalRectangle.leftBottom;
#endregion
#region mapParams
// Build mapParams
xMap.MapParams mapParams = new xMap.MapParams();
mapParams.showScale = true;
mapParams.useMiles = false;
#endregion
#region imageInfo
// Create imageInfo and set the frame size and image format. NOTE: 1052; 863
xMap.ImageInfo imageInfo = new xMap.ImageInfo();
imageInfo.format = xMap.ImageFileFormat.PNG;
imageInfo.height = 1052;
imageInfo.width = 863;
imageInfo.imageParameter = "";
#endregion
#region layers
// Create a line from the calculated route
xMap.LineString[] lineStrings = new xMap.LineString[] { route.polygon };
xMap.Lines[] lines = new xMap.Lines[1];
xMap.LineOptions options = new xMap.LineOptions();
xMap.LinePartOptions partoptions = new xMap.LinePartOptions();
partoptions.color = new xMap.Color();
partoptions.visible = true;
partoptions.width = -10;
options.mainLine = partoptions;
lines[0] = new xMap.Lines();
lines[0].wrappedLines = lineStrings;
lines[0].options = options;
// Define customLayer that contains the object lines and set layers.
xMap.CustomLayer customLayer = new xMap.CustomLayer();
customLayer.visible = true;
customLayer.drawPriority = 100;
customLayer.wrappedLines = lines;
customLayer.objectInfos = xMap.ObjectInfoType.NONE;
customLayer.centerObjects = true;
xMap.Layer[] layers = new xMap.Layer[] { customLayer };
#endregion
#region includeImageInResponse
// Set argument includeImageInResponse to false (default).
Boolean includeImageInResponse = false;
#endregion
// Return object map using the following method.
xMap.Map map = xMapClient.renderMapBoundingBox(boundingBox, mapParams, imageInfo, layers, includeImageInResponse, null);
// Retrieve the image
string result = "http://" + map.image.url;
// Return the drawn map
return result;
}
The problem lies with the boundingBox object and the lineString object. route.totalRectangle contains a Point object from the xRoute namespace which is identical to that of xMap. Is there anyway to copy or convert it?
This issue does not seem to happen in java examples, but it does in C#. I am sure that if I can solve this error, the other ones will be solved aswell. I have searched my ass off on the API, but it may help you:
xMap:
http://xserver.ptvgroup.com/fileadmin/files/PTV-COMPONENTS/DeveloperZone/Documents/PTV_xServer/API/xMapAPI/pages/apidoc.html
xRoute: http://xserver.ptvgroup.com/fileadmin/files/PTV-COMPONENTS/DeveloperZone/Documents/PTV_xServer/API/xRouteAPI/pages/apidoc.html
Still digging myself.
In C# you cannot convert from one type to another, even if they are for all purposes identical, without copying all the properites, etc. unless an implicit conversion exists.
So you can either write a implicit conversion opertor as shown in link above or you could use a tool like AutoMapper to copy between the two objects
I have found another solution for this issue in the meanwhile whilst randomly playing with the code and the API and this is a partial solution for two of the errors by copying over the well known text values from one object to another. Hopefully I can do the same for the linestring part. I am posting this just incase anyone else comes across this and finds it a usefull solution. New code region below.
// Set boundingBox fand use corners from the calculated route
xMap.BoundingBox boundingBox = new xMap.BoundingBox();
xMap.Point rightTop = new xMap.Point();
rightTop.wkt = route.totalRectangle.rightTop.wkt;
xMap.Point leftBottom = new xMap.Point();
leftBottom.wkt = route.totalRectangle.leftBottom.wkt;
boundingBox.leftTop = rightTop;
boundingBox.rightBottom = leftBottom;
EDIT: Same solution for the linestrings.
// Solution: Cannot implicitly conver ttype xRoute.LineString to xMap.LineString
xMap.LineString maproute = new xMap.LineString();
maproute.wkt = route.polygon.wkt;
// Create a line from the calculated route
xMap.LineString[] lineStrings = new xMap.LineString[] { maproute };
Thanks for the help, I hope someone might find this solution usefull aswell.
Review this for your own purposes... but one option is to use a JSON Parser to serialize one class into JSON, then to deserialize it back into a different class. Short and simple answer, but if all you are looking for is to grab properties from Contoso.Project.UrMom, and transfer them directly to Albiet.Project.UrMom, it works well.
I've found this other alternative that is based on serialization of the objects. As far as I'm concerned it has the disadvantage of accessing the disk.
How did you create the client classes from the WSDL's?
I prefer to create them via command line:
WSDL /sharetypes /out:"XServer.cs" /namespace:"Plantool"
"https://xroute-eu-n-test.cloud.ptvgroup.com/xlocate/ws/XLocate?WSDL"
"https://xroute-eu-n-test.cloud.ptvgroup.com/xroute/ws/XRoute?WSDL"
"https://xroute-eu-n-test.cloud.ptvgroup.com/xtour/ws/XTour?WSDL"
/sharetypes ensures that classes such as Point will be merged intoa single shared class
This also works fine with the xServer2 API and it's WSDLs.