In my ASP.NET MVC app, I want to encrypt the route data and NOT QueryString, in other word:
I’m using the ASP.NET MVC default route pattern :
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "WHATEVER" }
);
And I have Action Method take id Parameter:
public ActionResult Example(int id)
{
return View();
}
So My Url Now to pass the data to this Action Method is:
/Controller/Example/5
And I want it like this
/Controller/Example/ENCRYPTEDPARAMTER
Thanks in Advance
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I found a nice guide to do what I want but with QueryString BUT NOT Route Data, So I updated it to work with both QueryString and Route Data, the guide was based on creating custom Helper and custom Attribute, so put my changes easily, I will mention by code my changes:
Custom 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());
}
Custom Attribute:
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);
}
Actually My changes was not that big, so the creadit actually for this guide.
Method 2
You can use a custom model binder for this parameter
// /Controller/Example/0000000A
public ActionResult Example([ModelBinder(typeof(EncryptDataBinder))]int id)
{
return View(id);
}
The model binder
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);
}
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0