RavenDB Id 和 ASP.NET MVC3 路由

发布于 2024-10-09 06:25:58 字数 910 浏览 9 评论 0原文

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

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

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

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

@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 将其解释为自己的路由。

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

Just building a quick, simple site with MVC 3 RC2 and RavenDB to test some things out.

I've been able to make a bunch of projects, but I'm curious as to how Html.ActionLink() handles a raven DB ID.

My example: I have a Document called "reasons" (a reason for something, just text mostly), which has reason text and a list of links. I can add, remove, and do everything else fine via my repository.

Below is the part of my razor view that lists each reason in a bulleted list, with an Edit link as the first text:

@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>
}

The Problem

This works fine, except for the edit link. While the values and code here appear to work directly (i.e the link is firing directly), RavenDB saves my document's ID as "reasons/1".

So, when the URL happens and it passes the ID, the resulting route is "http://localhost:4976/Reasons/Edit/reasons/2". So, the ID is appended correctly, but MVC is interpreting it as its own route.

Any suggestions on how I might be able to get around this? Do I need to create a special route to handle it or is there something else I can do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尹雨沫 2024-10-16 06:25:58

我刚刚下载了最新版本的 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);

您不需要扩展方法,这样您就不需要改变上面提到的任何路由,因为您将处理好的整数。字符串 Id 几乎是一个交易破坏者,但令人惊讶的是,它有效,因此 RavenDB 又回到了搜索中。

  • 注意:我通过观看 Rob Ashton 的演讲并意识到他的所有文档类都将整数作为 Id 得出了这一点。

I just downloaded the latest version of RavenDB and tried this out.

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

When I saved it to RavenDB, the id in Raven was "entities/1", but the mapping in RavenDB client was able to successfully interpret the Id from what was in the database to the integer that I wanted.

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

You do not need a extension method, and this way you would not need to alter any routes as mentioned above, because you will be dealing with good ol' integers. The string Ids were almost a deal breaker, but amazingly this works so RavenDB is back in the hunt.

  • Note: I figured this out from watching a Rob Ashton talk and realizing that all his document classes had integers as Ids.
鹊巢 2024-10-16 06:25:58

在找到 @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。

我们通过这种方法实现的 url 看起来像这样:

/items/details/1

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

I was having a similar issue and came up with my own solution before I found the link to Shiju Varghese blog post referenced by @jfar.

It might not be as clean and simple as the solutions provided in the blog post, but I do believe it can compete as a solution none the less. So here goes:

In a standard model class, when using RavenDB, we normally have an id property like so:

public string Id { get; set; }

What I did, was to add another id property like so:

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

This will give us the number part of the given RavenDB id.
I then had a class that looked something like this:

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

    ...
}

Note that I have excluded the IdInt property, as I don't want the model binder to handle it.
Furthermore, note, that the IdInt property is nullable. This is to avoid problems with the model binder later on, when we are creating new items and the Id property is null.

Then in the routes I declared a rule similar to this:

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

Later on using an ActionLink or something similar we can do the following:

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

And lastly when we press the rendered link, we are sent to the appropriate action which could look something like this:

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

The reason why this will work is because of the Load method, which takes a ValueType as parameter and then automatically resolves the number to the correct RavenDB id.

What we have achieved with this approach is a url that looks something like this:

/items/details/1

As I said in the beginning, this solution is less elegant than the previous suggested solutions, however, this approach will give you a cleaner url as you can work with the id's as you normally would.

绝不放开 2024-10-16 06:25:58

仅供参考,@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分隔符

FYI, the link posted by @jfar was exactly the article. The following is the solution I used from the article:

Solution 2 - Modify ASP.NET MVC Route

Modify the ASP.NET MVC routes in the
Global.asax.cs file, as shown in the
following code:

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

We just put "*" in front of the id
variable that will be working with the
default Id separator of RavenDB

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文