OData Simple Client:找不到类型[Type]的链接集合

时间:2015-08-06 06:56:18

标签: c# web-services xamarin odata

我有xamarin表单应用程序。我使用odata简单客户端来操作app数据库。

我正在尝试将数据添加到多对多表中。

这是我的第一个实体

    public class Genre : BaseGenre
    {
        List<User> Users { get; set; }
    }

而我的另一个

    public class User : BaseUser
    {
        List<Genre> Genres { get; set; }
    }

这就是我试图链接它们的功能

    public async void AddGenresAsnyc(User u, List<Genre> Genres)
    {
        u.Genres = Genres;
        try {
            //await client.For<User> (CollectionName).Key(u).LinkEntryAsync(us => us.Genres, Genres);
            await client.For<User> (CollectionName).Key(u.id).Set(u).UpdateEntriesAsync();
        } catch (Exception e) {
            Exception ex = e;
        }
    }

第一个,linkentryasync抛出异常

  

参数数量与预期计数不符。

第二个抛出

  

未找到[Genre]类型的链接集合

任何帮助都会很棒。我被困在工作中。提前谢谢。

1 个答案:

答案 0 :(得分:1)

您需要更改的一件事是将属性Genre.Users和User.Genres公开。 Simple.OData.Client使用反射来分配属性值,并且无法为私有属性/字段分配值。我使用您发送给我的架构测试了您的代码,只要属性是公开的,请求就会完成。

关于下一个示例(使用LinkEntryAsync),如果要在单个调用中更新链接,则应使用UpdateEntryAsync,因为LinkEntryAsync会为单个链接执行此操作。所以要么使用:

var user = await client.For<User>("ApiUser").Key(1).FindEntryAsync();
user.Genres = genres;
await client.For<User>("ApiUser").Key(user).Set(user).UpdateEntryAsync();

foreach (var genre in genres)
{
    await client.For<User>("ApiUser").Key(user).LinkEntryAsync(genre);
}

可以用更有效的方式编写第一个操作:

await client.For<User>("ApiUser").Key(1).Set(new {Genres = genres}).UpdateEntryAsync();

这将生成HTTP PATCH而不是仅更新Genres的PUT,但看起来您的OData服务要求在正在更新的实体上发送所有必需属性,因此这不起作用。

最后但并非最不重要:获取Simple.OData.Client的最新版本(4.9.1)。它有一个对您的场景很重要的修复。

更新。我测试了你的OData服务,它似乎没有对寻址链接的适当支持。例如,如果我测试样本OData服务,我可以执行http://services.odata.org/V4/OData/%28S%28ygi3rwu514y0a4ooybn3d1gc%29%29/OData.svc/Products%284002%29/Categories/ $ ref之类的请求(注意$ ref段,它解决了Caterogories链接,因此这个URI可用于发布链接更新)。但是,如果我执行请求http:// {your_service_uri} / ApiUsers%281%29 / Genres / $ ref,那么我收到一条错误消息“找不到与请求URI匹配的HTTP资源'http://partymag.azurewebsites.net/ApiUsers(1)/Genres/ $ ref'。”只要此链接在服务器端不起作用,您将无法使用LinkEntryAsync或UnlinkEntryAsync,但您仍然可以使用上面显示的UpdateEntryAsync。

UPDATE2。使用UpdateEntryAsync的版本执行正常,但服务不更新链接,这是Fiddler的结果:

生成的URI:PATCH http:// {your_service_uri} / ApiUsers(1) PATCH有效载荷:

{  "@odata.type":"#PMWeb.Models.Models.User",
"id":1,"Name":"Ege",
"LastName":"Aydin",
"Email":"{removed}",
"Password":"{removed}",
"Genres@odata.bind":[
    "http://{your_service_uri}/Genre(31)","http://{your_service_uri}/Genre(32)"
  ]
}

响应:

{
  "@odata.context":"http://{your_service_uri}/$metadata#ApiUsers/$entity",
"id":1,
"Name":"Ege",
"LastName":"Aydin",
"Email":"{removed}",
"Password":"{removed}"
}

如果我现在检查用户类型的内容,它们是相同的。由于生成的有效负载是正确的并且服务接受了它,因此它必须是服务器上未正确执行的东西。