Hide parameter value from URL - c#

I have a URL like this
http://localhost/PW/LeaveWithoutPay/Edit?id=9
and I want to hide the id?=9 from my URL. Can any one demonstrate how to hide this id parameter with an example? I am using Visual Studio 2012.

You must need to implement Post method instead of GET method. Here is a sample example for it.
In your controller define something like this
public ActionResult Edit([FromBody] int id) {
TempData["MsgText"] = id.ToString();
return RedirectToAction("Index");
}
Now in your view, implement the POST method. A sample example is:
#{string id =(string)TempData["MsgText"];}
#using (Html.BeginForm("Edit", "Home", FormMethod.Post, new { id = "frmCallThis" })){
#Html.Label("label",string.IsNullOrEmpty(id)?"No Id Provided":"Current ID = " + id)
#Html.TextBox("id");
<input type="submit" value="Get This Printed" />
}
Finally you have the following output: (Before Submit)
And After submit:
Hope this helps,

Only one thing you have to doing here is using POST, not GET method. Because the web request is usually stateless, so I don't think we have any other methods to hide your id.

Related

How to retrieve input's value from a textbox

I'm learning to develop a webapp using .net and I'm having a problem in retrieving the value from an <input>
Size:
#using (Html.BeginForm("GetList", "User", FormMethod.Post))
{
#Html.TextBoxFor(Model => Model.PageSize)
<input type="submit" value="Invia" />
}
I want to retrieve the value posted and then use it as a parameter in the url but all I try isn't working and all this is frustrating me a lot, thanks for the help.
In your Post method in the Controller, define an input variable with the same datatype of the model that you are using in the view. Then you will be able to get the values that you have on the screen.
What happens is that when the submit button is pressed, all the input values will be submitted to Controller's post method.
Supposing that your model's datatype is "User", the Controller's Post method should look like the below:
[HttpPost]
public ActionResult GetList(User model)
{
int pageSize = model.PageSize;
...
return View();
}

How to use RouteConfig to append a page URL

