How to hide parameters of URL - c#

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");

Related

How to prevent controller from changing the View

I'm new to MVC, and currently I'm trying to create a function for my form that exports it values to PDF. I managed to do that using input with submit type that calls the controller.
My problem is when I want to keep the values in the form (because I want to create another button that will send the form as e-mail), but the form resets after clicking on the button.
I tried creating void function instead of action result, but after calling, the browser tries to redirect to another page with controller names as URL.
I also tried to change the input type from submit to button, but after changing it, it won't call the controller on click.
So there is my question, how to call the controller without causing the form to reset its values.
Here is index.cshtml that calls the controller
<div class="row clearfix">
<div class="input-group">
<input id="pdfBtn" value="Export to pdf" type="submit" formaction="#Url.Action("pdfExport")" />
</div>
</div>
Here is the controller
[HttpPost]
public ActionResult pdfExport([Bind(Include = "formId,formType,additionalTypeInfo,nameSurname,description,Attachment")] FormModel model)
{
if (ModelState.IsValid)
{
var pdf = new FormToPdf(model);
}
return RedirectToAction("Index");
}
You can try to return the model to Index action like this:
[HttpPost]
public ActionResult pdfExport([Bind(Include = "formId,formType,additionalTypeInfo,nameSurname,description,Attachment")] FormModel [HttpPost]
public ActionResult pdfExport([Bind(Include = "formId,formType,additionalTypeInfo,nameSurname,description,Attachment")] FormModel model)
{
if (ModelState.IsValid)
{
var pdf = new FormToPdf(model);
}
return RedirectToAction("Index");
})
{
if (ModelState.IsValid)
{
var pdf = new FormToPdf(model);
}
return RedirectToAction("Index",model);
}
Or you can use ajax to pass data when button click,so that the page will not be refreshed:
<input id="pdfBtn" value="Export to pdf" type="button" onclick="pdfExport()"/>
js:
function pdfExport() {
$.ajax({
type: "POST",
url: "pdfExport",
data: Data,
success: function (data) {
}
});
}
You are doing Redirection in your server side code.
Do an AJAX call to your MVC controller (better if it is Web API controller) and from controller return HTTP OK / HTTP Accepted. While doing AJAX call using JavaScript/jQuery on button click, prevent the default behaviour (submit the form) of the button like in this way:
function onButtonClickPdfExportToServerUsingAjax(e){
e.PreventDefault();
// AJAX call
}
After receiving successful AJAX call response, proceed with whatever you want to do next.

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();
}

Updating layout part dynamically

