2012-01-31 3 views
0

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

Теперь, для вывода 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, ссылающийся на правильный объект статуса?

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

ответ

0

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

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

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

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

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

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

0

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

[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); 
    } 
} 
Смежные вопросы