I am trying to get friendly urls. The friendly url at the moment are there like this:
localhost/customer/1/namehere
I want them like this:
localhost/customer/namehere
But still get want id (because I search my database with this id). What are my possibilities? And is this even possible?
This is my MapRoute:
context.MapRoute(
"Customer_Default",
"customer/{customername}/",
new { controller = "customer", action = "view", id = "", customername = "" }
);
This is how I link:
@Html.ActionLink(c.Bedrijfsnaam, "view", "customer", new { id = c.Klantnummer, customername = UrlEncoder.ToFriendlyUrl(c.Bedrijfsnaam) }, null)
Thanks.
Update: Oh, it doesn't matter if the user changes it. I just want it to not show. So that the user can easily change the url to where they want to go. And don't have to worry about ids. (But I still need it. :))
If I understood correctly your question, id is client id.
If you don't want to show your ID at all the solution is to not use a numeric id and do queries directly by client name. This is a little slower indeed but not so slow. You can get the id with a "reverse" query by client name, you can index by client name.
One possibility to avoid too much queries by username is to store the id in session or in an hidden field in a form using post (you can mix http post and http get without too much problems). You can store two fields: client name and client id, if client name match with the one in http get, you don't need to fetch the id. If they don't match, you can query the db for the id. The idea is to cache the id, so you search the id by client only once.
You could for example encrypt the id
+ add some hash on it. In this way the user couldn't simply change it.
Or you could simply encrypt your id
with a symmetric cipher, like AES
or DES
. The resulted id
would be longer (because they work in blocks of 64-256 bits) and it wouldn't be possible to change a random character and obtain a valid id
(technically with enough tries one could do it... Good luck!)
A code example
// 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);
for id
= 123
we have an encoded id
= 4E-CD-80-9E-7E-FB-A7-B9-74-B6-3A-37-57-9C-BD-A9
. I could have made it shorter by using Base64 or by removing the -
, but in the second case the code would be a little more difficult. Without the -
: D2B4F51E6577967A2262E3AE51F3EC74
, in Base64: 0rT1HmV3lnoiYuOuUfPsdA==
Considering your use, probably DES
is secure enough. With DES the id
would be:
F2-54-4B-CE-23-83-96-C2 // With -
F2544BCE238396C2 // Without -
8lRLziODlsI= // Base64
To use DES change all the Aes
to DES
and remove the BlockSize
and KeySize
lines.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With