web-dev-qa-db-ja.com

JSONをasp.netの.Netオブジェクトに変換する際のエラー

JSON文字列をasp.netの.netオブジェクトに変換できません。非表示フィールドを使用してクライアントからサーバーにJSON文字列を送信しています(JSONオブジェクト.Tostring()を非表示フィールドに保持し、コードビハインドファイルの非表示フィールド値を読み取ることにより)

Json string/Object:

 [[{"OfferId":"1","OrderValue":"11","HostingTypeID":"3"},
{"OfferId":"1","OrderValue":"11","HostingTypeID":"3"},
{"OfferId":"1","OrderValue":"11","HostingTypeID":"3"},
{"OfferId":"1","OrderValue":"2","HostingTypeID":"3"},
{"OfferId":"1","OrderValue":"2","HostingTypeID":"3"},
{"OfferId":"1","OrderValue":"67","HostingTypeID":"3"},
{"OfferId":"1","OrderValue":"67","HostingTypeID":"3"}],
[{"OfferId":"1","OrderValue":"99","HostingTypeID":"6"}],
[{"OfferId":"1","OrderValue":"10","HostingTypeID":"8"}]]

.Netオブジェクト

public class JsonFeaturedOffer
{
    public string OfferId { get; set; }

    public string OrderValue { get; set; }

    public string HostingTypeID { get; set; }
}

コードビハインドファイルの会話コード

byte[] byteArray = Encoding.ASCII.GetBytes(HdnJsonData.Value);
        MemoryStream stream = new MemoryStream(byteArray);
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(JsonFeaturedOffer));
        object result= serializer.ReadObject(stream);
        JsonFeaturedOffer jsonObj = result as JsonFeaturedOffer;

変換中に次のエラーが発生します:

名前空間 ''からの要素 'root'が必要です。名前 ''、名前空間 ''の 'None'が見つかりました。

36

これを手動で行う代わりに、組み込みの軽量 JavaScriptSerializer を使用することをお勧めします。 シリアライズ/デシリアライズするクラスに属性は必要ありません。

また、DataContractJsonSerializerよりも柔軟で高速です。これは、すべてのwcfのことを気にする必要がないためです。さらに、一般的なオーバーロードを備えているため、使用が非常に簡単であり、匿名タイプも処理できます。

シリアル化:

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var objectAsJsonString = serializer.Serialize(objectToSerialize);

逆シリアル化:

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
JsonFeaturedOffer deserializedObject = serializer.Deserialize<JsonFeaturedOffer>(s_JsonBaseDate);

さらに簡単にするために、オブジェクト/文字列に直接JSONシリアル化/非シリアル化を提供する拡張メソッドを作成できます。

34
ntziolis

残念ながら、提案された解決策のどれも問題の本当の原因を解決しません。この例外は、デシリアライザストリームの最後から読み取ろうとするであることを意味します。

解決策は、ストリームを最初に巻き戻すことです。をセットする - stream.Position = 0;逆シリアル化する前。

また、コメントにあるように、StreamWriterを使用した場合は、ストリームを使用する前にそれをフラッシュする必要があります。

78
Piotr Szmyd

クラスでjson/xmlに自動的にシリアル化するか、オブジェクトで逆シリアル化する場合は、いくつかのシリアル化可能な属性でクラスを装飾する必要があります。

[Serializable, XmlRoot("JsonFeaturedOffer"), DataContract(Name="JsonFeaturedOffer")]
public class JsonFeaturedOffer  
{
    [XmlElement ("OfferId"), DataMember(Name="OfferId")]
    public string OfferId {get; set;}

... 等々

3
amelvin

これがJsonFeaturedOffersの配列の配列である場合、そうではありません:

byte[] byteArray = Encoding.ASCII.GetBytes(HdnJsonData.Value);
MemoryStream stream = new MemoryStream(byteArray);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(JsonFeaturedOffer[][]));
object result= serializer.ReadObject(stream);
JsonFeaturedOffer[][] jsonObj = result as JsonFeaturedOffer[][];
2
Nick Gotch