15

只需使用 MVC 3 RC2 和 RavenDB 构建一个快速、简单的站点来测试一些东西。

我已经能够制作一堆项目,但我很好奇 Html.ActionLink() 如何处理 raven DB ID。

我的例子:我有一个名为“原因”的文档(某事的原因,主要是文本),其中包含原因文本和链接列表。我可以通过我的存储库添加、删除和执行其他所有操作。

下面是我的剃刀视图的一部分,它在项目符号列表中列出了每个原因,第一个文本是编辑链接:

@foreach(var Reason in ViewBag.ReasonsList)
{
    <li>@Html.ActionLink("Edit", "Reasons", "Edit", new { id = Reason.Id }, null) @Reason.ReasonText</li>
    <ul>
    @foreach (var reasonlink in Reason.ReasonLinks)
    { 
        <li><a href="@reasonlink.URL">@reasonlink.URL</a></li>
    }
    </ul>
}

问题

这工作正常,除了编辑链接。虽然此处的值和代码似乎可以直接工作(即链接直接触发),但 RavenDB 将我的文档 ID 保存为“reasons/1”。

因此,当 URL 发生并传递 ID 时,生成的路由是“http://localhost:4976/Reasons/Edit/reasons/2”。因此,ID 被正确附加,但 MVC 将其解释为自己的路由。

关于我如何能够解决这个问题的任何建议?我需要创建一个特殊的路线来处理它还是我可以做些什么?

4

3 回答 3

13

我刚刚下载了最新版本的 RavenDB 并尝试了一下。

public class Entity {
    public int Id { get;set; }
    public string Text { get;set; }
}

当我将它保存到 RavenDB 时,Raven 中的 id 是“entities/1”,但 RavenDB 客户端中的映射能够成功地将 Id 从数据库中的内容解释为我想要的整数。

var entity = session.Load<Entity>(1);
Assert.IsTrue(entity.Id == 1);

你不需要扩展方法,这样你就不需要改变上面提到的任何路由,因为你将处理好的 ol' 整数。字符串 Ids 几乎是一个交易破坏者,但令人惊讶的是,这很有效,所以 RavenDB 又回来了。

  • 注意:我通过观看 Rob Ashton 的演讲并意识到他所有的文档类都有整数作为 Id 来发现这一点。
于 2012-02-07T14:47:58.437 回答
2

在找到@jfar 引用的 Shiju Varghese 博客文章的链接之前,我遇到了类似的问题并提出了自己的解决方案。

它可能不像博客文章中提供的解决方案那样干净简单,但我相信它仍然可以作为解决方案竞争。所以这里是:

在标准模型类中,当使用 RavenDB 时,我们通常有一个 id 属性,如下所示:

public string Id { get; set; }

我所做的是添加另一个 id 属性,如下所示:

public int? IdInt
{
    get { return int.Parse(Id.Substring(Id.IndexOf("/") + 1)); }
}

这将为我们提供给定 RavenDB id 的数字部分。然后我有一个看起来像这样的类:

[Bind(Exclude = "IdInt")]
public class Item
{
    public string Id { get; set; }
    public int? IdInt
    {
        get { return int.Parse(Id.Substring(Id.IndexOf("/") + 1)); }
    }

    ...
}

请注意,我已排除 IdInt 属性,因为我不希望模型绑定器处理它。此外,请注意,IdInt 属性可以为空。这是为了避免以后模型绑定器出现问题,当我们创建新项目并且 Id 属性为空时。

然后在路由中我声明了一个类似的规则:

routes.MapRoute(
    "WithParam", // Route name
    "{controller}/{action}/{id}" // URL with parameters
);

稍后使用 ActionLink 或类似的东西,我们可以执行以下操作:

@Html.ActionLink("Details", "Details", new { id = item.IdInt })

最后,当我们按下呈现的链接时,我们会被发送到适当的操作,看起来像这样:

public ActionResult Details(int id)
{
    var item = _session.Load<Item>(id);            
    return View(item);
}

这将起作用的原因是因为 Load 方法,该方法将 ValueType 作为参数,然后自动将数字解析为正确的 RavenDB id。

我们用这种方法实现的是一个看起来像这样的 url:

/项目/详细信息/1

正如我在开始时所说,这个解决方案不如之前建议的解决方案那么优雅,但是,这种方法会给你一个更干净的 url,因为你可以像往常一样使用 id。

于 2011-07-05T22:11:04.977 回答
0

仅供参考,@jfar 发布的链接正是这篇文章。以下是我在文章中使用的解决方案:

解决方案 2 - 修改 ASP.NET MVC 路由

修改Global.asax.cs文件中的ASP.NET MVC路由,如下代码所示:

 routes.MapRoute(
     "WithParam",                                           // Route name
     "{controller}/{action}/{*id}"                         // URL with parameters
     );  

我们只是将“*”放在将使用 RavenDB 的默认 Id 分隔符的 id 变量前面

于 2010-12-24T21:16:21.157 回答