Short Answer
It is not possible to do what you want. In that if you want to be able to access the detailId
from your controller the you must pass the detailId
as part of your URL - you cannot access something that does not exist.
Long Answer
There are other ways to get around 'hiding' the detailId
from the user, and here are some suggestions:
1. Use Alias instead:
You can remove detailId
all together and use the Alias
value instead. This however will require the Alias
value to be unique to the product you are trying to query, and the required changes might look like this:
routes.MapRoute(
//..
url: "Products/{Alias}",
//..
);
public ActionResult ProductDetail(string Alias)
{
var pro = db.Products.FindByAlias(Alias);
//...
}
2. Use a POST request:
Another solution that will effectively hide the detailId
from the URL but still allow the value to be passed to the controller would be to use a POST request, where the parameter value would be specified in the POST request body.
The drawback of this however is that you cannot simply provide a URL for the user to click, and coding links within your site takes considerably more effort. Typically with MVC, POST request occur when a form is submitted, and you can also do POST request with javascript ajax calls.
This is a bit too much to go into in this answer so if you are interested then do some research, such as this question, or some generally info here.
3. Encrypt the detailId value:
Now this options doesn't hide the detailId
from the URL, but if your concern is that the current ID is just too user friendly then you could 'encrypt' (used loosely) the value. For example you could convert to a base64 string, and then back to an int within your controller. This would give you a URL something like this:
http://www.domain.com/Products/{Alias}-MQ%3D%3D
This URL represents 1
as the detailId
and you have to be ensure to URL encode/decode your values if using this method.
In this instance, Base64 conversion isn't really 'encrypting' it, any semi-savvy user will notice this and could get around it. But you could just as easily use a more secure 2-way encryption algorithm if you wanted to take this approach, one where only the server knows the encryption/decryption key. The drawback here is that only the server will be able to produce valid URLs for your users to 'click on'.
At this point it is worth considering that if your concern is that the URL is too user friendly by including a simple numeric ID, then the question is: why do you care?
If you are worried the user could simply change the detailId
value and then have access to products they should have access to, then you have a bigger problem with security. If this is the case, then your controller should be responsibly for validating is the user has access to the product they are trying to access, and then act accordingly.
All security checking and validation should be handled server-side, never rely on your client code or user actions to do it for you.