Подтвердить что ты не робот

Wcf deserialize enum как строка

Я пытаюсь использовать веб-службу RESTful с помощью WCF. Я не контролирую формат веб-службы, поэтому мне нужно сделать несколько обходных решений здесь и там. Одна из основных проблем, с которыми я, похоже, не обойти, заключается в том, как сделать WCF десериализацией перечисления в виде строки.

Это мой код (имена изменены, очевидно):

[DataContract]
public enum Foo
{
    [EnumMember( Value = "bar" )]
    Bar,

    [EnumMember( Value = "baz" )]
    Baz
}

[DataContract]
public class UNameIt
{
    [DataMember( Name = "id" )]
    public long Id { get; private set; }

    [DataMember( Name = "name" )]
    public string Name { get; private set; }

    [DataMember( Name = "foo" )]
    public Foo Foo { get; private set; }
}

И это возвращенные данные, которые не дают десериализации:

{
     "id":123456,
     "name":"John Doe",
     "foo":"bar"
}

Наконец, созданное исключение:

Ошибка десериализации объекта типа Service.Foo. Значение "bar" не может быть проанализировано как тип "Int64".

Я не хочу переключиться на использование XmlSerializer, потому что среди многих других недостатков он не позволит мне иметь частные настройки свойств.

Как сделать WCF (или, ну, DataContractSerializer) обрабатывать мои перечисления как строковые значения?

РЕДАКТИРОВАТЬ. Выполнение этого кажется невозможным, и поведение такое, как оно по дизайну. Спасибо, Microsoft, за то, что мы не предоставили нам возможности, нужно прибегать к хакам. Сделать это так, как предлагает somori, кажется, единственный способ получить строки перечисления с JSON и WCF.

4b9b3361

Ответ 1

Это может быть глупый вопрос.

Что произойдет, если вы сделаете

[DataMember( Name = "foo" )]
private string foo { get; private set; }

public Foo Foo 
{ 
  get 
  {
    return Foo.Parse(foo);
  }
}

?

Ответ 2

Я знаю, что это старый пост, но я думаю, что это стоит упомянуть.

Я получил аналогичную ошибку, когда десериализация строки json завершилась неудачно, похоже, десериализоваться на неправильные типы.

Исправление для меня состояло в том, чтобы просто URL-кодировать строку json перед отправкой на сервер. Простая, но легкая ошибка.

HttpUtility.UrlEncode(JSONInstruction) /*remember to encode the string*/

Ответ 4

Возможно, это происходит потому, что сеттер является закрытым, а сообщаемая ошибка вводит в заблуждение. Foo - это первое свойство, подлежащее десериализации, и поскольку никакой публичный сеттер не доступен, он генерирует исключение.