2013-02-08 9 views
7

Ciao a tutti come posso passare l'ID cifrato in ActionLink, questo è quello che ho scritto nel mio viewcome crittografare l'ID stringa di query in mvc4 ActionLink

@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) 
} 
+0

Che tipo di crittografia in modo che si desidera utilizzare? –

+0

Qualsiasi tipo di crittografia invece di trasferire la pagina come 'http: // localhost: 1931/Home/Dettagli? TopicID = 1' Mi piacerebbe avere' http: // localhost: 1931/Home/Dettagli? TopicID = Ek7vP1YwVhc = ' – Dotnet

risposta

17

Qui ci sono un paio di semplici metodi che è possibile utilizzare codificare/decodificare. Il valore codificato non è sicuro e, come puoi vedere, la decodifica è banale. Se il tuo obiettivo è quello di offuscare l'id, funzionerà. Se è necessario sicuro, si dovrebbe adottare un approccio diverso.

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); 
} 

Così si potrebbe inserire questi metodi nel controller, e passare il TechId codificato per la vista con viewBag

int techId = 1; 
var encoded = Encode(id.ToString()); 
ViewBag.Encoded = encoded; 

E poi usarlo nel tuo link

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

(Tuttavia, dovresti davvero considerare l'utilizzo di un modello di visualizzazione: ViewBag, mentre un modo semplice e comodo per passare i dati alla vista, non è considerato una buona pratica. ews renderà la tua vita in mvc molto più facile in futuro. Per non parlare, produrre un codice più pulito e più manutenibile per quelli che ti seguono.)

+0

C'è un problema con questo codice, penso Convert.ToBase64String può generare (+) sign (io forse/anche io; m non sono sicuro) quei segni causano problemi nell'URL – Dabbas

0

Mi sono imbattuto in questo mentre cercavo un metodo sicuro per farlo. Nel caso in cui qualcun altro desideri farlo in modo sicuro, è possibile utilizzare MvcSerializer (l'ho trovato nel progetto MVC futures 3, non sono sicuro che sia incluso in MVC 4). Per esempio:

(new MvcSerializer()).Serialize(<Your data here>, SerializationMode.EncryptedAndSigned) 

E poi a invertire il processo di ...

(new MvcSerializer()).Deserialize(<Serialized data here>, SerializationMode.EncryptedAndSigned) 

Ciò è grande perché, senza alcuno sforzo aggiuntivo crittografa e firma i dati. Il progetto futures include anche alcuni attributi per farlo avvenire automaticamente durante il binding del modello.

2

aggiungere una cartella con due classi

Classe 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()); 
     } 

    } 
} 

Classe 2: MyExtensions

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

namespace MVCInvoicClient.Extensions 
{ 
    public static class MyExtensions 
    { 
     public static MvcHtmlString EncodedActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes) 
     { 
      string queryString = string.Empty; 
      string htmlAttributesString = string.Empty; 
      if (routeValues != null) 
      { 
       RouteValueDictionary d = new RouteValueDictionary(routeValues); 
       for (int i = 0; i < d.Keys.Count; i++) 
       { 
        if (i > 0) 
        { 
         queryString += "?"; 
        } 
        queryString += d.Keys.ElementAt(i) + "=" + d.Values.ElementAt(i); 
       } 
      } 

      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); 
       } 
      } 

      //<a href="/Answer?questionId=14">What is Entity Framework??</a> 
      StringBuilder ancor = new StringBuilder(); 
      ancor.Append("<a "); 
      if (htmlAttributesString != string.Empty) 
      { 
       ancor.Append(htmlAttributesString); 
      } 
      ancor.Append(" href='"); 
      if (controllerName != string.Empty) 
      { 
       ancor.Append("/" + controllerName); 
      } 

      if (actionName != "Index") 
      { 
       ancor.Append("/" + actionName); 
      } 
      if (queryString != string.Empty) 
      { 
       ancor.Append("?q=" + Encrypt(queryString)); 
      } 
      ancor.Append("'"); 
      ancor.Append(">"); 
      ancor.Append(linkText); 
      ancor.Append("</a>"); 
      return new MvcHtmlString(ancor.ToString()); 
     } 

     private static string Encrypt(string plainText) 
     { 
      string key = "jdsg432387#"; 
      byte[] EncryptKey = { }; 
      byte[] IV = { 55, 34, 87, 64, 87, 195, 54, 21 }; 
      EncryptKey = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, 8)); 
      DESCryptoServiceProvider des = new DESCryptoServiceProvider(); 
      byte[] inputByte = Encoding.UTF8.GetBytes(plainText); 
      MemoryStream mStream = new MemoryStream(); 
      CryptoStream cStream = new CryptoStream(mStream, des.CreateEncryptor(EncryptKey, IV), CryptoStreamMode.Write); 
      cStream.Write(inputByte, 0, inputByte.Length); 
      cStream.FlushFinalBlock(); 
      return Convert.ToBase64String(mStream.ToArray()); 
     }    
    } 
} 

controller

Add this line above the controller class Example for your Index 
[EncryptedActionParameter] 

Secondo lei

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

aggiungere un'istruzione using

@using MVCInvoicClient.Extensions 
+0

Dovresti usare davvero 'HttpUtility.ParseQueryString' ([documentation] (https://msdn.microsoft.com/en -us/library/ms150046.aspx)) invece di analizzarlo manualmente. – chteuchteu

+0

Nell'attributo si consiglia di modificare quanto segue farlo funzionare per qualsiasi tipo di parametro anziché solo int: dopo string [] paramsArrs = decrptedString.Split ('?'); mettere la riga seguente: var paramInfos = ((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.GetParameters(); e nel ciclo for farei questo: var paramArr = paramArrs[i].Split('='); var paramInfo = paramInfos.First(x => x.Name == paramArr[0]); var paramType = paramInfo.ParameterType; decryptedParameters.Add(paramArr[0], Convert.ChangeType(paramArr[1], paramType));

Problemi correlati