RavenDB Ids和ASP.NET MVC3路由

时间:2010-12-24 18:49:41

标签: asp.net-mvc asp.net-mvc-3 actionlink ravendb

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

我已经能够制作一堆项目,但我很好奇Html.ActionLink()如何处理乌鸦数据库ID。

我的例子:我有一个名为“reason”的文档(一个事情的原因,主要是文本),它有原因文本和链接列表。我可以通过我的存储库添加,删除和完成其他所有操作。

以下是我的剃刀视图中的一部分,其中列出了项目符号列表中的每个原因,并将编辑链接作为第一个文本:

@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保存为“reason / 1”。

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

有关如何解决这个问题的任何建议?我是否需要创建一个特殊的路线来处理它,或者我还能做些什么呢?

3 个答案:

答案 0 :(得分:13)

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

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

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

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

您不需要扩展方法,这样您就不需要改变上面提到的任何路由,因为您将处理好的ol&#39;整数。字符串ID几乎是一个交易破坏者,但令人惊讶的是,这可以使RavenDB重新开始搜索。

  • 注意:我从观看Rob Ashton的演讲中了解到这一点,并意识到他所有的文档类都有整数作为Ids。

答案 1 :(得分: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属性为null。

然后在路线中我宣布了一条类似于此的规则:

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。

我们用这种方法取得的成果是一个类似于此的网址:

/项目/信息/ 1

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

答案 2 :(得分:0)

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

  

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

     

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

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

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