ASP.NET / WCF: сопоставление внешних ключей JSON с их реальными объектами - PullRequest
0 голосов
/ 31 января 2012

У меня есть веб-служба WCF с методом «Read», который выдает сериализованный в JSON список объектов Person. Каждый из этих объектов Person имеет определенный статус, представленный соответствующим объектом Status. Entity Framework отображает это как отношение внешнего ключа.

Теперь для вывода в формате JSON я не хотел, чтобы статус каждого персонажа сериализовался как полностью вложенный объект. Вместо этого я хотел, чтобы веб-сервис включал соответствующий «StatusId». Вот как я это сделал:

[DataContract]
public class Status
{
    public Status() {}

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [DataMember(Name = "StatusId")]
    public int StatusId { get; set; }

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


[DataContract]
public class Person
 {
    public Person() {}

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [DataMember(Name = "PersonId")]
    public int PersonId { get; set; }

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

    public Status Status { get; set; }

    [DataMember(Name = "StatusId")]
    [NotMapped]
    public int JsonStatusId
    {
        get
        {
            if (Status == null) return -1;
            return Status.StatusId;
        }
        set {}
    }
}

И мой метод веб-сервиса выглядит следующим образом:

[OperationContract]
[WebGet]
public List<Person> Persons()
{
    return _dbContext.Persons.
        Include(person => person.Status)
        Select(person => person).
        ToList();
}

Пока все отлично работает. Но когда мое WebApp отправляет запрос на обновление одного из объектов, я не знаю, как сопоставить StatusId с реальным объектом Status. Вкратце: я получаю JSON-запрос, содержащий обновленный объект Person с измененным StatusId. Есть ли правильный способ получить объект Person, ссылающийся на правильный объект Status?

Спасибо всем заранее, Florian

Ответы [ 2 ]

0 голосов
/ 30 апреля 2012

Ваша проблема заключается в следующем:

[DataMember(Name = "StatusId")]
[NotMapped]
public int JsonStatusId
{
    get
    {
        if (Status == null) return -1;
        return Status.StatusId;
    }
    set {}
}

Просто реализовать набор, что-то вроде:

[DataMember(Name = "StatusId")]
[NotMapped]
public int JsonStatusId
{
    get
    {
        if (Status == null) return -1;
        return Status.StatusId;
    }
    set 
    {
        var _dbContext= new entities()
        Status = _dbContext.Statuses.First(p => p.Id == value);
    }
}
0 голосов
/ 26 апреля 2012

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

  • Сериализация Status и StatusId всегда.Другими словами, пометьте Status также как DataMember.Я понимаю, ПОЧЕМУ вы хотите сериализовать только StatusId, но это не увеличит время обработки более значительно, если вы также сериализуете Status.Клиенты, которые не заботятся о статусе или не понимают его, могут вообще их пропустить.Это значительно увеличивает размер провода, потому что он

  • Использование обратного вызова десериализации (OnDeserializing / OnDeserialized) с объектом данных расширения (IExtensibleDataObject, он же «данные расширения»). Идея состоит в том, чтоВы проектируете тип так, что любые данные, которые тип не понимает (например, информация о состоянии), будут десериализованы в «пакет данных расширения».Ваш обратный вызов десериализации может проверить эти данные и установить статус, если он выглядит так, как будто он присутствовал в сети.

  • Используйте суррогат контракта данных (IDataContractSurrogate), чтобы объекты состояния могли переводиться назад и вперед в другие типы

  • Использовать контракт данныхresolver (DataContractResolver) для динамического разрешения известных типов.

В дополнение к MSDN и Stackoverflow я также рекомендую этот блог от члена команды WCF;он очень подробно описывает все эти точки расширения регистра углового случая сериализации.

...