我找到了一个 nice guide 来做我想做的事,但使用的是 QueryString BUT NOT Route Data,所以我更新了它以同时使用 QueryString 和 Route Data,该指南基于创建自定义 Helper和自定义属性,所以我的更改很容易,我将通过代码提及我的更改:
自定义助手
public static MvcHtmlString EncodedActionLink(this HtmlHelper htmlHelper, string linkText, string Action, string ControllerName, string Area, object routeValues, object htmlAttributes)
{
string queryString = string.Empty;
string htmlAttributesString = string.Empty;
//My Changes
bool IsRoute = false;
if (routeValues != null)
{
RouteValueDictionary d = new RouteValueDictionary(routeValues);
for (int i = 0; i < d.Keys.Count; i++)
{
//My Changes
if (!d.Keys.Contains("IsRoute"))
{
if (i > 0)
{
queryString += "?";
}
queryString += d.Keys.ElementAt(i) + "=" + d.Values.ElementAt(i);
}
else
{
//My Changes
if (!d.Keys.ElementAt(i).Contains("IsRoute"))
{
queryString += d.Values.ElementAt(i);
IsRoute = true;
}
}
}
}
if (htmlAttributes != null)
{
RouteValueDictionary d = new RouteValueDictionary(htmlAttributes);
for (int i = 0; i < d.Keys.Count; i++)
{
htmlAttributesString += " " + d.Keys.ElementAt(i) + "=" + d.Values.ElementAt(i);
}
}
StringBuilder ancor = new StringBuilder();
ancor.Append("<a ");
if (htmlAttributesString != string.Empty)
{
ancor.Append(htmlAttributesString);
}
ancor.Append(" href='");
if (Area != string.Empty)
{
ancor.Append("/" + Area);
}
if (ControllerName != string.Empty)
{
ancor.Append("/" + ControllerName);
}
if (Action != "Index")
{
ancor.Append("/" + Action);
}
//My Changes
if (queryString != string.Empty)
{
if (IsRoute == false)
ancor.Append("?q=" + Encrypt(queryString));
else
ancor.Append("/" + Encrypt(queryString));
}
ancor.Append("'");
ancor.Append(">");
ancor.Append(linkText);
ancor.Append("</a>");
return new MvcHtmlString(ancor.ToString());
}
自定义属性:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
int Id;
Dictionary<string, object> decryptedParameters = new Dictionary<string, object>();
if (HttpContext.Current.Request.QueryString.Get("q") != null)
{
string encryptedQueryString = HttpContext.Current.Request.QueryString.Get("q");
//string decrptedString = Decrypt(encryptedQueryString.ToString());
string decrptedString = Decrypt(encryptedQueryString.ToString());
string[] paramsArrs = decrptedString.Split('?');
for (int i = 0; i < paramsArrs.Length; i++)
{
string[] paramArr = paramsArrs[i].Split('=');
decryptedParameters.Add(paramArr[0], Convert.ToInt32(paramArr[1]));
}
}
else if (!HttpContext.Current.Request.Url.ToString().Contains("?"))
{
//if (int.TryParse(Decrypt(HttpContext.Current.Request.Url.ToString().Split('/').Last()), out Id))
if (int.TryParse(Decrypt(HttpContext.Current.Request.Url.ToString().Split('/').Last()), out Id))
{
string id = Id.ToString();
decryptedParameters.Add("id", id);
}
}
else if (HttpContext.Current.Request.Url.ToString().Contains("?"))
{
//if (int.TryParse(Decrypt(HttpContext.Current.Request.Url.ToString().Split('/').Last().Split('?')[0]), out Id))
if (int.TryParse(Decrypt(HttpContext.Current.Request.Url.ToString().Split('/').Last().Split('?')[0]), out Id))
{
string id = Id.ToString();
if (id.Contains('?'))
{
id = id.Split('?')[0];
}
decryptedParameters.Add("id", id);
}
string[] paramsArrs = HttpContext.Current.Request.Url.ToString().Split('/').Last().Split('?');
for (int i = 1; i < paramsArrs.Length; i++)
{
string[] paramArr = paramsArrs[i].Split('=');
decryptedParameters.Add(paramArr[0], Convert.ToInt32(paramArr[1]));
}
}
for (int i = 0; i < decryptedParameters.Count; i++)
{
filterContext.ActionParameters[decryptedParameters.Keys.ElementAt(i)] = decryptedParameters.Values.ElementAt(i);
}
base.OnActionExecuting(filterContext);
}
其实我的改动并没有那么大,所以这个guide的真正功劳。