Проблема RouteValuediCySary / Object в MVC ActionLink
-
25-09-2019 - |
Вопрос
Так вот идет:
У меня есть HTML-помощник, который делает ActionLink
S с дополнительными параметрами текущего URL-адреса в нем. Этот HTML Helper также позволяет вам добавить еще дополнительные параметры, как вы, пожалуйста, и сливаются их в 1 RouteValueDictionary
.
public static string ActionLinkwParams(this HtmlHelper helper, string linktext, string action, string controller, object extraRVs, object htmlAttributes) {
//get current optional params from current URL
NameValueCollection c = helper.ViewContext.RequestContext.HttpContext.Request.QueryString;
//put those in a dict
RouteValueDictionary r = new RouteValueDictionary();
foreach (string s in c.AllKeys) {
r.Add(s, c[s]);
}
RouteValueDictionary htmlAtts = new RouteValueDictionary(htmlAttributes);
RouteValueDictionary extra = new RouteValueDictionary(extraRVs);
//merge them
RouteValueDictionary m = RouteValues.MergeRouteValues(r, extra);
return helper.ActionLink(linktext, action, controller, m, htmlAtts).ToHtmlString();
}
Это работает идеально, но теперь я добавил Security ActionLinks.
так
return helper.ActionLink(linktext, action, controller, m, htmlAtts).ToHtmlString();
становится
return helper.SecurityTrimmedActionLink(linktext, action, controller, m, htmlAtts);
Что затем звонит:
public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, object extraRVs, object htmlAttributes) {
return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, extraRVs, htmlAttributes, false);
}
public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, object extraRVs, object htmlAttributes, bool showDisabled) {
if (controller == null) {
RouteData routeData = htmlHelper.ViewContext.RouteData;
controller = routeData.GetRequiredString("controller");
}
if (IsAccessibleToUser(action, controller)) {
return htmlHelper.ActionLink(linkText, action, controller, extraRVs, htmlAttributes).ToHtmlString();
} else {
return showDisabled ? String.Format("<span>{0}</span>", linkText) : "";
}
}
Теперь это не работает. Он компилирует, но мой URL выглядит не хорошо.
<a count="3" keys="System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]" values="System.Collections.Generic.Dictionary`2+ValueCollection[System.String,System.Object]" href="/2011-2012/Instelling?Count=3&Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&Values=System.Collections.Generic.Dictionary%602%2BValueCollection%5BSystem.String%2CSystem.Object%5D">Back to List</a>
Как вы видите, то, что ранее работала, сейчас не потому, что это берет RouteValueDictionary
как объекты, которые дают мне не результат, который я хочу.
так что я думал, что если я сделаю их RouteValueDictionary
S снова.
if (IsAccessibleToUser(action, controller)) {
RouteValueDictionary parsedextraRVs = null;
if (extraRVs != null && extraRVs.GetType().Name == "RouteValueDictionary") {
parsedextraRVs = (RouteValueDictionary)extraRVs;
}
RouteValueDictionary parsedHtmlAttributes = null;
if (htmlAttributes != null && htmlAttributes.GetType().Name == "RouteValueDictionary") {
parsedHtmlAttributes = (RouteValueDictionary)htmlAttributes;
}
return htmlHelper.ActionLink(linkText, action, controller, parsedextraRVs == null ? extraRVs : parsedextraRVs, parsedHtmlAttributes == null ? htmlAttributes : parsedHtmlAttributes).ToHtmlString();
}
Но это тоже дает мне URL-адрес, который я просто опубликовал выше. Почему эта работа в моем ActionLinkwParams
метод, но не когда ActionLinkwParams
называет SecurityTrimmedActionLink
Метод? И как я это исправить?
Решение
Изменить подпись SecurityTrimmedActionLink
Способ этого:
public static string SecurityTrimmedActionLink(
this HtmlHelper htmlHelper,
string linkText,
string action,
string controller,
RouteValueDictionary extraRVs,
RouteValueDictionary htmlAttributes
)
Обратите внимание на разницу между это а также это. Отказ В вашем случае (тот, который не работает), вы называете вторую перегрузку, принимая объекты, но в вашем случае вы не проходите анонимные объекты, а попереживать, который лечится как если бы это был анонимный объект и его публичные свойства (счетчик, Клавиши, значения) сериализуются как атрибуты.
Примечание: ваши методы помощника не являются правильными. Они возвращают струны. Это не то, как это должно быть. Методы помощника должны вернуться Mvchtmlstring..
Так вместо
public static string ActionLinkwParams(...)
{
...
return helper.ActionLink(linktext, action, controller, m, htmlAtts).ToHtmlString();
}
так должно быть:
public static MvcHtmlString ActionLinkwParams(...)
{
...
return helper.ActionLink(linktext, action, controller, m, htmlAtts);
}
Другие советы
Итак, что я сделал в конце (спасибо Дарин) добивается дополнительных перегрузок, чтобы сделать эту работу.
public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action) {
return SecurityTrimmedActionLink(htmlHelper, linkText, action, null, null);
}
public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller) {
return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, null);
}
public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, object extraRVs) {
return SecurityTrimmedActionLink(htmlHelper, linkText, action, null, extraRVs, null);
}
public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, object extraRVs) {
return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, extraRVs, null);
}
public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, RouteValueDictionary extraRVs) {
return SecurityTrimmedActionLink(htmlHelper, linkText, action, null, extraRVs, null);
}
public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, RouteValueDictionary extraRVs) {
return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, extraRVs, null);
}
public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, object extraRVs, object htmlAttributes) {
RouteValueDictionary rv = new RouteValueDictionary(extraRVs);
RouteValueDictionary html = new RouteValueDictionary(htmlAttributes);
return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, extraRVs, html);
}
public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, RouteValueDictionary extraRVs, IDictionary<String, Object> htmlAttributes) {
if (controller == null) {
RouteData routeData = htmlHelper.ViewContext.RouteData;
controller = routeData.GetRequiredString("controller");
}
if (IsAccessibleToUser(action, controller)) {
return htmlHelper.ActionLink(linkText, action, controller, extraRVs, htmlAttributes);
} else {
return MvcHtmlString.Empty;
}
}