Asp.net mvc 4 如何在MVC4ActionLink中加密查询字符串ID

Asp.net mvc 4 如何在MVC4ActionLink中加密查询字符串ID,asp.net-mvc-4,Asp.net Mvc 4,如何在ActionLink中传递加密的id。这是我在我的视图中写的: @model IEnumerable<forumAPP.tblTechnology> @foreach (var item in Model) { string techName=item.TechName; @Html.ActionLink(techName, "Details","Home", new { TopicID = item.TechID },null) // Here I would like to

如何在
ActionLink
中传递加密的id。这是我在我的
视图中写的:

@model IEnumerable<forumAPP.tblTechnology>
@foreach (var item in Model)
{
string techName=item.TechName;
@Html.ActionLink(techName, "Details","Home", new { TopicID = item.TechID },null) // Here I would like to encrypt the TopicID
<br />
<br />
@Html.DisplayFor(modelItem => item.TechDesc)
}
@model IEnumerable
@foreach(模型中的var项目)
{
字符串techName=item.techName;
@ActionLink(techName,“Details”,“Home”,new{TopicID=item.TechID},null)//这里我想加密TopicID


@DisplayFor(modeleItem=>item.TechDesc) }
这里有两种简单的编码/解码方法。 编码的值是不安全的,正如您所看到的,对其进行解码非常简单。如果您的目标是混淆id,这将起作用。如果您需要保护它,您应该采取不同的方法

public string Encode( string encodeMe )
{
    byte[] encoded = System.Text.Encoding.UTF8.GetBytes( encodeMe );
    return Convert.ToBase64String( encoded );
}

public static string Decode( string decodeMe )
{
    byte[] encoded = Convert.FromBase64String( decodeMe );
    return System.Text.Encoding.UTF8.GetString( encoded );
}
因此,您可以将这些方法放置在控制器中,并将编码的TechId传递给带有viewBag的视图

int techId = 1;
var encoded = Encode(id.ToString());
ViewBag.Encoded = encoded;
然后在链接中使用它

@Html.ActionLink(techName, "Details","Home", new { TopicID = ViewBag.Encoded },null)

(但是,你应该真正考虑使用一个视图模型。ViewBag,一种将数据传递给视图的简便方法并不被认为是最佳实践。对视图模型和强类型视图感到舒适会使你的MVC生活在将来变得更容易。更不用说,为那些T产生更干净和更可维护的代码。这是我在寻找安全的方法时遇到的。如果其他人希望安全地执行此操作,您可以使用MVC序列化程序(我在MVC futures 3项目中找到它,我不确定它是否包含在MVC 4中)。例如:

(new MvcSerializer()).Serialize(<Your data here>, SerializationMode.EncryptedAndSigned)
(新的MvcSerializer()).Serialize(,SerializationMode.EncryptedAndSigned)
然后要逆转这个过程

(new MvcSerializer()).Deserialize(<Serialized data here>, SerializationMode.EncryptedAndSigned)
(新的MvcSerializer())。反序列化(,序列化模式。加密并签名)

这很好,因为它不需要任何额外的努力就可以对数据进行加密和签名。futures项目还包括一些属性,以便在模型绑定期间自动执行此操作。

添加一个包含两个类的文件夹

类别1:EncryptedActionParameterAttribute

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Web;
using System.Web.Mvc;

namespace MVCInvoicClient.Extensions
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class EncryptedActionParameterAttribute : ActionFilterAttribute
    {

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

            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[] paramsArrs = decrptedString.Split('?');

                for (int i = 0; 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);

        }

        private string Decrypt(string encryptedText)
        {

                string key = "jdsg432387#";
                byte[] DecryptKey = { };
                byte[] IV = { 55, 34, 87, 64, 87, 195, 54, 21 };
                byte[] inputByte = new byte[encryptedText.Length];

                DecryptKey = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, 8));
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                inputByte = Convert.FromBase64String(encryptedText);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(DecryptKey, IV), CryptoStreamMode.Write);
                cs.Write(inputByte, 0, inputByte.Length);
                cs.FlushFinalBlock();
                System.Text.Encoding encoding = System.Text.Encoding.UTF8;
                return encoding.GetString(ms.ToArray());
        }

    }
}
在您看来

 @Html.EncodedActionLink("Download Invoice", "FileDownload","DataFiles", new { id = item.DataFilesID }, null)
添加using语句

@using MVCInvoicClient.Extensions

您希望使用哪种加密?任何一种加密,而不是以
http://localhost:1931/Home/Details?TopicID=1
我想要
http://localhost:1931/Home/Details?TopicID=Ek7vP1YwVhc=
我认为此代码有问题,Convert.ToBase64String可能会生成(+)符号(我可能/我也不确定)这些符号会导致URL出现问题您应该真正使用
HttpUtility.ParseQueryString
(),而不是手动解析它。在属性中,我建议更改以下内容,以使其适用于任何参数类型,而不仅仅是int:after string[]paramsars=decrptedString.Split(“?”);放置以下行:
var-paramInfos=((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.GetParameters();
在for循环中,我会这样做:
var-paramArr=paramArr[i]。拆分('=');var-paramInfos=paramInfos.First(x=>x.Name==paramArr[0]);var paramType=paramInfo.ParameterType;decryptedParameters.Add(paramArr[0],Convert.ChangeType(paramArr[1],paramType));
 @Html.EncodedActionLink("Download Invoice", "FileDownload","DataFiles", new { id = item.DataFilesID }, null)
@using MVCInvoicClient.Extensions