C # JavaScriptSerializer сериализует поля, которые не существуют в интерфейсе, но существуют в исходном объекте - PullRequest
0 голосов
/ 19 марта 2019

Я пытаюсь сериализовать объект без каких-либо полей. Я попытался определить интерфейс без этих полей, а затем преобразовать и сериализовать его, но JavaScriptSerializer также включает эти поля.

interface iStam {
    public int a {
        get;
        set;
    }
}

class Stam :iStam{
    private int _a = 0;
    public int a {
        get {return _a;}
        set {_a = value;}
    }
    public int b = 0;
}


void fun() {
    Stam s = new Stam();
    /*
    s.a == 0;
    s.b == 0;
    */
    iStam _s = (iStam) s;
    /*
    _s.a == 0;
    _s.b Not exists!  compilation error.
    */

    JavaScriptSerializer jss = new JavaScriptSerializer ();
    Console.WriteLine(jss.Serialize(_s));
}

Ожидаемое:

{
    "a":0
}

Got:

{
    "a":0,
    "b":0,
}

Почему?

1 Ответ

2 голосов
/ 09 июня 2019

Проблема здесь заключается в том, что JavaScriptSerializer.Serialize() принимает аргумент object, а не универсальный тип, и сериализует объект на основе сигнатуры его класса, а не интерфейса, к которому вы приводите.JavaScriptSerializer довольно старый (возможно, не рекомендуется), и в настоящее время рекомендуется использовать Newtonsoft.Json или другой сериализатор.

Однако, если у вас нет выбора, кроме как использовать JavaScriptSerializer, тогдаВы можете аннотировать свойства и поля, которые вы не хотите сериализовать, с помощью атрибута ScriptIgnore.

В классе Stam:

[ScriptIgnore]
public int b = 0;

Вызовите, как раньшено нет необходимости разыгрывать:

Stam s = new Stam();
JavaScriptSerializer jss = new JavaScriptSerializer();
Console.WriteLine(jss.Serialize(s));

Вывод:

{"a":0}

Если вам нужна большая гибкость, и снова, если вы не можете перейти на более современный сериализатор, тогдавам нужно написать JavaScriptConverter .

...