ASP.NET/WCF:将JSON外键映射回它们的真实对象

ASP.NET/WCF:将JSON外键映射回它们的真实对象,asp.net,wcf,json,entity-framework-4.1,deserialization,Asp.net,Wcf,Json,Entity Framework 4.1,Deserialization,我有一个WCFWebService,它带有一个Read方法,可以给出一个JSON序列化的Person对象列表。这些Person对象中的每一个都有特定的状态,由各自的状态对象表示。实体框架将其映射为外键关系 现在,对于JSON输出,我不希望将每个人的状态序列化为完整的嵌套对象。相反,我希望Web服务包含相应的StatusId。我就是这样做的: [DataContract] public class Status { public Status() {} [DatabaseGene

我有一个WCFWebService,它带有一个Read方法,可以给出一个JSON序列化的Person对象列表。这些Person对象中的每一个都有特定的状态,由各自的状态对象表示。实体框架将其映射为外键关系

现在,对于JSON输出,我不希望将每个人的状态序列化为完整的嵌套对象。相反,我希望Web服务包含相应的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 {}
    }
}
我的webservice方法如下所示:

[OperationContract]
[WebGet]
public List<Person> Persons()
{
    return _dbContext.Persons.
        Include(person => person.Status)
        Select(person => person).
        ToList();
}
到目前为止,一切都很好。但是当我的WebApp为其中一个实体发送更新请求时,我不知道如何将StatusId映射回真实的Status对象。简而言之:我得到一个JSON请求,其中包含一个更新的Person对象,其状态ID已更改。是否有适当的方式接收引用正确状态对象的Person对象

提前谢谢大家,,
Florian

您当前的解决方案相当不错,但我认为您在这里有一些选择,这意味着您可能需要稍微更改现有的解决方案

始终序列化Status和StatusId。换句话说,将Status也标记为DataMember。我知道为什么只想序列化StatusId,但如果同时序列化Status,则不会显著增加处理时间。不关心或不了解状态的客户可以完全跳过它们。这确实会显著增加导线尺寸,因为它是

使用反序列化回调OnDeserialization/OnDeserialized与扩展数据对象IExtensibleDataObject(又名扩展数据)一起使用。其思想是,您设计该类型时,该类型不理解的任何数据(如状态信息)都将被反序列化到扩展数据包中。您的反序列化回调可以检查此数据并设置状态(如果它看起来像是在线路上)

使用数据协定代理项IDataContractProgate,以便状态对象可以来回转换为其他类型

使用数据协定解析程序DataContractResolver动态解析已知类型

除了MSDN和Stackoverflow,我还推荐WCF团队成员;它非常详细地描述了所有这些序列化角案例扩展点。

您的问题是:

[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);
    }
}