DataContractJsonSerializer и перечисления

Мое решение для гибридного + веб-приложения.

после любой oData Прочитайте ......

    var uriStr; 

    if (typeof sap.hybrid !== 'undefined') {
        uriStr = oUserData.__metadata.uri;
    }
    else{
        uriStr = window.location.href;
    }

    var split1 = uriStr.split("-");  // split by - 
    var secondSubString = split1[1]; // all characters AFTER the first -
    var split2 = secondSubString.split(".");  // split by . 
    self.subAccount = split2[0];  // all characters BEFORE the first .

Затем используйте self.subAccount в вызывающий URI.

39
задан FlySwat 27 April 2009 в 22:04
поделиться

3 ответа

Похоже, что это по замыслу , и это поведение не может быть изменено:

Значения члена перечисления обрабатываются как числа в JSON, который отличается от того, как они обрабатываются в данных контракты, где они включены как имена членов.

Вот пример использования альтернативного (и IMO лучше и более расширяемого) сериализатора, который достигает того, что вы ищете:

using System;
using Newtonsoft.Json;

class Program
{
    static void Main(string[] args)
    {
        var baz = Foo.Baz;
        var serializer = new JsonSerializer();
        serializer.Converters.Add(new JsonEnumTypeConverter());
        serializer.Serialize(Console.Out, baz);
        Console.WriteLine();
    }
}

enum Foo
{
    Bar,
    Baz
}

public class JsonEnumTypeConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Foo);
    }
    public override void WriteJson(JsonWriter writer, object value)
    {
        writer.WriteValue(((Foo)value).ToString());
    }

    public override object ReadJson(JsonReader reader, Type objectType)
    {
        return Enum.Parse(typeof(Foo), reader.Value.ToString());
    }
}
25
ответ дан 27 November 2019 в 02:48
поделиться

edit: Извините, только что встал без кофе: (

Вот код для выполнения того, что вы хотите сделать с помощью Serializer Json, а не DataContractJsonSerializer.

У меня нет Я проделал какую-то работу с DataContractJsonSerializer, но после быстрого сканирования документов я довольно разочарован в MS. Они явно пошли на крайние меры, чтобы сделать WCF очень расширяемым, но с DataContractJsonSerializer нет расширяемости. Вы должны использовать с ним JSON со вкусом MS. SUPER хромает MS ... уже испортил WCF.

    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using System.Web.Script.Serialization;

Некоторые тестовые объекты и Enum:

    public enum SomeSillyEnum
    {
        Foo,Bar,Doo,Daa,Dee
    }

    public class UseSillyEnum
    {
        public SomeSillyEnum PublicEnum { get; set; }
        public string SomeOtherProperty { get; set; }
        public UseSillyEnum()
        {
            PublicEnum = SomeSillyEnum.Foo;
            SomeOtherProperty = "Testing";
        }
    }

JavaScriptConverters. Один для всех перечислений и один для объекта, использующего перечисление.

public class EnumStringConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        foreach(string key in dictionary.Keys)
        {
            try { return Enum.Parse(type, dictionary[key].ToString(), false); }
            catch(Exception ex) { throw new SerializationException("Problem trying to deserialize enum from JSON.",ex); }
        }
        return Activator.CreateInstance(type);
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        Dictionary<string,object> objs = new Dictionary<string, object>();
        objs.Add(obj.ToString(), ((Enum)obj).ToString("D"));
        return objs;
    }

    public override IEnumerable<Type> SupportedTypes{get {return new Type[] {typeof (Enum)};}}
}

public class SillyConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        UseSillyEnum se = new UseSillyEnum();
        foreach (string key in dictionary.Keys)
        {
            switch(key)
            {
                case "PublicEnum":
                    se.PublicEnum = (SomeSillyEnum) Enum.Parse(typeof (SomeSillyEnum), dictionary[key].ToString(), false);
                    break;
                case "SomeOtherProperty":
                    se.SomeOtherProperty = dictionary[key].ToString();
                    break;
            }
        }
        return se;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        UseSillyEnum se = (UseSillyEnum)obj;
        Dictionary<string, object> objs = new Dictionary<string, object>();
        objs.Add("PublicEnum", se.PublicEnum);
        objs.Add("SomeOtherProperty", se.SomeOtherProperty);
        return objs;
    }

    public override IEnumerable<Type> SupportedTypes { get { return new Type[] { typeof(UseSillyEnum) }; } }
}

И используя его внутри страницы:

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        /* Handles ALL Enums

        JavaScriptSerializer jsonSer = new JavaScriptSerializer(); 
        jsonSer.RegisterConverters( new JavaScriptConverter[] { new EnumStringConverter() } );

        string json = jsonSer.Serialize(new UseSillyEnum());
        Response.Write(json);

        UseSillyEnum obj = jsonSer.Deserialize<UseSillyEnum>(json);
        Response.Write(obj.PublicEnum);

        */

        /* Handles Object that uses an enum */
        JavaScriptSerializer jsonSer = new JavaScriptSerializer();
        jsonSer.RegisterConverters( new JavaScriptConverter[] { new SillyConverter() } );
        string json = jsonSer.Serialize(new UseSillyEnum());
        Response.Write(json);

        UseSillyEnum obj = jsonSer.Deserialize<UseSillyEnum>(json);
        Response.Write(obj.PublicEnum);
    }
}
3
ответ дан 27 November 2019 в 02:48
поделиться

Чтобы получить двустороннюю сериализацию/десериализацию для wcf json, вы можете добавить второе свойство get set типа string, когда вы создаете свой json объект в javascript, используйте именованное свойство string, на стороне сервера используйте сильно типизированную версию enum: например,

public class DTOSearchCriteria
{
    public int? ManufacturerID { get; set; }
    public int? ModelID { get; set; }


    private SortBy _sort;


    public SortBy SortType
    {
        get
        {
            return _sort;
        }
        set
        {
            _sort = value;
        }
    }

    public String Sort 
    {
        get
        {
            return _sort.ToString();
        }
        set
        {
            _sort = (SortBy) Enum.Parse(typeof(SortBy), value);
        }
    }





    public int PageSize { get; set; }
    public int PageNumber { get; set; }
}


public enum SortBy
{
    PriceDescending,
    PriceAscending
}
10
ответ дан 27 November 2019 в 02:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: