【问题标题】:How to access a child object using OData, WebAPI and a DTO?如何使用 OData、WebAPI 和 DTO 访问子对象?
【发布时间】:2014-03-25 16:14:04
【问题描述】:

从 WebAPI 控制器,我从 OData 请求 /odata/ProjectEditor?$format=json&$inlinecount=allpages&$top=10 返回 ProjectEditorDTO 对象列表:

    [Queryable]
    public virtual IHttpActionResult Get(ODataQueryOptions<Website> odataQueryOptions)
    {
        var userId = UserContext.Identity.UserId;
        try
        {
            var results = odataQueryOptions.ApplyTo(_uow.Repository<Website>()
                .Query()
                .Get()
                .Where(u => u.UserId == userId)
                .OrderBy(o => o.WebsiteName)).Cast<Website>()
                .Select(s => new ProjectEditorDTO()
                {
                    // projection
                    WebsiteId = s.WebsiteId,
                    WebsiteGUID = s.WebsiteGUID,
                    WebsiteName = s.WebsiteName,
                    WebsiteNotes = s.WebsiteNotes,
                    DefaultContentTypeId = s.ContentType.ContentTypeId,
                    DefaultContentType = new ContentTypeDTO
                    {
                        ContentTypeId = s.ContentType.ContentTypeId,
                        Description = s.ContentType.Description
                    }
                });

            var r = results.ToList();
            . . .

JSON 输出:

{
  "odata.metadata":"http://localhost:1981/odata/$metadata#ProjectEditor","odata.count":"2","value":[
    {
      "WebsiteId":6,"WebsiteName":"Jobs","WebsiteGUID":"5252fa54-5cbc-4b7e-aa74-4fc2c5c90a6a","WebsiteNotes":"notes","DefaultContentTypeId":67
    },{
      "WebsiteId":7,"WebsiteName":"news","WebsiteGUID":"f0717700-5900-44f7-84a4-9dde9a451285","WebsiteNotes":"notes","DefaultContentTypeId":65
    }
  ]
}

在投影中,我定义了DefaultContentType,但它没有出现在返回给客户端的JSON数据中,即使它在.ToList()点处可见。

我不想定义导航属性,所以我不应该(也不能)$expand 它。

我可以简单地在投影中定义DefaultContentTypeIdDefaultContentTypeDescription,就可以解决问题。但是,我想知道如何让DefaultContentType 对象出现在序列化的 JSON 对象中。

-- 更新--

ProjectEditorDTO:

public class ProjectEditorDTO
{
    [ForeignKey("DefaultContentTypeId")]
    public int WebsiteId { get; set; }

    [Required]
    [StringLength(100, MinimumLength = 3)]
    [Display(Name = "Project Name")]
    public string WebsiteName { get; set; }

    public string WebsiteGUID { get; set; }
    //public string WebsitePW { get; set; }
    public string WebsiteNotes { get; set; }

    public int DefaultContentTypeId { get; set; }
    public string DefaultContentTypeDescription { get; set; }

    public virtual ContentTypeDTO DefaultContentType { get; set; }
}

ContentTypeDTO:

public class ContentTypeDTO
{
    public int ContentTypeId { get; set; }

    [Required]
    [StringLength(100, MinimumLength=3)]
    [Display(Name="Content Type")]
    public string Description { get; set; }
}

【问题讨论】:

  • ProjectEditorDTO 是实体还是复杂类型?你能提供你的元数据吗?
  • @Schandlich - 我添加了上面的类。

标签: json c#-4.0 odata asp.net-web-api2


【解决方案1】:

我相信CLR类型ContentTypeDTO是你元数据中的一个实体类型,可以通过请求得到

http://localhost:1981/odata/$metadata

只需将其更改为复杂类型即可。改变

odataConventionModelBuilder.Entity<ContentTypeDTO>() 

odataConventionModelBuilder.ComplexType<ContentTypeDTO>();

【讨论】:

  • 感谢您的建议。这行得通,但是我之前定义了以下路线:modelBuilder.EntitySet&lt;ContentTypeDTO&gt;("ContentType");,可通过 ~/odata/ContentType 访问。我不能将类型定义为EntitySetComplexType。我该如何解决这个问题?
  • 如果 ContentTypeDTO 是实体类型,则 DefaultContentType 是导航属性,因此必须使用 $expand。
猜你喜欢
  • 2013-06-02
  • 2014-09-07
  • 2013-11-26
  • 2019-07-14
  • 1970-01-01
  • 2014-08-01
  • 2014-02-16
  • 1970-01-01
  • 2018-07-24
相关资源
最近更新 更多