24. marts 2011 - 13:04Der er
8 kommentarer og 1 løsning
json og serialize i .net uden at definere class til objektet
Hej,
Jeg har behov for at kalde json fra min .net kode. Jeg forsøger med følgende helper class: public class JSONHelper { public static string Serialize<T>(T obj) { System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType()); MemoryStream ms = new MemoryStream(); serializer.WriteObject(ms, obj); string retVal = Encoding.Default.GetString(ms.ToArray()); ms.Dispose(); return retVal; }
public static T Deserialize<T>(string json) { T obj = Activator.CreateInstance<T>(); MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)); System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType()); obj = (T)serializer.ReadObject(ms); ms.Close(); ms.Dispose(); return obj; } }
Yderligere har jeg følgende klasse: [DataContract] public class Person { public Person() { } public Person(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; }
[DataMember] public string FirstName { get; set; }
og jeg kan så skrive: Response.Write(myPerson.FirstName) og det heler funker som det skal.
Men når jeg kalder min url der returnerer mig et jsonobject, så får jeg null i mine attributter. dvs. at myPerson.FirstName er null
Det skal siges at objektet jeg får retur ikke er ens med min Person klasse. Og ja jeg ved godt den burde være det, men hvis man kalder samme url i javascript eller php så behøves man ikke at "kende" sit objekt til bevidstløshed.
Blot man viser til de rigtige feltnavne som her: java script: var rese = eval('(' + res + ')'); document.write(rese.firstName + "<br>" + rese.firstName);
Hvordan kan jeg arbejde med mit returnerede json objekt uden at skulle definere en class inde i min kode ? Hvis der fx tilføjes et ekstra feltnavn til json objektet, så vil jeg at min kode skal være upåvirket af det, fordi det kan godt være at jeg ikke har behov for feltet, men kun aflæser firstname og lastname !
Håber at spørgsmålet er forståeligt, og håber at få noget response på dette ?
Det er lidt vanskeligere i C# end i PHP fordi C# er et typestærkt sprog.
Men se nedenfor for et forslag til løsning:
using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Text; using System.Web.Script.Serialization;
namespace E { public static class Json1 { public static string Serialize<T>(T o) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(); ser.WriteObject(ms, o); return Encoding.UTF8.GetString(ms.ToArray()); } public static T Deserialize<T>(string json) { MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); return (T)ser.ReadObject(ms); } } [DataContract] public class Person { public Person() : this("", "") { } public Person(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; } [DataMember] public string FirstName { get; set; } [DataMember] public string LastName { get; set; } } public static class Json2 { public static string Serialize(object o) { JavaScriptSerializer ser = new JavaScriptSerializer(); return ser.Serialize(o); } public static T Deserialize<T>(string json) { JavaScriptSerializer ser = new JavaScriptSerializer(); return ser.Deserialize<T>(json); } public static object Deserialize(string json) { JavaScriptSerializer ser = new JavaScriptSerializer(); return ser.DeserializeObject(json); } } public class Program { public static void Main(string[] args) { Person o = new Person("Peter", "Pan"); string json = Json1.Serialize<Person>(o); Console.WriteLine(json); Person ox = Json1.Deserialize<Person>(json); Console.WriteLine(ox.FirstName + " " + ox.LastName); Person o2 = new Person("Peter", "Pan"); string json2 = Json2.Serialize(o2); Console.WriteLine(json2); Person o2x = Json2.Deserialize<Person>(json2); Console.WriteLine(o2x.FirstName + " " + o2x.LastName); IDictionary<string, object> o2xx = (IDictionary<string, object>)Json2.Deserialize(json2); Console.WriteLine(o2xx["FirstName"] + " " + o2xx["LastName"]); string json3 = "{\"FN\":\"Peter\",\"LN\":\"Pan\"}"; Console.WriteLine(json2); IDictionary<string, object> o3xx = (IDictionary<string, object>)Json2.Deserialize(json3); Console.WriteLine(o3xx["FN"] + " " + o3xx["LN"]); Console.ReadKey(); } } }
Jeg har dog et lille "issue" vedr. hvordan jeg kan aflæse street i address i følgende json streng: "{\n \"vaerdi\" : 20,\n \"laengde\" : 0\n , \"ialt\": 47\t\n ,\"address\": [\n \n { \n \t\t\t\"id\": \"29\",\n \t\t\t\"grp_id\": \"NGL13510658\",\n\t\t\t\t\"street\": \"storegade\"
Den kode jeg anvendte fra dig er: IDictionary<string, object> o3xx = (IDictionary<string, object>)E.Json2.Deserialize(json3);
using System; using System.Collections.Generic; using System.Web.Script.Serialization;
namespace E { public static class Json { public static object Deserialize(string json) { JavaScriptSerializer ser = new JavaScriptSerializer(); return ser.DeserializeObject(json); } } public class Program { public static void Main(string[] args) { string json = "{\"a\":\"This is a\",\"b\":{\"c\":\"This is c\",\"d\":\"This is d\"}}"; Console.WriteLine(json); IDictionary<string, object> o = (IDictionary<string, object>)Json.Deserialize(json); string a = (string)o["a"]; IDictionary<string, object> b = (IDictionary<string, object>)o["b"]; string c = (string)b["c"]; string d = (string)b["d"]; Console.WriteLine(a + " " + c + " " + d); Console.ReadKey(); } } }
var serializer = new JavaScriptSerializer(); serializer.RegisterConverters(new[] {new DynamicJsonConverter()}); dynamic obj = serializer.Deserialize(json, typeof (object));
int value = obj.vaerdi; int length = obj.laengde; int total = obj.ialt; string id = obj.address[0].id; string street = obj.address[0].street; //osv.
Som du kan se, så er det næsten som i javascript, da det er muligt at tilgå dataene med standard dot notation.
Men her er hele koden. Den har jeg på et eller andet tidspunkt lånt fra stackoverflow.com.
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Dynamic; using System.Linq; using System.Web.Script.Serialization; //ligger i System.Web.Extensions
namespace Dynamic { internal sealed class DynamicJsonConverter : JavaScriptConverter { public override IEnumerable<Type> SupportedTypes { get { return new ReadOnlyCollection<Type>(new List<Type>(new[] {typeof (object)})); } }
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) { if (dictionary == null) { throw new ArgumentNullException("dictionary"); } return type == typeof (object) ? new DynamicJsonObject(dictionary) : null; }
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) { throw new NotImplementedException(); } }
public DynamicJsonObject(IDictionary<string, object> dictionary) { if (dictionary == null) { throw new ArgumentNullException("dictionary"); } _dictionary = dictionary; }
public override bool TryGetMember(GetMemberBinder binder, out object result) { if (!_dictionary.TryGetValue(binder.Name, out result)) { // return null to avoid exception. caller can check for null this way... result = null; return true; } var dictionary = result as IDictionary<string, object>; if (dictionary != null) { result = new DynamicJsonObject(dictionary); return true; } var arrayList = result as ArrayList; if (arrayList != null && arrayList.Count > 0) { if (arrayList[0] is IDictionary<string, object>) { result = new List<object>( arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x))); } else { result = new List<object>(arrayList.Cast<object>()); } } return true; } } }
array returneres som object[] ikek som IDictionary<string.object>
demo:
using System; using System.Collections.Generic; using System.Web.Script.Serialization;
namespace E { public static class Json { public static object Deserialize(string json) { JavaScriptSerializer ser = new JavaScriptSerializer(); return ser.DeserializeObject(json); } } public class Program { public static void Main(string[] args) { string json = "{\"a\":\"This is a\",\"b\":{\"c\":\"This is c\",\"d\":\"This is d\"},\"e\":[1,2,3]}"; Console.WriteLine(json); IDictionary<string, object> o = (IDictionary<string, object>)Json.Deserialize(json); string a = (string)o["a"]; IDictionary<string, object> b = (IDictionary<string, object>)o["b"]; string c = (string)b["c"]; string d = (string)b["d"]; Console.WriteLine(a + " " + c + " " + d); object[] e = (object[])o["e"]; int e0 = (int)e[0]; int e1 = (int)e[1]; int e2 = (int)e[2]; Console.WriteLine(e0 + " " + e1 + " " + e2); Console.ReadKey(); } } }
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.