2013-02-08 10 views
7

Cześć wszystkim, jak mogę przekazać zaszyfrowany identyfikator ActionLink, to co napisałem w moim viewJak szyfrować identyfikator ciąg kwerendy w 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

Jakie szyfrowanie więc chcesz użyć? –

+0

Wszelkiego rodzaju szyfrowanie zamiast przenoszenia strony jako 'http: // localhost: 1931/Home/Details? TopicID = 1' Chciałbym mieć' http: // localhost: 1931/Home/Details? TopicID = Ek7vP1YwVhc = ' – Dotnet

Odpowiedz

17

Oto kilka prostych metod można użyć do kodowania/dekodowania. Zakodowana wartość nie jest bezpieczna i jak widać dekodowanie jest banalne. Jeśli Twoim celem jest zamazanie identyfikatora, to zadziała. Jeśli potrzebujesz, aby zabezpieczyć, powinieneś przyjąć inne podejście.

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

Więc można umieścić te metody w kontrolerze, i przekazać zakodowany TechId do widoku z viewBag

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

A następnie używać go w linku

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

(Chociaż należy rozważyć użycie modelu widoku, ViewBag, który jest wygodnym i łatwym sposobem przekazywania danych do widoku, nie jest uważany za najlepszą praktykę. ews sprawi, że twoje życie w mvc będzie łatwiejsze w przyszłości. Nie wspominając już o produkowaniu czystszego i łatwiejszego w utrzymaniu kodu dla tych, którzy Cię śledzą.)

+0

Wystąpił problem z tym kodem, myślę, Konwertuj.ToBase64String może generować (+) znak (ja być może/też nie jestem pewien) te znaki powodują problemy w adresie URL – Dabbas

0

Natknąłem się na to, szukając bezpiecznej metody robienia tego. W przypadku, gdy ktoś inny chce to zrobić bezpiecznie, możesz użyć MvcSerializer (znalazłem go w projekcie Futures 3 MVC, nie jestem pewien, czy jest on zawarty w MVC 4). Na przykład:

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

A potem odwrócić proces ...

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

To jest wielki, ponieważ bez żadnego dodatkowego wysiłku szyfruje i podpisuje danych. Projekt futures obejmuje również pewne atrybuty, które umożliwiają automatyczne wykonywanie tego procesu podczas wiązania modelu.

2

dodać folder z dwóch klas

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

    } 
} 

Klasa 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] 

w widoku

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

dodać using

@using MVCInvoicClient.Extensions 
+0

Powinieneś naprawdę użyć 'HttpUtility.ParseQueryString' ([documentation] (https://msdn.microsoft.com/en -us/library/ms150046.aspx)) zamiast parsować go ręcznie. – chteuchteu

+0

W atrybucie, które zaleciłbym zmianę, spraw by działał dla dowolnego typu parametru zamiast tylko int: po napisie [] paramsArrs = decrptedString.Split ("?"); wstaw następującą linię: var paramInfos = ((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.GetParameters(); iw pętli for zrobiłbym to: 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));

Powiązane problemy