I am struggling to get my code work, but I think I've read enough to suggest this is the correct way to approach this.
On my intranet, I'd like the user to type in a single word to search into a textbox, and check a checkbox. When the new page loads, I'd like the URL rewritting services of ASP.NET MVC to kick in and change a value from
mysite.com/?id=blah&isChecked=true
to
mysite.com/home/index/blah/true
My code isn't working in the sense of it gives no error, but doesn't do what I am explaining. So, I've removed the check box to just focus on the textbox.
My only route is
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{MyType}",
defaults: new { controller = "Home", action = "Index", MyType = UrlParameter.Optional }
);
My Controller
public ActionResult Index()
{
ViewBag.Message = "Modify this";
return View();
}
[HttpGet]
public ActionResult Index(string MyType)
{
ViewBag.Message = "..." + MyType;
return View();
}
and my View has
#using (Html.BeginForm("Index", "Home",FormMethod.Get))
{
<input name="MyType" /><br />
<input type="submit" />
}
#Html.ActionLink("Click me", "Index", new { #MyType = "Blah" }) //renders correctly
The problem is, it shows the querystring still in the address bar
mysite.com/?MyType=MySearchValue
instead of
mysite.com/Home/Index/MySearchValue
You can't do this purely with routing because the browser will always send form values as query string parameters when they are part of a GET request. Once the request has been sent to the server, the MVC framework can't do anything about the URL that was used.
This leaves you with only one real option (assuming you don't want to send a custom request using JavaScript), which is to explicitly redirect to the desired URL (meaning you will always have two requests when this form is submitted).
The simplest way of doing this is simply in the controller (rather, in a separate controller to ensure that there is no conflict in method signatures):
public class FormController : Controller
{
public ActionResult Index(string MyType)
{
return RedirectToAction("Index", "MyProperController", new { MyType });
}
}
If you direct your form to this controller action, MVC will then use the routing engine to generate the proper URL for the real action and redirect the browser accordingly.
You could do this from the same controller action but it would involve inspecting the request URL to check whether a query string was used or not and redirecting back to the same action, which is a little odd.

ASP MVC and changing url of posted form

I have an MVC 4 app and I am using a RESTful methodology for my URLs. I have the following routes registered in my app (along with others that are not relevant to my question:
//EDIT
routes.MapRoute(alias + "_EDIT", alias + "/{id}/edit",
new { controller = controllerName, action = "edit" },
new { httpMethod = new RestfulHttpMethodConstraint(HttpVerbs.Get) });
//PUT (update)
routes.MapRoute(alias + "_PUT", alias + "/{id}",
new { controller = controllerName, action = "update" },
new { httpMethod = new RestfulHttpMethodConstraint(HttpVerbs.Put) });
I have the following methos in my controller mapping to these routes:
public override ActionResult Edit(int id)
{...}
public override ActionResult Update(RequestEditViewModel userModel)
{
if (!ModelState.IsValid)
{
//do some stuff to ensure lookups are populated
...
return View("Edit", userModel);
}
}
In my app when I perform a request to edit a request my URL looks like:
http://server/request/1/edit
it correctly calls the Edit method on my controller.
My Edit.cshtml uses the followng to ensure the Update method is called on PUT:
#using (Html.BeginForm("Update", "Request"))
{
#Html.HttpMethodOverride(HttpVerbs.Put);
...
}
My form is generated as follows:
<form action="/requests/71" method="post" autocomplete="off" novalidate="novalidate">
<input name="X-HTTP-Method-Override" type="hidden" value="PUT"/>
...
</form>
When I click the submit button it correctly calls my Update method.
OK...Now for the issue. If my model is NOT valid I want to return back the Edit model. As you can see in the above code but, the URL is the one called from the submit button:
http://server/request/1
not
http://server/requests/1/edit
I have tried an reviewed two other options but both of these redirect the request back through the Edit method again which adds additional overhead and also puts all the model values in the querystring which I do NOT want:
return RedirectToAction("Edit", userModel);
return RedirectToRoute("requests_Edit", userModel);
So, is there a way to just return the View as I have in my code but, ensure the URL changes back and include the "/edit"?
The only alternative I have come up with is to perform an AJAX call and put the update that way the URL never changes, but I was trying to avoid that for this form.
Conceptually, you want to be doing something like a Server.Transfer (that is, making on URL appear to be another.) This discussion may be of use to you:
How to simulate Server.Transfer in ASP.NET MVC?

How to hide parameters of URL

My current url is /Product/Create?date=5/7/2014%2012:00:00%20AM
Actually I want like this: /Product/Create
My sample code is :
public class ProductController : Controller
{
public ActionResult Create(DateTime date)
{
ViewBag.Date = date;
return View();
}
}
Any one can help me?
Assuming that this is infact a GET request for a view which requires a Date parameter (for whatever reason) I'd say your best bet is to pass the information as a custom header in the request
GET /Products/Create HTTP/1.1
X-YourApp-Date: 2014-07-05T12:00:00
Your action would then look like
public ActionResult Create() <-- no parameters
{
ViewBag.Date = DateTime.ParseExact(Request.Headers["X-YourApp-Date"],
"yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture);
return View();
}
Some side notes
It's generally best to work with dates as UTC and not as Local (however it really depends on the circumstance)
If the date is important or used in anyway related to security then you should probably encrypt it.
If you are passing it up as a string use a consistent format and stick with it, this makes it easier when it comes to server-side parsing (see example)
You can use HttpPost to force this:
public class ProductController : Controller
{
[HttpPost]
public ActionResult Create(DateTime date)
{
ViewBag.Date = date;
return View();
}
}
And when calling the action you need to submit it via a form-post. If you show us the code how you call it we can help you there...
The HttpPost attribut will force you to use "post" - if you still want the "other option" possible you can leave the attribute away and just use "post" for your desired case.
UPDATE:
You need to call the action like:
#using(Html.BeginForm("Create", "Product", FormMethod.Post))
{
#Html.Hidden("date", DateTime.Now.ToString())
<input type="submit" value="create">
}
To your current code <a href="/Product/Create?date=#DateTime.Now.Date">:
This creates a GET request and even if you want that you should do it like the following:
#Html.ActionLink("Create", "Product", new { date = DateTime.Now.ToString() })
This will take the proper routing in account and create a valid link.
Using e.g. JQuery you can do the follwoing to have a link if JS is enabled:
#using(Html.BeginForm("Create", "Product", FormMethod.Post, new { id = "myForm" }))
{
#Html.Hidden("date", DateTime.Now.ToString())
<input id="myFormSubmit" type="submit" value="create">
<a id="myFormLink" href="#" style="display: none;" onclick="$('#myForm').submit(); return false;">create</a>
}
<script type="text/javascript">
$(document).ready(function () {
$('#myFormLink').show();
$('#myFormSubmit').hide();
});
<script>
In addition with controller change to handle only POST requests
...
[HttpPost]
public ActionResult Create(DateTime date)
...
You also have to change code for calling action in markup from link to something like
#using(Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { style = "display:inline" })) {
#Html.Hidden("date", DateTime.Now.ToString())
Whatever
}
In JS:
window.history.pushState("", "", "/Product/Create");

html form posting to mvc controller

I am trying to set up a simple login html page, whose action is sent to mvc controller on another of my sites. I have no problem setting up the page to do the post, and in the mvc controller I have my method that reads the form post. The problem is that I am not seeing my fields from the html form in the form collection.
Is there something special that I need to do to read a form post within a mvc controller method, if so what is that?
The is the form action markup from my page
<form action="http://reconciliation-local.sidw.com/login/launch" method="post">
User Name <input type="text" id="username"/><br/>
Password <input type="text" id="password"/>
<input type="submit" value="launch"/>
</form>
The controller method
[HttpPost]
public ActionResult launch(FormCollection fc)
{
foreach (string fd in fc)
{
ViewData[fd] = fc[fd];
}
return View();
}
When I step through the controller method code, I am not seeing anything in the formcollection parameter.
Post Html To MVC Controller
Create HTML page with form (don't forget to reference a Jquery.js)
<form id="myform" action="rec/recieveData" method="post">
User Name <input type="text" id="username" name="UserName" /><br />
Password <input type="text" id="password" name="Password"/>
<input type="submit" id="btn1" value="send" />
</form>
<script>
$(document).ready(function () {
//get button by ID
$('#btn1').submit(function () {
//call a function with parameters
$.ajax({
url: 'rec/recieveData', //(rec)= Controller's-name
//(recieveData) = Action's method name
type: 'POST',
timeout: '12000', (optional 12 seconds)
datatype: 'text',
data: {
//Get the input from Document Object Model
//by their ID
username: myform.username.value,
password: myform.password.value,
}
});
});
});
</script>
Then in The MVC Controller
controller/action
| |
1. Create Controller named rec (rec/recieveData)
Create View named rec.cshtml
Here is the controller:
public class recController : Controller
{
// GET: rec
string firstname = "";
string lastname = "";
List<string> myList = new List<string>();
public ActionResult recieveData(FormCollection fc)
{
//Recieve a posted form's values from parameter fc
firstname = fc[0].ToString(); //user
lastname = fc[1].ToString(); //pass
//optional: add these values to List
myList.Add(firstname);
myList.Add(lastname);
//Importan:
//These 2 values will be return with the below view
//using ViewData[""]object...
ViewData["Username"] = myList[0];
ViewData["Password"] = myList[1];
//let's Invoke view named rec.cshtml
// Optionaly we will pass myList to the view
// as object-model parameter, it will still work without it thought
return View("rec",myList);
}
}
Here is the View:
#{
ViewBag.Title = "rec";
}
<h2>Hello from server</h2>
<div>
#ViewData["Username"]<br /> <!--will display a username-->
#ViewData["Password"] <!-- will display a password-->
</div>
If you posted some code it would be much easier to help you, so please edit your question...
Make sure that your form's action has the correct address, that your method is specifying POST (method="POST") and that the input fields under your form have name attributes specified.
On the server side, try making your only parameter a FormCollection and test that the fields in your form posted through the debugger. Perhaps your model binding isn't correct and the FormCollection will at least show you what got posted, if anything.
These are just common issues I've seen. Your problem could be different, but we need to see what you're working with to be able to tell.
Try something like this:
cQuery _aRec = new cQuery();
_aRec.Sqlstring = "SELECT * FROM Admins";
DataSet aDS = _aRec.SelectStatement();
DataTable aDT = aDS.Tables[0];
foreach (DataRow aDR in aDT.Rows){
if (txtAdminUsername.Text == aDR[0].ToString()){
if (txtAdminPassword.Text == aDR[1].ToString()){
Session["adminId"] = aDR[0];
Response.Redirect("Admin.aspx");
return;
}
}
}
Make sure that your FormCollection object properties for username and password are defined properly.
I had to use the name attribute on the text tag, and that solved my problem, is now working like a charm.
You have to use Ajax to do that.. Whenever you want to "submit" from client side, you should use Ajax to update the server
Step 1 - you redirect your Ajax call to your action, but with your list of parameters in the query-string appended
$.ajax(url: url + "?" + your_query_string_parameter_list_you_want_to_pass)
Step 2 - add optional parameters to your Controller-action with the same names and types you expect to get returned by the client
public ActionResult MyControllerAjaxResponseMethod(type1 para1 = null,
type2 para2 = null,
type3 para3 = null, ..)
Know that the optional parameters have to be initialized, otherwise the Action itself will always ask for those
Here's where the "magic" happens though --> MVC will automatically convert the query-string parameters into your optional controller-parameters if they match by name
I was also looking for a good answer for this, --> i.e. - one that doesn't use q-s for that usage, but couldn't find one..
Kinda makes sense you can't do it in any other way except by the url though..

Categories