'How to hide Query string parameter in URL

I have a Telerik grid in which I am using client templates for edit/delete actions for each record. So for the edit/delete action I need to pass the id of that record along with the URL, here in this case I am afraid about some security issues. I am looking for a way to hide the query string parameter here to overcome this issues.

I am aware about encryption of parameter and currently I am using that. But i want to completely hide the query string parameter. I can't use session/ViewBag here since I can't set the session value for each record at the time of button click and access it in controller.

Any help is appreciated. Thanks in advance. my Controller and View codes are the following

View

@model IEnumerable<Data.Models.MyViewModel>
@{
    Volunteer.Data.User currentUser = (Data.User)Session["CurrentUser"];
}
<div id="myDivId">
    <p style="clear:none;">
        @Html.ActionLink("Add", "Create", "MyController", new { area = "", ID = ViewBag.MyDataID }, new { @class = "aMyClass" })
    </p>
    @{
        Html.Telerik().Grid<MyViewModel>().Name("MyGrid")
            .Columns(col =>
            {
                col.Bound(c => c.FirstName).Width("120px");
                col.Bound(c => c.LastName).Width("80px");
                col.Bound(c => c.Designation).Width("80px");
                col.Bound(c => c.Company).Width("80px");
                col.Bound(c => c.Married).Filterable(false).ClientTemplate(
                    "<input type='checkbox'" + "<#= Married?\"checked\":\"\" #>" + " OnClick='return false' />"
                    ).Width("40px");               
                if (currentUser.AdminRole == true || currentUser.Manager == true || currentUser.StaffRole == true)
                {
                    col.Bound(c => c.EmployeeID).Sortable(false).ClientTemplate(
                                        "<a href='" + Url.Content("~/MyController/Edit/") + "<#= EmployeeID #>' title='Edit Employee Details' class='edit'>Edit</a>" +
                                        "<a href='" + Url.Content("~/MyController/Delete/") + "<#= EmployeeID #>' title='Delete Employee Details' class='delete'>Delete</a>"
                    ).Title("Action").Width("75px");
                }
                else
                {
                    col.Bound(c => c.EmployeeID).Sortable(false).ClientTemplate(
                                        "<a href='" + Url.Content("~/MyController/Details/") + "<#= EmployeeID #>' title='Associated Party Details' class='details'>Details</a>"
                    ).Title("Action").Width("75px");
                }
            })

        .DataBinding(dataBinding => dataBinding.Ajax().Select("_GetEmployeeList", "MyController", new { id = "MyDataID" }))
        .Pageable()
        .Sortable()        
        .Render();
    }
</div>

Controller

public ActionResult Edit(int id)//Want to pass this id without using Query string parameter
{
    User user = (User)Session["CurrentUser"];

    Employee employee = db.Employees.Single(c => c.EmployeeID == id);
    //some code
    return View(employee);
}

[HttpPost]
public ActionResult Edit(Employee employee)
{
    User user = (User)Session["CurrentUser"];

    if (ModelState.IsValid)
    {
        db.Employees.Attach(employee);
        db.ObjectStateManager.ChangeObjectState(Employees, EntityState.Modified);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    Employee employee = db.Employees.Single(c => c.EmployeeID == id);
    //some code
    return View(employee);
}


Solution 1:[1]

But i want to completely hide the query string parameter.

Query string parameters are part of the HTTP standard for using the GET method as they are part of the URI.

HTTP 1.1 Get Request

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.

Please understand that the GET method by default, sends parsable information in the URI for example:

http://www.mywebsite.com/person?id=1
                                ^--- one location that can be parsed is the querystring

So hiding this means that you either need to change the way you make the request or change the request type.

@Html.ActionLink(/* irrelevant parameters*/)

Creates an Anchor Tag and part of the anchor tag is an attribute (href) that stores the URI. To my knowledge there is no default way to override the URI to not pass information via the Querystring.

HTTP 1.1 Post Request

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

This is a fancy way of saying, send information to the URI. However this time, you can either use the Querystring or using the body of the request (which as far as I know, GET does not allow a body of the request). The body can contain just about any type of mime type, but is typically application/x-www-form-urlencoded.

So an alternative piece of code to:

@Html.ActionLink("Add", "Create", "MyController", new { area = "", ID = ViewBag.MyDataID }, new { @class = "aMyClass" })

Might be:

@using(Html.BeginForm("Create", "MyController", FormMethod.Post))
{
  <input type="hidden" name="area" value="" />
  <input type="hidden" name="ID" value="@ViewBag.MyDataID" />
  <input type="submit" value="Add" />
}

Based on the question you asked, I highly suggest reading up on MVC at http://www.asp.net/mvc/overview/getting-started/introduction/getting-started.

Solution 2:[2]

I don't know how to make query strings completely invisible, but I can make them inaccessible for you.

The general idea idea is to create at least two pathways to the url with the query string. In the pathway(s) you want people to be able to access, create an intermediate method that redirects to the action where you want to return your view. The 2nd pathway will access that action I mentioned before directly. In the intermediate method, you tell a database to increase the value of "has this page been accessed before to 1.

You might have to think about the next part for a couple of hours before getting why it works 99% of the time. At the end of the intermediate method, set the value back to 0! In the action that returns a view, make it so that the view you want to return can only be returned if the value is set to 0! However, before the view is returned, set the value to 1! While, this method is not 100% secure. I think it is the only implementation that uses only basics and very little code. Obsfucating doesn't made query string urls inaccessible. It just makes it harder for people to access the website.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Alexander Kao