Как не сериализовать свойство __type в объектах JSON - PullRequest
62 голосов
/ 09 марта 2009

Каждый объект, который я возвращаю из WebMethod из ScriptService, помещается в объект JSON с данными в свойстве с именем d. Это нормально. Но я не хочу, чтобы дополнительное свойство __type передавалось клиенту, поскольку я выполняю ручную обработку с помощью jQuery.

Возможно ли это?

Ответы [ 15 ]

1 голос
/ 22 мая 2012

Немного опоздал с веткой, но здесь идет.

У нас была такая же проблема, когда свойство, добавляемое в строку json, представляло собой список . Мы добавили еще одно свойство, представляющее собой массив T, что-то вроде.

До.

[DataMember]
public List<Person> People { get; set; }

После того, как.

public List<Person> People { get; set; }

[DataMember(Name = "People")]
public Person[] Persons {
    get {
        return People.ToArray();
    }
    private set { }
}

Хотя это и не идеальное решение, оно делает свое дело.

1 голос
/ 03 июня 2009

Не используйте атрибут [Serializable].

Следующее должно просто сделать это

JavaScriptSerializer ser = новый JavaScriptSerializer (); строка json = ser.Serialize (objectClass);

0 голосов
/ 27 марта 2019

В дополнение к ответу @sean об использовании JavaScriptSerializer.

При использовании JavaScriptSerializer и отмечении ResponseFormat = WebMessageFormat.Json метода полученный ответ имеет двойную кодировку JSON, плюс, если полученный ответ равен string, он будет заключен в двойные кавычки.

Чтобы избежать этого, используйте решение из этого превосходного ответа , чтобы определить тип содержимого как JSON (перезаписать) и передать двоичный результат JavaScriptSerializer.

Пример кода из упомянутого ответа:

public Stream GetCurrentCart()
{
    //Code ommited
    var j = new { Content = response.Content, Display=response.Display,
                  SubTotal=response.SubTotal};
    var s = new JavaScriptSerializer();
    string jsonClient = s.Serialize(j);
    WebOperationContext.Current.OutgoingResponse.ContentType =
        "application/json; charset=utf-8";
    return new MemoryStream(Encoding.UTF8.GetBytes(jsonClient));
}

JavaScriptSerializer находится в пространстве имен System.Web.Script.Serialization, найденном в System.Web.Extensions.dll, на которое по умолчанию нет ссылок.

0 голосов
/ 15 июня 2011

Это что-то вроде хака, но у меня это сработало (используя C #):

s = (JSON string with "__type":"clsname", attributes)
string match = "\"__type\":\"([^\\\"]|\\.)*\",";
RegEx regex = new Regex(match, RegexOptions.Singleline);
string cleaned = regex.Replace(s, "");

Работает с [DataContract] и [DataContract(Namespace="")]

0 голосов
/ 10 августа 2010

Это должно решить.

В частном методе SerializeValue JavaScriptSerializer в System.WebExtensions.dll, __type добавляется во внутренний словарь, если его можно разрешить.

От отражателя:

private void SerializeValue(object o, StringBuilder sb, int depth, Hashtable objectsInUse)
{
    if (++depth > this._recursionLimit)
    {
        throw new ArgumentException(AtlasWeb.JSON_DepthLimitExceeded);
    }
    JavaScriptConverter converter = null;
    if ((o != null) && this.ConverterExistsForType(o.GetType(), out converter))
    {
        IDictionary<string, object> dictionary = converter.Serialize(o, this);
        if (this.TypeResolver != null)
        {
            string str = this.TypeResolver.ResolveTypeId(o.GetType());
            if (str != null)
            {
                dictionary["__type"] = str;
            }
        }
        sb.Append(this.Serialize(dictionary));
    }
    else
    {
        this.SerializeValueInternal(o, sb, depth, objectsInUse);
    }
}

Если тип не может быть определен, сериализация будет продолжена, но тип будет игнорироваться. Хорошей новостью является то, что, поскольку анонимные типы наследуют getType (), а возвращаемые имена динамически генерируются компилятором, TypeResolver возвращает ноль для ResolveTypeId, а атрибут «__type» впоследствии игнорируется.

Я также на всякий случай воспользовался советом Джона Моррисона с внутренним конструктором, хотя, используя только этот метод, я все еще получал свойства __type в своем ответе JSON.

//Given the following class
[XmlType("T")]
public class Foo
{
    internal Foo()
    {

    }

    [XmlAttribute("p")]
    public uint Bar
    {
        get;
        set;
    }
}

[WebService(Namespace = "http://me.com/10/8")]
[System.ComponentModel.ToolboxItem(false)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class MyService : System.Web.Services.WebService
{

    //Return Anonymous Type to omit the __type property from JSON serialization
    [WebMethod(EnableSession = true)]
    [System.Web.Script.Services.ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json, XmlSerializeString = false)]
    public object GetFoo(int pageId)
    {
        //Kludge, returning an anonymois type using link, prevents returning the _type attribute.
        List<Foo> foos = new List<Foo>();
        rtnFoos.Add( new Foo(){
            Bar=99
        }};

        var rtn = from g in foos.AsEnumerable()
                   select g;

        return rtn;
    }
}

Примечание: Я использую унаследованный преобразователь типов JSON, который считывает атрибуты сериализации XML из сериализованных типов для дальнейшего сжатия JSON. Благодаря CodeJournal . Работает как шарм.

...