Bad saving in Unity 3D with JSON - json

My source code of voxel terrain can't save the data. I have a 3D char array called terrain and when I save, then it's result is empty json. The result is:
{}
The source code is:
public void TerrainSave() {
LoadingSavingClass myObject = new LoadingSavingClass();
myObject.terrain = terrain;
string json = JsonUtility.ToJson(myObject);
File.WriteAllText(Application.streamingAssetsPath + "/terrain/save.ter", json);
if(json == "{}")
{
Debug.Log("Saved clear data");
}
}
The class is:
[Serializable]
public class LoadingSavingClass
{
public char[,,] terrain = new char[128, 32, 128];
}
The saved 3D char char array isn't empty, I put some data into it before saving.

As mentioned here in JSON Serialization Docs JsonUtility.ToJson will only serialize the same types as you can serialize in Unity's inspector. char[,,,] won't serialize in Unity's inspector so it won't serialize with JsonUtility.ToJson

Related

How to convert string Map to JSON string in java?

I have fact an issue related to convert string map to string json with below example
public class Demo {
public static void main(String[] args) throws JsonProcessingException {
String stringRequest = "{A=12, B=23}";
System.out.println(new Gson().toJson(stringRequest));
}
}
```
OUTPUT: "{A\u003d12, B\u003d23}"
Please you help me how can I map this to json string.
It is a bit unclear what actually is your problem but the main thing in your example is that you are serializing a String object to JSON. That is why you get such an output, it is not a presentation of a Map but a String.
However with that string you can easily create a Map which you can then serialize. Not saying there is any point on that unless you want to do some cleaning or so but anyway:
// Check first which kind of types are keys & values
// keys are always Strings and here it seems that values can be Integers
Type type = new TypeToken<Map<String, Integer>>(){}.getType();
// Create the actual map from that string
Map<String, Integer> map = getGson().fromJson(stringRequest, type);
// Serialize the map to the console (added pretty printing here)
System.out.println(new Gson().toJson(map));
and you can see:
{ "A": 12, "B": 23 }

Exclude a data member from JSon serialization

This is with the Docusign Rest api. When I call ToJson() on an EnvelopeDefinition, it returns the correct info, but I would like it to not serialize the base64 array for when I am writing this out to a log file. I tried using the [JsonIgnore] directive, but that stopped the array from being serialized altogether. Do I need to override the Serialize method on this class or just create another method, something like ToJsonForLogging() and not serialize that array?
I have created an extension method that will work for you. You can call this extension method in your code as follows
string json = envelopeDefinition.ToJsonLog(logDocumentBase64:false)
I am copying the DocumentBase64 into a temporary List and then using .ToJson() function to log without the documentBase64 property.
public static class EnvelopeDefinitionExtensions
{
public static string ToJsonLog(this EnvelopeDefinition envDefinition, bool logDocumentBase64 = true)
{
if (logDocumentBase64) return envDefinition.ToJson();
var tempDocumentBase64List = new List<string>();
foreach(var doc in envDefinition.Documents)
{
tempDocumentBase64List.Add(doc.DocumentBase64);
doc.DocumentBase64 = null;
}
string json = envDefinition.ToJson();
int i =0;
foreach(var doc in envDefinition.Documents)
{
doc.DocumentBase64 = tempDocumentBase64List[i];
i++;
}
return json;
}
}

How can I deserialize a JSON array with LibGDX

How can I deserialize a JSON array into a Java object with libgdx? I can use the libgdx Json serialization classes to deserialize a JSON object into a Java object but I don't know how to deal with an JSON array response. Surely there is an easy way to do this?
The Array class can handle JSON arrays representations. It can be just a field of class that you want to deserialize to:
//Example of json string:
String jsonString = "{\"array\":[{\"id\":1}, {\"id\":2}, {\"id\":3}]}";
//Item class
public class Item
{
public int id;
}
//class with Array
public class ItemArray
{
public Array<Job> array;
}
//and deserialization:
... //getting JSON
Json json = new Json();
ItemArray itemArray = json.fromJson(ItemArray.class, jsonString);
If you want to use primitives please notice that there are also FloatArray and IntArray classes in LibGDX
You can always loop the json values and put it in a array yourself.
float[] elements = new float[jsonArray.get("arrayElement").size];
for (JsonValue element : jsonArray.get("arrayElement"))
{
System.out.println(element.asString());
}
Not sure how you can put the array one on one into a java array. Neither do I have the time to figure out that one.

How to genearte JSON on the client

In the project, I have to send complex JSON commands form the server to the client. Is it effective to generate JSONObjects ( Strings, Numbers, etc.) convert them to the string and then send them via RequestBuilder or is there a more effective method.
Is it effective to convert JSON objects to string (via the .toString method on the Object)
Code example:
JSONObject retObject = new JSONObject();
retObject.put("NumberVar", new JSONNumber(1));
retObject.put("StringVar", new JSONString("HelloWorld"));
JSONArray arrayVar= new JSONArray();
for (int i = 0; i < 5; i++) {
arrayVar.set(i,
new JSONString("Array"));
}
retObject.put("EventParameters", arrayVar);
System.out.println(retObject.toString());
Output:
{"NumberVar":1, "StringVar":"HelloWorld", "EventParameters":["Array","Array","Array","Array","Array"]}
Regards,
Stefan
The solution you have will work.
If you want to do it more efficiently, and you only want to support modern browsers with support for JSON.stringify(), you can work in JavaScriptObjects instead of JSONObjects and use this native method:
private static native String stringify(JavaScriptObject jso) /*-{
return JSON.stringify(jso);
}-*/;
Alternatively, you can stringify a JSO by doing:
String json = new JSONObject(jso).toString();
JavaScriptObjects are more efficient because they are represented in the final compiled code as JS objects, while JSONObjects are represented as emulated Java objects. The second solution will mean less overhead while you construct the JSO, but comparatively more (than the first) when you stringify it.
Your solution will work just fine though.
There's also AutoBeans.
public interface MyJsonFactory extends AutoBeanFactory {
AutoBean<MyJsonObj> myJsonObj();
}
public interface MyJsonObj {
#PropertyName("NumberVar")
int getNumberVar();
#PropertyName("NumberVar")
void setNumberVar(int val);
#PropertyName("StringVar")
String getStringVar();
#PropertyName("StringVar")
void setStringVar(String val);
#PropertyName("EventParameters")
List<String> getEventParameters();
#PropertyName("EventParameters")
void setEventParameters(List<String> val);
}
MyJsonFactory factory = GWT.create(MyJsonFactory.class);
AutoBean<MyJsonObj> bean = factory.myJsonObj();
MyJsonObj obj = bean.as();
// bean and obj are 2 distinct view on the exact same data
obj.setNumberVar(1);
obj.setStringVar("HelloWorld");
List<String> list = new ArrayList<String>(5);
for (int i = 0; i < 5; i++) {
list.add("Array");
}
obj.setEventParameters(list);
System.out.println(AutoBeanCodex.encode(bean).getPayload());
The #PropertyName is needed is as your JSON property names do not align with the AutoBean conventions (inspired by Java Beans ones), where getNumberVar() gets a numberVar property (with lower-case n)

WCF restful returning JSON by using Entity Framework Complex

recently I have set up a WCF restful service with EF4.
It all worked out when returning XML format response. however when it comes to JSON, I got 504 Error. unable to return json data, WCF Resful Service .NET 4.0
By digging deeper by using Service Trace Viewer:
I found this error:
'The type 'xxx.DataEntity.AppView'
cannot be serialized to JSON because
its IsReference setting is 'True'. The
JSON format does not support
references because there is no
standardized format for representing
references. To enable serialization,
disable the IsReference setting on the
type or an appropriate parent class of
the type.'
The "AppView" is a complex object class which generated by EF4 from a store procedure.
I spend quite a bit time google how to disable the IsReference, very little result so far.
anyone? with any solutions?
thanks in advance
Code:
[OperationContract]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "App/{id}/{format}")]
AppView FuncDetail(string id, string format);
public AppView FuncDetail(string id, string format)
{
SetResponseFormat(format);
return AppSvcs.GetById(id);
}
private void SetResponseFormat(string format)
{
if (format.ToLower() == "json")
{
ResponseContext.Format = WebMessageFormat.Json;
}
else
{
ResponseContext.Format = WebMessageFormat.Xml;
}
}
I ran into exactly the same issue. It only happened on one of my service methods where I was trying to return JSON serialised Entity objects. For all my other methods I was returning JSON serialised data transfer objects (DTOs), which are stand-alone and not connected to the Entity framework. I am using DTOs for data posted into methods. Often, the data you send out does not need all the data you store in the model or the database e.g. ID values, updated dates, etc. The mapping is done in the model class, like so:
public partial class Location
{
public static LocationDto CreateLocationDto(Location location)
{
LocationDto dto = new LocationDto
{
Accuracy = location.Accuracy,
Altitude = location.Altitude,
Bearing = location.Bearing
};
return dto;
}
It may seem a bit clunky but it works and it ensures that you only send the data fields you intended to send back. It works for me because I only have 5 or 6 entities but I can see that it would get a bit tedious if you have lots of classes.
I was running into the same problem, as caused by using the auto-generated ADO Entity Models. I have not found a direct fix for this issue, but as a work around, I serialize the response as json explicitly.
So in your example, the AppView FuncDetail looks like this:
public object FuncDetail(string id, string format)
{
SetResponseFormat(format);
// where AppSvc is the object type and the enumerable list of this type is returned by the GetById method, cast it to a json string
return JSONSerializer.ToJson<AppSvc>(AppSvcs.GetById(id));
}
Here are the Serializers that I'm using:
public static class GenericSerializer
{
public static DataTable ToDataTable<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = new DataTable();
// column names
PropertyInfo[] oProps = null;
if (varlist == null) return dtReturn;
foreach (T rec in varlist)
{
// Use reflection to get property names, to create table, Only first time, others will follow
if (oProps == null)
{
oProps = ((Type)rec.GetType()).GetProperties();
foreach (PropertyInfo pi in oProps)
{
Type colType = pi.PropertyType;
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
== typeof(Nullable<>)))
{
colType = colType.GetGenericArguments()[0];
}
dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
}
}
DataRow dr = dtReturn.NewRow();
foreach (PropertyInfo pi in oProps)
{
dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
(rec, null);
}
dtReturn.Rows.Add(dr);
}
return dtReturn;
}
}
public static class JSONSerializer
{
public static string ToJson<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = GenericSerializer.ToDataTable(varlist);
return GetJSONString(dtReturn);
}
static object RowsToDictionary(this DataTable table)
{
var columns = table.Columns.Cast<DataColumn>().ToArray();
return table.Rows.Cast<DataRow>().Select(r => columns.ToDictionary(c => c.ColumnName, c => r[c]));
}
static Dictionary<string, object> ToDictionary(this DataTable table)
{
return new Dictionary<string, object>
{
{ table.TableName, table.RowsToDictionary() }
};
}
static Dictionary<string, object> ToDictionary(this DataSet data)
{
return data.Tables.Cast<DataTable>().ToDictionary(t => "Table", t => t.RowsToDictionary());
}
public static string GetJSONString(DataTable table)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(table.ToDictionary());
}
public static string GetJSONString(DataSet data)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(data.ToDictionary());
}}
It is a lot clearer to use Entity Metadata instead of Reflection.
The Metadata is pretty extensive.
another way to do this is to use LINQ to create an anonymous type with the subset of fields that you need from your entity and then use JSON.NET to serialize the collection of anon types that you created in the LINQ statement. then persist that collection out as a string by serializing.