加密 URL 中的路由数据
Encrypt Route Data in URL
在我的 ASP.NET MVC 应用程序中,我想加密路由数据而不是 QueryString,换句话说:
我正在使用 ASP.NET MVC 默认路由模式:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "WHATEVER" }
);
而且我有 Action Method 带 id 参数:
public ActionResult Example(int id)
{
return View();
}
所以我的 Url 现在将数据传递给此操作方法是:
/Controller/Example/5
我想要这样
/Controller/Example/ENCRYPTEDPARAMTER
提前致谢
您可以为此参数使用自定义模型绑定器
// /Controller/Example/0000000A
public ActionResult Example([ModelBinder(typeof(EncryptDataBinder))]int id)
{
return View(id);
}
模型活页夹
public class EncryptDataBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(int))
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueProviderResult != null)
{
// Use your own logic here
bytes = ConvertUtilities.ToBytesFromHexa((string)valueProviderResult.RawValue);
return BitConverter.ToInt32(bytes, 0);
}
}
return base.BindModel(controllerContext, bindingContext);
}
}
我找到了一个 nice guide 来做我想做的事情,但是使用 QueryString 但不是路由数据 ,所以我更新了它以同时使用 QueryString 和路由数据,指南基于创建自定义助手和自定义属性,因此请轻松放置我的更改,我将通过代码提及我的更改:
自定义助手
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.
在我的 ASP.NET MVC 应用程序中,我想加密路由数据而不是 QueryString,换句话说:
我正在使用 ASP.NET MVC 默认路由模式:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "WHATEVER" }
);
而且我有 Action Method 带 id 参数:
public ActionResult Example(int id)
{
return View();
}
所以我的 Url 现在将数据传递给此操作方法是:
/Controller/Example/5
我想要这样
/Controller/Example/ENCRYPTEDPARAMTER
提前致谢
您可以为此参数使用自定义模型绑定器
// /Controller/Example/0000000A
public ActionResult Example([ModelBinder(typeof(EncryptDataBinder))]int id)
{
return View(id);
}
模型活页夹
public class EncryptDataBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(int))
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueProviderResult != null)
{
// Use your own logic here
bytes = ConvertUtilities.ToBytesFromHexa((string)valueProviderResult.RawValue);
return BitConverter.ToInt32(bytes, 0);
}
}
return base.BindModel(controllerContext, bindingContext);
}
}
我找到了一个 nice guide 来做我想做的事情,但是使用 QueryString 但不是路由数据 ,所以我更新了它以同时使用 QueryString 和路由数据,指南基于创建自定义助手和自定义属性,因此请轻松放置我的更改,我将通过代码提及我的更改:
自定义助手
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.