0
\$\begingroup\$

I am pretty new to unity but I am not new to programming. I am building a Hololens application in Unity 2017.2 and it communicates with a REST api that I built. I am using Unity as a front end more or less and it manages my state. Coming from the web developement world, I have my server converting my models into JSON and I am sending that as a response. For the most part, it works well but since Unity works on an older version of C#, I am having issues working with the JSON data, mainly if the data type is not a string, int, float, or double. For example, if my model contains a date data type I am having issues converting it back into a c# model or even arrays are proving to be a pain. I don’t want to rely on unity packages too much as most I have tried don’t do what I need but I am open to any good ones if you know of any.

My question is, what is the best way to send data from my API to Unity? Should I send xml or a csv instead? Or even a more C# native approach? (If that makes sense)

\$\endgroup\$
2
  • 2
    \$\begingroup\$ There is never just one best way. Only the way which works best for your particular project. There is a myriad of different data exchange formats. Which one fits you depends on your data. \$\endgroup\$
    – Philipp
    Dec 22, 2017 at 8:16
  • \$\begingroup\$ I found a solid solution for me last night. I posted it below. \$\endgroup\$ Dec 22, 2017 at 15:43

2 Answers 2

1
\$\begingroup\$

I was able to find a solid solution at this link

I put the static method in my server

public static string GetXMLFromObject(object o)
{
    StringWriter sw = new StringWriter();
    XmlTextWriter tw = null;
    try
    {
        XmlSerializer serializer = new XmlSerializer(o.GetType());
        tw = new XmlTextWriter(sw);
        serializer.Serialize(tw, o);
    }
    catch (Exception ex)
    {
        //Handle Exception Code
    }
    finally
    {
        sw.Close();
        if (tw != null)
        {
            tw.Close();
        }
    }
    return sw.ToString();
}

And all worked well.

And then the method for sending the response called the function like in the link

[HttpGet]
public string GetData(){
    Employee emp = new Employee();
    emp.FirstName = "Code";
    emp.LastName = "Handbook";
    string xml = GetXMLFromObject(emp);
    return xml;
}

And in my Unity C# script, I parsed the response using the second static method given in the link but two changes had to be made.

public static Object ObjectToXML(string xml, Type objectType)
{
    StringReader strReader = null;
    XmlSerializer serializer = null;
    XmlTextReader xmlReader = null;
    Object obj = null;
    try
    {
        strReader = new StringReader(xml);
        serializer = new XmlSerializer(objectType);
        xmlReader = new XmlTextReader(strReader);
        obj = serializer.Deserialize(xmlReader);
    }
    catch (Exception exp)
    {
        //Handle Exception Code
    }
    finally
    {
        if (xmlReader != null)
        {
            xmlReader.Close();
        }
        if (strReader != null)
        {
            strReader.Close();
        }
    }
    return obj;
}

The changes were easy enough to implement, they were: Unity C# does not support XmlReader using the System namespace so I had to add a conditional statement to the using statement. You can read more about it in the official unity documentation here

#if NETFX_CORE
using XmlReader = WinRTLegacy.Xml.XmlReader;
#else
using XmlReader = System.Xml.XmlReader;
#endif

The second change was that strReader.Close() does not exist in the Unity C# scripting.

Change this:

if (strReader != null)
{
    strReader.Close();
}

To this:

if (strReader != null)
{
    strReader.Dispose();
}

I found that solution in a forum here

One last thing to note, Object was giving me some issues so I had to add the System to it. System.Object although Visual Studio said I did not need it, errors were thrown with out it. The final method looked like this:

public static System.Object ObjectToXML(string xml, Type objectType)
{
    StringReader strReader = null;
    XmlSerializer serializer = null;
    XmlTextReader xmlReader = null;
    System.Object obj = null;
    try
    {
        strReader = new StringReader(xml);
        serializer = new XmlSerializer(objectType);
        xmlReader = new XmlTextReader(strReader);
        obj = serializer.Deserialize(xmlReader);
    }
    catch (Exception exp)
    {
        //Handle Exception Code
    }
    finally
    {
        if (xmlReader != null)
        {
            xmlReader.Close();
        }
        if (strReader != null)
        {
            strReader.Dispose();
        }
    }
    return obj;
}

And to use it, I did this:

// handled response above
string xml = response.text;
Employee emp = new Employee();

try{
    System.Object obj = ObjectToXML(xml,typeof(Employee));
    emp = (Employee)obj;
}
catch (Exception ex){
    Debug.Log(ex.message);
    emp = null;
}
finally{
    if(emp != null){
        // do stuff
    }
    else{
        // handle error
    }
}

This was a lot easier than trying to parse JSON and I am able to throw the XML right into an object. The actual object I used was more complex than the Employee example and it worked just fine.

\$\endgroup\$
0
\$\begingroup\$

I’ve found using simplejson as an easy way to handle json responses

https://wiki.unity3d.com/index.php/SimpleJSON

For the setup, you just need to place the simplejson file in a project folder. When handling responses, you can access the data like this:

jsonresponse["players"][2]["items"][5].Value;

for string values, and:

jsonresponse["players"][1]["life"].AsInt;

for int values and so on.

It solves the problem of having to predefine the expected json response data beforehand.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .