簡體   English   中英

如何在.NET中將空字符串反序列化為long?

[英]How to handle deserialization of empty string into long in .NET?

下面說明表示建築類型的對象TestClass2使用類型的對象TestClass1與序列化/反序列化的幫助。

TestClass1TestClass2具有相同的結構,只是其中一個成員在TestClass1為字符串,而在TestClass2 long。

public class TestClass1
{
    public string strlong;
}

public class TestClass2
{
    public long strlong;
}

TestClass1 objT1 = new TestClass1();
objT1.strlong = "20134567";
TestClass2 objT2;
JavaScriptSerializer serializer = new JavaScriptSerializer();
string JSON1 = serializer.Serialize(objT1);
objT2 = serializer.Deserialize<TestClass2>(JSON1);

手術后, objT2會有值objT1strlong現在將是長期的,而不是字符串。

問題是,如果strlong價值objT1是一個空字符串- >“”,反序列化失敗並拋出異常"" is not a valid value for Int64

如果strlong是僅包含數字字符的非空字符串,則當前的反序列化有效。 但是當出現空字符串之類的內容時,我不知道解決方法。

現在,讓我們假設

  1. strlong將在long范圍內
  2. 將只是一個數字字符序列,即沒有. , /或任何其他類型的字符
  3. 只能訪問用於序列化的對象,而我不能對TestClass1TestClass2進行修改。

如果有一種簡單的方法(或沒有)可以使用另一類的對象創建一個類的對象,請在注釋中提及。

編輯-擴展邏輯

為了將下面“答案”中給出的解決方案邏輯擴展到包含其他類類型成員的類,我也對成員項也使用了下面給出的序列化解決方案。 換句話說,如果類包含其他類的成員,是否有比下面的代碼更好的方法來處理更深層次的代碼?

// **Item1 :** 
// These are the subclasses and classes
// whose objects I am trying to serialize
// and deserialize from one type to another
public class SubClass1
{
    public string toomuch;
    public int number = 30;
}

public class SubClass2
{
    public long toomuch;
    public int number;
}

public class TestClass1
{
    public string strlong;
    public SubClass1 item2;
}

public class TestClass2
{
    public long strlong;
    public SubClass2 item2;
}

// **Item2 :** 
// Solution from StackOverflow for serialization of 
// empty string
public class TestClass1Converter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get { return new Type[] { typeof(TestClass1) }; }
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var data = obj as TestClass1;
        var dic = new Dictionary<string, object>();
        if (data == null)
        {
            return dic;
        }

        long val = 0;
        long.TryParse(data.strlong, out val);
        dic.Add("strlong", val);

        // **Item3 :** 
        // trying to serialize and deserialize item2 which is of type SubClass1
        // which might also have empty string
        /*******************/
        JavaScriptSerializer subClassSerializer = new JavaScriptSerializer();
        subClassSerializer.RegisterConverters(new[] { new SubClass1Converter() });
        string JSONstr = subClassSerializer.Serialize(data.item2);
        dic.Add("item2", subClassSerializer.Deserialize<SubClass2>(JSONstr));
        /*******************/

        return dic;
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

// **Item4 :** 
// Serialization for subclass
public class SubClass1Converter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get { return new Type[] { typeof(SubClass1) }; }
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var data = obj as SubClass1;
        var dic = new Dictionary<string, object>();
        if (data == null)
        {
            return dic;
        }

        long val = 0;
        long.TryParse(data.toomuch, out val);
        dic.Add("toomuch", val);
        dic.Add("number", data.number);
        return dic;
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestClass1 objT1 = new TestClass1();
        objT1.strlong = "";
        SubClass1 objSub = new SubClass1();
        objSub.toomuch = "";
        objT1.item2 = objSub;
        TestClass2 objT2;


        JavaScriptSerializer serializer = new JavaScriptSerializer();
        serializer.RegisterConverters(new[] { new TestClass1Converter() });
        string JSON1 = serializer.Serialize(objT1);
        objT2 = serializer.Deserialize<TestClass2>(JSON1);
    }
}

您應該將您的TestClass2.strlong聲明為可為空。

public class TestClass2
{
    public long? strlong;
}

現在你可以有null的情況下,當TestClass1.strlong為空字符串或null。

如果您沒有權限修改類,這是UPDATE

您應該通過RegisterConverters將轉換器添加到序列化器以自定義轉換。 這是示例:

public class TestClass1Converter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get { return new Type[] { typeof(TestClass1)}; }
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var data = obj as TestClass1;
        var dic = new Dictionary<string, object>();
        if(data == null)
        {
            return dic;
        }

        long val = 0;
        long.TryParse(data.strlong, out val);
        dic.Add("strlong", val);
        return dic;
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

如果無法將其轉換為long ,則此轉換器會將strlong序列strlong 0。 您可以通過以下方式使用它:

TestClass1 objT1 = new TestClass1();
objT1.strlong = "444";
TestClass2 objT2;
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new [] {new TestClass1Converter()});
string JSON1 = serializer.Serialize(objT1);
objT2 = serializer.Deserialize<TestClass2>(JSON1);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM