【问题标题】:Issue with Entity Framework class being returned via Web Service通过 Web 服务返回的实体框架类的问题
【发布时间】:2012-10-08 13:46:19
【问题描述】:

我已经实现了一个 Web 服务,我通过 ajax 调用它。
注意:我的实体是为实体框架代码第一目的而制作的。

我的 ajax 如下所示:

$.ajax({
   type: "GET",
   url: "/MyProject/MyService.svc/GetEntity",
   data: "entityID=1",
   dataType: "json",
   contentType: "application/json; charset=utf-8",
   success: AjaxSucceeded,
   error: function (msg, status, extra) {
      alert(status + " - " + extra);
   }
 });

AjaxSucceeded 只是一个带有数据变量的函数,我只是在控制台中记录数据。

我的 GetEntity 函数目前如下所示:

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public MyEntity GetEntity(int entityID)
{
    AccessObject accessObject = new AccessObject("MyConnectionString");

    MyEntity theEntity = accessObject.GetByID(entityID);

    return theEntity;
}

我已经用一个专门为测试而创建的类对此进行了测试,它按预期工作(例如,我在 Web 服务中创建了一个 MyEntity 类,它非常简单,有几个属性,没有其他方法等)。

当我返回一个我为代码优先实体框架创建的实体时,问题就出现了。它不起作用,多次调用 Web 服务函数,然后控制台中出现错误,指出“加载资源失败”,指的是我的服务函数。

作为参考,这是我的实体:

[DataContract(IsReference=true)]
public class MyEntity
{
    #region Properties

    [Key]
    [DataMember]
    public int ID { get; set; }

    public bool SomeBoolean { get; set; }

    [StringLength(1000)]
    public string Description { get; set;}

    #endregion

    #region Relationships

    public virtual SomeOtherEntity OtherEntity { get; set; }

    #endregion

}

我只设置了 ID 为 DataMember 进行测试,但仍然没有成功。

谁能指出我正确的方向?我知道 Web 服务可以工作,因为其他功能也可以工作,如果我设置了一个本地(在 Web 服务内)类,它会毫无问题地返回它。所以我假设它与实体框架属性有关?我可能错了,但这是我能想象的。

感谢您的宝贵时间。

哦,另外,作为参考,我的服务类具有以下属性:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  

【问题讨论】:

  • 我尽量不在论文中提出这个问题。很抱歉它的长度。
  • 您的 wcf 服务是“启用 ajax 的 wcf 服务”吗?

标签: c# .net ajax web-services entity-framework


【解决方案1】:

问题只是实体并不是真正为序列化而构建的。我的建议是创建一个 DTO,映射相关属性并将其通过网络传递,例如

public class EntityDto
{
    public int ID { get; set; }
    public string Description { get; set; }
    ...
}

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public EntityDto MyEntity(int entityId)
{
    AccessObject accessObject = new AccessObject("MyConnectionString");
    MyEntity theEntity = accessObject.GetByID(entityID);
    return new EntityDto()
    {
        ID = theEntity.ID,
        Description = theEntity.Description,
        ...
    };
}

【讨论】:

  • @ThePower 您永远不应该从不仅仅是 DTO 的 Web 服务返回任何内容。您的 Web 服务是一份合同,如果不立即破坏客户端,您就无法更改它。返回您的实体意味着您无法更改它们,但如果您有 DTO,您可以更改您的实体并仅更新映射,从而让您的客户满意。
  • @ThePower 只是为了补充安迪所说的,您还需要考虑一个事实,即实体具有与消费者无关的属性/数据负载,因此,您使用了不必要的带宽。一条经验法则是——只通过网络发送消费者真正需要的东西。此外,拥有不同的模型可以清楚地分离关注点,即您的实体用于持久性,而您的 DTO 用于在层/层之间传递数据。考虑到这是一个面向公众的 API,就像 Andy 提到的那样,这使您可以灵活地更改后端,而不会影响您的 API。
  • 太好了,感谢您提供的信息。我没有将它作为 API 风格的 Web 服务来处理。它更适用于网站的特定部分,其中需要在客户端工作,我需要打几个电话并获取一些数据以供显示。但现在将其视为我完全理解的面向公众的 API,它也打开了 API 的机会!谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-30
  • 1970-01-01
  • 2011-01-11
相关资源
最近更新 更多