【问题标题】:How to POST an entity complete with navigational relationship in Web API OData?如何在 Web API OData 中发布具有导航关系的实体?
【发布时间】:2014-07-20 18:31:49
【问题描述】:

我正在使用带有 OData 的 ASP.NET Web API。我正在尝试发布一个 Child 实体,它与 Parent 有关系(父母已经存在)。当我发布实体(使用 WCF 数据服务客户端和 SetLink)时,我可以通过 Fiddler 看到它正在将 <link...href=[address of parent]> 添加到请求的正文中。这个完全相同的请求适用于我们的 WCF 数据服务版本的服务(我们正在迁移到 Web API)。但是,这似乎没有将任何内容转换为 Web API 中控制器上的 Post 方法。

将孩子发布到 ChildController 时,我如何从 ChildController 上的 Post 操作中访问 Parent 的 ID? 我知道请求中的值,但是如何我可以得到这个值吗?没有父级就无法创建子级。我需要修改控制器动作签名吗?也许我可以在某处使用某些属性?从 API 的角度来看,如果可能的话,我想避免将 ParentId 直接添加到子实体中。

public class ChildController
{
    public HttpActionResult Post([FromBody]Child child)
    {
        //child.Parent is null here, but all other 
        //properties of Child are populated.
        //How can I get the Parent's ID from the POST request??
    }
}

public class Child
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Parent Parent { get; set; }
}

public class Parent
{
    public int Id { get; set; }
    public IEnumerable<Children> Children { get; set; }
}

编辑: 这是我的要求。我更改了一些名称以保护无辜(替换主机名,以及带有父/子的实体名称):

POST https://localhost/MyWebService/Child HTTP/1.1
Content-Type: application/atom+xml
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 3.0;NetFx
Accept: application/atom+xml,application/xml
Accept-Charset: UTF-8
User-Agent: Microsoft ADO.NET Data Services

Host: localhost
Content-Length: 1048
Expect: 100-continue

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<category term="MyWebService.Entities.Child" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="https://localhost/MyWebService/Parents(1L)" />
<id />
<title /><updated>2014-05-30T16:07:28Z</updated><author><name /></author>
<content type="application/xml">
<m:properties>
<d:Content>content</d:Content>
<d:CreatedDate m:type="Edm.DateTime">0001-01-01T00:00:00</d:CreatedDate>
<d:Description>desc</d:Description>
<d:Enabled m:type="Edm.Boolean">true</d:Enabled>
<d:Id m:type="Edm.Int64">0</d:Id><d:TabName>tname</d:TabName>
</m:properties>
</content>
</entry>

【问题讨论】:

    标签: asp.net-web-api odata wcf-data-services asp.net-web-api-routing wcf-data-services-client


    【解决方案1】:

    为了从导航链接发布实体,您需要在父控制器中定义您的操作。这是代码sn-p:

    public class ParentController
    {
        public HttpActionResult PostToChildren(int key, [FromBody]Child child)
        {
            var parent = parents.single(p=>p.Id == key);
            if(parent != null)
            {
                parent.Children.Add(child);
                ChildController.Children.Add(child);
                return StatusCode(HttpStatusCode.NoContent);
            }
            else
                return BadRequest();
        }
    }
    

    【讨论】:

    • 谢谢。我的主要问题是:如何通过直接向 ChildController 发布帖子来做到这一点?这是一个重构,所以我试图维护现有的 Web 服务行为。
    • 嗨乔希,你能分享你的请求网址和正文吗?如果您不想发布到 ParentController,为什么会有导航链接?还是 child.Parent.Id 是你想要的?
    • 嗨@Feng,我在上面更新了请求。我不介意向 Parent 发布一个额外的入口点,但是保持现有的将 Child 作为顶级实体发布的能力会很好。这发生在我们 API 的几个不同的地方,避免对 API 使用者进行重构会很好,而且我想拥有一般的能力会很好。在回答您的另一个问题时,是的,child.Parent.Id 绝对是我想要获得的,这样我就可以创建实体并将其绑定到适当的父级。提前感谢您的任何想法!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 2014-07-09
    • 2013-12-06
    • 2017-11-13
    • 2021-09-21
    • 2012-11-07
    相关资源
    最近更新 更多