C# asp.net MVC project: I have my index page with a button in it, I want to press it and update the same page with some results.
Here's some code:
The View: (with a button that calls the getConfig method in the controller)
#{
ViewBag.Title = "Home Page";
}
<form method="get" action="/Home/GetConfig/" >
<input type="submit" value="Get Config WS" />
</form>
<p>
#ViewBag.totalRecords
</p>
The controller:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Test webservices";
return View();
}
public void getConfig()
{
string totalRecords = string.Empty;
wsConfig.config_pttClient client = new wsConfig.config_pttClient();
wsConfig.getConfigInput gci = new wsConfig.getConfigInput();
wsConfig.getConfigOutput gco = new wsConfig.getConfigOutput();
gco = client.getConfig(gci);
totalRecords = gco.result.totalRecords.ToString();
ViewBag.totalRecords = totalRecords;
}
I want to press the view's button and show the totalRecords on the same page.
How can I achieve this?
Edit: There might be other solutions, (if you don't mind updating your entire page) but this how I generally do it.
Ok, there are a couple of things that you need to change in order to make it work:
Create a new partial view that contains just the part that you would like to update (and wrap it an element with an id). In this example, let's call it 'Partial_TotalCount'.
This partial view will contain the following code:
<div id="updated">
<p>
#ViewBag.totalRecords
</p>
</div>
Now, change your original view so that it includes the partial view:
#{
ViewBag.Title = "Home Page";
}
<form method="get" action="/Home/GetConfig/" >
<input type="submit" value="Get Config WS" />
</form>
#Html.Partial("Partial_TotalCount", #Model)
Now, update your controller to work with an ajax request. This would make your controller looks like:
public ActionResult Index()
{
ViewBag.Message = "Test webservices";
if (Request.IsAjaxRequest())
{
getconfig();
return PartialView("Partial_TotalCount");
}
return View();
}
Now, you need to be able to submit the page when you click the button. This can be done through javascript:
First your javascript function that will update the contents:
<script type="text/javascript">
function Refresh() {
$.ajax({
url: '/Home/Index',
type: "GET",
dataType: "html",
success: function(data) {
$("#updated").html(data);
},
error: function() { alert('Refreshing error.'); }
});
}
</script>
You just need to add an onclick on your button. And you can remove the form tags from around your form aswell.
Edit: As requested by the questioner, I provide a bit of explanation on the Javascript function itself:
$.ajax means that we are doing an Ajax request. It means that we are doing some asynchronous requests with the server.
Then a couple of parameters are passed:
Url: The url that should be executed. In your example, the code behind the url "Home/GetConfig" get's executed.
Type: The type of submit that you want to do (POST, GET, ...)
dataType: The type we are expecting back from the server.
Success: The piece of javascript that needs to execute when complete. (In this case, update the DIV element with the id "WithCss" with the contents that are received with the url "Home/Getconfig".
Error: A function that is executed when the request failed for some reason.
There are a lot of other parameters you can pass (for example if you need to pass an id, and others.
For more explanation, please look at the original documentation.
Also, consider marking this answer as accepted.
I hope it works.
Try This:
Replace your input button code with the following code :
<input type="submit" id="btnSave" name="BtnSave" value="Get Config WS" />
Then in controller change the whole code for this code:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Test webservices";
return View();
}
public ActionResult getConfig()
{
return View();
}
[HttpPost]
public ActionResult getConfig(FormCollection Form)
{
if(Form["BtnSave"]!=null)
{
string totalRecords = string.Empty;
wsConfig.config_pttClient client = new wsConfig.config_pttClient();
wsConfig.getConfigInput gci = new wsConfig.getConfigInput();
wsConfig.getConfigOutput gco = new wsConfig.getConfigOutput();
gco = client.getConfig(gci);
totalRecords = gco.result.totalRecords.ToString();
ViewBag.totalRecords = totalRecords;
}
return View();
}
Hopefully it works...!

Hide parameter value from URL

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.

ASP.NET MVC Preview 4 - Stop Url.RouteUrl() etc. using existing parameters

I have an action like this:
public class News : System.Web.Mvc.Controller
{
public ActionResult Archive(int year)
{
/ *** /
}
}
With a route like this:
routes.MapRoute(
"News-Archive",
"News.mvc/Archive/{year}",
new { controller = "News", action = "Archive" }
);
The URL that I am on is:
News.mvc/Archive/2008
I have a form on this page like this:
<form>
<select name="year">
<option value="2007">2007</option>
</select>
</form>
Submitting the form should go to News.mvc/Archive/2007 if '2007' is selected in the form.
This requires the form 'action' attribute to be "News.mvc/Archive".
However, if I declare a form like this:
<form method="get" action="<%=Url.RouteUrl("News-Archive")%>">
it renders as:
<form method="get" action="/News.mvc/Archive/2008">
Can someone please let me know what I'm missing?
You have a couple problems, I think.
First, your route doesn't have a default value for "year", so the URL "/News.mvc/Archive" is actually not valid for routing purposes.
Second, you're expect form values to show up as route parameters, but that's not how HTML works. If you use a plain form with a select and a submit, your URLs will end up having "?year=2007" on the end of them. This is just how GET-method forms are designed to work in HTML.
So you need to come to some conclusion about what's important.
If you want the user to be able to select something from the dropdown and that changes the submission URL, then you're going to have to use Javascript to achieve this (by intercepting the form submit and formulating the correct URL).
If you're okay with /News.mvc/Archive?year=2007 as your URL, then you should remove the {year} designator from the route entirely. You can still leave the "int year" parameter on your action, since form values will also populate action method parameters.
I think I've worked out why - the route includes {year} so the generated routes always will too..
If anyone can confirm this?
Solution
Okay here is the solution, (thanks to Brad for leading me there).
1) Require default value in route:
routes.MapRoute(
"News-Archive",
"News.mvc/Archive/{year}",
new { controller = "News", action = "Archive", year = 0 }
);
2) Add a redirect to parse GET parameters as though they are URL segments.
public ActionResult Archive(int year)
{
if (!String.IsNullOrEmpty(Request["year"]))
{
return RedirectToAction("Archive", new { year = Request["year"] });
}
}
3) Make sure you have your redirect code for Request params before any code for redirecting "default" year entries. i.e.
public ActionResult Archive(int year)
{
if (!String.IsNullOrEmpty(Request["year"]))
{
return RedirectToAction("Archive", new { year = Request["year"] });
}
if (year == 0)
{
/* ... */
}
/* ... */
}
3) Explicitly specify the default value for year in the Url.RouteUrl() call:
Url.RouteUrl("News-Archive", new { year = 0 })

Categories