ASP.NET MVC: правильный способ распространения параметра запроса по всем ссылкам ActionLink - PullRequest
5 голосов
/ 25 февраля 2012

В моем приложении key параметр строки запроса может использоваться для предоставления доступа к определенным действиям / представлениям.
Теперь я хочу, чтобы все ActionLinks и Forms автоматически включали этот параметр, если он присутствует в текущей строке запроса.

Как правильно это сделать?

Я спрашиваю о правильном пути, потому что я видел несколько решений, которые предлагали изменить представления так или иначе (альтернативные методы расширения / помощники, ручная передача параметров). Это не решение, которое я ищу.

UPDATE:
Окончательное решение (на основе ответа MikeSW): https://gist.github.com/1918893.

Ответы [ 6 ]

10 голосов
/ 25 февраля 2012

Вы можете сделать это с маршрутами, но вам нужно немного больше в будущем.Примерно так:

public class RouteWithKey:Route
{
  //stuff omitted
   public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
   {
     values.Add("key", requestContext.HttpContext.Request.QueryString["key"]);   
    var t = base.GetVirtualPath(requestContext, values);        
        return t;
    } 
}

Конечно, вам нужно извлечь ключ из параметров запроса и обработать случай, когда ключ является вторым параметром в запросе, но это приложение автоматически добавит ключ к каждомуUtel, созданный с помощью обычных помощников as.net mvc

Я просто использую собственный маршрут для приложения, для другой цели, но я проверил приведенный выше код, и он добавляет параметр, так чтов моем проекте, кажется, работает правильно.

2 голосов
/ 25 февраля 2012

Как насчет добавления ключа к значениям маршрута.

{контроллер} / {действие} / {ключ}

Всякий раз, когда URL содержит строку запроса с key = somevalue, URL будет выглядеть как

Home / Index / SomeValue

Теперь все ссылки на действия и относительные URL также будут включать это по умолчанию.

0 голосов
/ 08 июля 2012

Для этого я написал расширение для HtmlHelper под названием «ActionLinkBack».Методы compose action связывают обратно с тем же контроллером действие и объединяют существующие значения маршрута с любыми указанными новыми.

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, object routeValues)
{
    return ActionLinkBack(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary());
}

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, object routeValues, object htmlAttributes)
{
    return ActionLinkBack(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
}

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues)
{
    return ActionLinkBack(htmlHelper, linkText, routeValues, new RouteValueDictionary());
}

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
{
    // Build a new dictionary of route values based on the previous set
    var newRouteValues = new RouteValueDictionary(htmlHelper.ViewContext.RouteData.Values);

    // Retain current querystring parameters
    var queryString = htmlHelper.ViewContext.HttpContext.Request.QueryString;
    if (queryString.Count > 0)
    {
        foreach (string key in queryString.Keys)
        {
            newRouteValues[key] = queryString[key];
        }
    }

    // Add and override entries from the list of new route values
    if (routeValues != null)
    {
        foreach (var routeValueItem in routeValues)
        {
            newRouteValues[routeValueItem.Key] = routeValueItem.Value;
        }
    }

    return new HtmlString(htmlHelper.ActionLink(linkText, null, newRouteValues, htmlAttributes).ToHtmlString());
}

В моем представлении «навигатор страниц» многократного использования я использую расширения для составленияссылки на предыдущую, следующую и отдельные страницы:

@Html.ActionLinkBack("Next", new { page = (int)ViewData["Page"] + 1 }, new { @class = "navigationLink" })
0 голосов
/ 25 февраля 2012

Самое простое - поместить параметр «ключ» во все Url.Action и Html.ActionLink следующим образом:

@Url.Action("MyAction", "MyController", new { key = Request["key"] })

, если Request["key"] пусто, параметр строки запроса будет пропущен.

0 голосов
/ 25 февраля 2012

Наличие параметра строки запроса, который управляет авторизацией, является плохой идеей. Что мешает мне добавить этот параметр в мой URL, который не содержит?

Предпочтительным способом реализации авторизации является использование ролей (http://msdn.microsoft.com/en-us/library/system.web.security.roleprovider.aspx).

0 голосов
/ 25 февраля 2012

Привет для ситуации, которую вы описываете, вы можете легко использовать куки.Создайте файл cookie с ключом name и значением, равным значению для параметра URL вашего ключа.Теперь вы можете предоставить или отклонить доступ для ваших пользователей, используя наличие или отсутствие действительного файла cookie вместо наличия или отсутствия ключевого параметра.

Вы можете получить доступ к файлам cookie, используя Response.Cookies

вы все еще хотите изменить всех помощников Form и ActionLink, затем вы можете создать своих собственных помощников, которые будут вызывать помощников MVC, с дополнительным параметром key, и везде использовать настраиваемые помощники.Посмотрите здесь для написания пользовательских помощников

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...