Как опубликовать объект с навигационными отношениями в OData веб-API?

Я использую веб-API ASP.NET с OData. Я пытаюсь отправить объект Child, который имеет отношение к Parent (родительский объект уже существует). Когда я публикую объект (используя клиент службы данных WCF и SetLink), я вижу через Fiddler, что он добавляет <link...href=[address of parent]> в тело запроса. Точно такой же запрос работает с нашей версией службы данных WCF (мы переходим на веб-API). Однако это, похоже, ничего не переводит в метод Post на контроллере в веб-API.

При отправке дочернего элемента в ChildController, как я могу получить доступ к идентификатору родителя из действия Post в ChildController? Я знаю, что значение есть в запросе, но как я могу получить держать это значение? Ребенок не может быть создан без Родителя. Нужно ли мне изменять сигнатуру действия контроллера? Может быть, есть какой-то атрибут, который я могу использовать где-нибудь? С точки зрения API я хотел бы по возможности избегать добавления ParentId непосредственно в объект Child.

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>



Ответы (1)


Чтобы опубликовать объект по навигационной ссылке, вам необходимо определить свое действие в родительском контроллере. Вот фрагмент кода:

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();
    }
}
person zoe    schedule 31.05.2014
comment
Спасибо. Мой главный вопрос: как я могу сделать это с сообщением непосредственно в ChildController? Это рефакторинг, поэтому я пытаюсь сохранить существующее поведение веб-сервиса. - person Josh; 02.06.2014
comment
Привет, Джош, не могли бы вы поделиться URL-адресом и телом вашего запроса? Если вы не хотите отправлять сообщения в ParentController, зачем нужна навигационная ссылка? Или это child.Parent.Id, что вы хотите? - person Feng Zhao; 03.06.2014
comment
Привет @Feng, я обновил запрос выше. Я не возражаю против публикации в Parent в качестве дополнительной точки входа, однако было бы неплохо сохранить существующую возможность публикации в Child в качестве сущности верхнего уровня. Это происходит в нескольких разных местах нашего API, и было бы неплохо избежать рефакторинга потребителя API, и было бы неплохо иметь возможность в целом, я думаю. Отвечая на ваш другой вопрос, да, child.Parent.Id определенно является тем, что я пытаюсь понять, чтобы я мог создать сущность и связать ее с соответствующим родителем. Заранее спасибо за любые идеи! - person Josh; 03.06.2014