Идентификаторы RavenDB и маршруты ASP.NET MVC3 - PullRequest
15 голосов
/ 24 декабря 2010

Просто создайте быстрый, простой сайт с MVC 3 RC2 и RavenDB, чтобы проверить некоторые вещи.

Мне удалось создать несколько проектов, но мне любопытно, как Html.ActionLink () обрабатывает идентификатор базы данных raven.

Мой пример: у меня есть документназывается "причины" (причина для чего-то, в основном просто текст), который имеет текст причины и список ссылок.Я могу добавлять, удалять и делать все остальное нормально через мой репозиторий.

Ниже приведена часть моего вида бритвы, в которой перечислены все причины в маркированном списке со ссылкой «Редактировать» в качестве первого текста:

@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 сохраняет идентификатор моего документа как "reason / 1".

Итак, когда происходит URL-адрес и он передает идентификатор,В результате получается «http://localhost:4976/Reasons/Edit/reasons/2". Итак, идентификатор добавлен правильно, но MVC интерпретирует его как свой собственный маршрут.

Любые предложения о том, как я мог бы обойти это? Нужно ли создаватьспециальный маршрут, чтобы справиться с этим, или я могу что-то еще сделать?

Ответы [ 3 ]

13 голосов
/ 07 февраля 2012

Я только что скачал последнюю версию RavenDB и попробовал это.

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

Когда я сохранил его в RavenDB, идентификатор в Raven был «entity / 1», но отображение в клиенте RavenDB смогло успешно интерпретировать идентификатор из того, что было в базе данных, в целое число, которое я хотел.

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

Вам не нужен метод расширения, и таким образом вам не нужно будет изменять какие-либо маршруты, как упомянуто выше, потому что вы будете иметь дело с хорошими старыми целыми числами. Строковые идентификаторы были чуть ли не решающим фактором, но, как ни странно, это работает, поэтому RavenDB снова в поиске.

  • Примечание. Я понял это, посмотрев речь Роба Эштона и осознав, что все его классы документов имеют целые числа в качестве идентификаторов.
2 голосов
/ 06 июля 2011

У меня была похожая проблема, и я нашел собственное решение, прежде чем нашел ссылку на пост в блоге Шиджу Варгезе, на который ссылается @ jfar.

Возможно, он не такой простой и понятный, как решения, представленные в сообщении в блоге, но я уверен, что он может конкурировать как решение, тем не менее. Итак, вот так:

В стандартном классе модели при использовании RavenDB у нас обычно есть свойство id, например, так:

public string Id { get; set; }

Что я сделал, так это добавил еще одно свойство id, например:

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

Это даст нам номерную часть данного идентификатора RavenDB. У меня тогда был класс, который выглядел примерно так:

[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 имеет значение null. Это позволит избежать проблем с подшивкой модели в дальнейшем, когда мы создаем новые элементы, а свойство 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.

То, что мы достигли с помощью этого подхода, - это URL, который выглядит примерно так:

/ элементы / детали / 1

Как я уже говорил в начале, это решение менее элегантно, чем предыдущие предложенные решения, однако этот подход даст вам более чистый URL-адрес, поскольку вы можете работать с идентификаторами, как обычно.

0 голосов
/ 25 декабря 2010

К вашему сведению, ссылка, размещенная @jfar, была именно той статьей. Вот решение, которое я использовал из статьи:

Решение 2 - Изменить маршрут ASP.NET MVC

Изменить маршруты ASP.NET MVC в Файл Global.asax.cs, как показано в следующий код:

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

Мы просто ставим "*" перед идентификатором переменная, которая будет работать с стандартный разделитель идентификаторов RavenDB

...