我想获得友好的网址。目前友好的网址是这样的:
本地主机/客户/ 1 / namehere
我希望他们这样:
本地主机/客户/ namehere
但仍然需要id(因为我用这个id搜索我的数据库)。 我的可能性是什么?这甚至可能吗?
这是我的MapRoute:
context.MapRoute(
"Customer_Default",
"customer/{customername}/",
new { controller = "customer", action = "view", id = "", customername = "" }
);
这是我链接的方式:
@Html.ActionLink(c.Bedrijfsnaam, "view", "customer", new { id = c.Klantnummer, customername = UrlEncoder.ToFriendlyUrl(c.Bedrijfsnaam) }, null)
感谢。
更新 哦,如果用户更改它并不重要。我只是想让它不显示。这样用户就可以轻松地将网址更改为他们想去的地方。而且不必担心ids。 (但我仍然需要它。:))
答案 0 :(得分:2)
你可以加密id
+加上一些哈希值。这样用户就不能简单地改变它。
或者您只需使用对称密码加密id
,例如AES
或DES
。结果id
会更长(因为它们工作在64-256位的块中)并且无法更改随机字符并获得有效的id
(技术上有足够的尝试可以这样做...祝你好运!)
代码示例
// Generate key. You do it once and save the key in the web.config or in the code
var encryptorForGenerateKey = Aes.Create();
encryptorForGenerateKey.BlockSize = 128;
encryptorForGenerateKey.KeySize = 128;
encryptorForGenerateKey.GenerateKey();
encryptorForGenerateKey.GenerateIV();
var key = encryptorForGenerateKey.Key;
var iv = encryptorForGenerateKey.IV;
// Encrypt
var encryptor = Aes.Create();
var encryptorTransformer = encryptorForGenerateKey.CreateEncryptor(key, iv);
int id = 123;
var bytes = BitConverter.GetBytes(id);
var encrypted = encryptorTransformer.TransformFinalBlock(bytes, 0, bytes.Length);
var encryptedString = BitConverter.ToString(encrypted);
Console.WriteLine(encryptedString);
// Decrypt
var decryptor = Aes.Create();
var decryptorTransformer = decryptor.CreateDecryptor(key, iv);
String[] arr = encryptedString.Split('-');
byte[] encrypted2 = new byte[arr.Length];
for (int i = 0; i < arr.Length; i++)
{
encrypted2[i] = Convert.ToByte(arr[i], 16);
}
// If the block is irregular there is the possibility TransformFinalBlock will throw
var result = decryptorTransformer.TransformFinalBlock(encrypted2, 0, encrypted2.Length);
if (result.Length != sizeof(int))
{
throw new Exception();
}
var id2 = BitConverter.ToInt32(result, 0);
id
= 123
我们有一个编码id
= 4E-CD-80-9E-7E-FB-A7-B9-74-B6-3A-37-57-9C-BD-A9
。我可以通过使用Base64或删除-
来缩短它,但在第二种情况下,代码会更难一些。没有-
:D2B4F51E6577967A2262E3AE51F3EC74
,在Base64中:0rT1HmV3lnoiYuOuUfPsdA==
考虑到您的使用,可能DES
足够安全。使用DES,id
将是:
F2-54-4B-CE-23-83-96-C2 // With -
F2544BCE238396C2 // Without -
8lRLziODlsI= // Base64
要使用DES将Aes
更改为DES
并删除BlockSize
和KeySize
行。
答案 1 :(得分:2)
如果我理解你的问题,那么id就是客户ID。
如果您不想显示您的ID,则解决方案是不使用数字ID并直接按客户端名称进行查询。 这确实有点慢但不是那么慢。 您可以通过客户端名称获取带有“反向”查询的ID,您可以按客户端名称进行索引。
通过用户名避免过多查询的一种可能性是使用post将id存储在会话中或表单中的隐藏字段中(您可以混合使用http post和http get而不会出现太多问题)。 您可以存储两个字段:客户端名称和客户端ID,如果客户端名称与http get中的名称匹配,则无需获取ID。如果它们不匹配,则可以在db中查询id。 我们的想法是缓存id,因此您只需按客户端搜索一次id。
答案 2 :(得分:0)
如果您希望结果具有确定性,则必须传递一些独特的参数组合。在您的情况下,对于具有相同名称的客户,您可以使用带有某个数字的“customername”参数(您必须将该数字与客户名称一起存储在数据库中)。例如:
localhost/customer/Aaron_Babichev - for the first customer with name Aaron Babichev
localhost/customer/Aaron_Babichev_2 - for the second customer with name Aaron Babichev
...
您的路线掩码类似于customer/{customername}_{customerIndex}/
。