I have added the following route before the default route
routes.MapRoute(
name: "RecordDefault",
url: "{controller}/{action}/{name}",
defaults: new { controller = "Person", action = "Record" }
);
I can hit the page I want using: sitename/Person/Record/John
But I have an global search in the navigation with the following code
#using (Html.BeginForm("Record", "Person", FormMethod.Get, new { #class = "navbar-form navbar-left" }))
{
#Html.TextBox("name", "", new { #class = "form-control", placeholder = "Search Name" })
}
When I submit the form the following URL is displayed: sitename/Person/Record?name=John
What do I have to do to ensure the URL is formatted without the query string parameter?
Thanks
Not the same as the posted duplicate, that marked answer does not resolve my problem and according to the comments it also didnt work for others.
Your form generates ../Person/Record?name=John because a browser has no knowledge of your routes (which is c# code running on your server). And the HTML standards require that the value of successful form controls be added as query string values when the method is GET.
In order to generate your preferred url (../Person/Record/John), you need javascript to intercept and cancel the default submit, and build a url to navigate to. Using jQuery:
$('form').submit(function() {
var baseUrl = $(this).attr('action');
// or var baseUrl = '#Url.Action("Record", "Person")';
var url = baseUrl + '/' + $('#name').val();
location.href = url; // redirect
return false; // cancel the default submit
});
Use form post FormMethod.Post instead of Get. So the value will be not appeared in querystring.
#using (Html.BeginForm("Record", "Person", FormMethod.Post, new { #class = "navbar-form navbar-left" }))
{
#Html.TextBox("name", "", new { #class = "form-control", placeholder = "Search Name" })
}
In your Controller add the following -
[HttpPost]
public ActionResult Record(string name)
{
//code for what needs to be performed.
return View();
}
In your view add the following code replacing your existing and check -
#using (Html.BeginForm("Record", "Person", FormMethod.Post))
{
#Html.TextBox("name")
<input type="submit" />
}
Related
I am using this simple tutorial to upload a file in my MVC5 C# VS2015 project, and without requireing additional parameters in controllers action, file gets successfuly uploaded. Here are controllers action
[HttpPost]
public string UploadFile(HttpPostedFileBase file)
{
if (file.ContentLength <= 0)
throw new Exception("Error while uploading");
string fileName = Path.GetFileName(file.FileName);
string path = Path.Combine(Server.MapPath("~/Uploaded Files"), fileName);
file.SaveAs(path);
return "Successfuly uploaded";
}
and view's form for uploading
#using (Html.BeginForm("UploadFile", "Documents", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.TextBox("file", "", new { type = "file" })
<input type="submit" value="Dodaj fajl" />
}
In that view, I have another variable called DocumentNumber, that I need to pass on to UploadFile action. I only guess that then header of my action would look like this: public string UploadFile(HttpPostedFileBase file, int docNo) if I wanted to pass that variable on, but I also don't know how to set this value in view's form. I tried adding: new { enctype = "multipart/form-data", docNo = DocumentNumber } without success. How do I pass DocumentNumber (that needs to be hidden, not visible) from my view to controller's action with post method?
Add a parameter to your action method
[HttpPost]
public string UploadFile(HttpPostedFileBase file,int DocumentNumber)
{
}
and make sure your form has an input element with same name. It can be a hidden or visible. When you submit the form, the input value will be send with same name as of the input element name, which is matching to our action method parameter name and hence value will be mapped to that.
#using (Html.BeginForm("UploadFile", "Documents", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.TextBox("file", "", new { type = "file" })
<input type="text" name="DocumentNumber" value="123"/ >
<input type="submit" value="Dodaj fajl" />
}
If you want to use the DocumentNumber property value of your model, you may simply use one of the helper methods to generate the input element with the value (which you should set in the GET action method)
#Html.TextBoxFor(s=>s.DocumentNumber)
or for the hidden input element
#Html.HiddenFor(s=>s.DocumentNumber)
I'm creating a form for a DropDown like this:
#{
Html.BeginForm("View", "Stations", FormMethod.Get);
}
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"), new { onchange = "this.form.submit();" })
#{
Html.EndForm();
}
If I choose a value from my dropdown I get redirected to the correct controller but the URL is not as I would like to have it:
/Stations/View?id=f2cecc62-7c8c-498d-b6b6-60d48a862c1c
What I want is:
/Stations/View/f2cecc62-7c8c-498d-b6b6-60d48a862c1c
So how do I get the id= querystring parameter replaced by the more simple URL Scheme I want?
A form with FormMethod.Get will always post back the values of its form controls as query string values. A browser cannot generate a url based on your route configurations because they are server side code.
If you really wanted to generate /Stations/View/f2cecc62-7c8c-498d-b6b6-60d48a862c1c, then you could use javascript/jquery to build your own url and redirect
#using (Html.BeginForm("View", "Stations", FormMethod.Get))
{
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"))
}
var baseUrl = '#Url.Action("View", "Stations")';
$('#id').change(function() {
location.href = baseUrl + '/' $(this).val();
});
Side note: Submitting on the .change() event is not expected behavior and is confusing to a user. Recommend you add a button to let the user make their selection, check it and then submit the form (handle the button's .click() event rather that the dropdownlist's .change() event)
Remove "id"
from
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"), new { onchange = "this.form.submit();" })
I am trying to use #Html.ActionLink and send the value of my #Html.DropDownList selected item.
here is my code:
<span class="MemberList">
#Html.DropDownList("ParticipantList", new SelectList(ViewBag.ParticipantList, "UserName", "UserName", ViewBag.ParticipantList), new { #class = "members" })
</span>
<span>
#Html.ActionLink("Login", "Impersonate", "Studio", new { username = DropDown.SelectedValue }, new { #class = "gobutton3" })
</span>
So I am wondering how could I send the value to the ActionLink
the only way to add dynamic content to a link is through script
<a class="lnkLogin" href="#">Login</a>
and then in your script
$('.lnkLogin').on('click', function(){
var url = '#Url.Action("Impersonate", "Studio", new { username = "----" })';
url = url.replace("----", $('#ParticipantList').val());
window.location = url;
});
this will redirect using the window.location. being a login you may want to do an ajax call to verify credentials before redirecting.
I have the following in my view:
#Html.DropDownList("ProductionOrder", null, htmlAttributes: new { #class = "form-control", #id = "ProductionOrder" })
<div class="col-lg-6" id="ProductionOrderDetails"></div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
$("#ProductionOrder").change(function () {
var po = $("#ProductionOrder").val().toString();
//This alert is for debug purpose only
alert(po);
$.get('/wetWashRequests/GetDetails/' + po, function (data) {
$('#ProductionOrderDetails').html(data);
$('#ProductionOrderDetails').fadeIn('fast');
});
})
})
</script>
then I have the following in my controller:
public PartialViewResult GetDetails(string PONumber)
{
var details = db.vwProductionOrderLookups.Where(x => x.No_ == PONumber).SingleOrDefault();
return PartialView("_ProductionOrderDetails", details);
}
What I don't understand is why it doesn't pass the value to the controller or why, when I enter the URL manually in the browser, like so(http://localhost:51702/wetWashRequests/GetDetails/WO033960), it also doesn't assign it to the parameter and so returns no data.
What am I missing? I thought I was on the right track but...
You need to edit the route configuration to allow URL of type {controller}/{action}/{PONumber}. Otherwise, you can also send the PONumber via querystring, so that your URL looks like this:
http://localhost:51702/wetWashRequests/GetDetails?PONumber=WO033960
Use URL.Action() method
var url= "#Url.Action("wetWashRequests","GetDetails")"+"?PONumber="+po;
$.get(url,function(data)
{
});
I think this modification will work:
$.get('/wetWashRequests/GetDetails?PONumber=' + po,
please note #malkam's remark to always use: #Url.Action(controller,action)
var url= "#Url.Action("wetWashRequests","GetDetails")"+"?PONumber="+po;
To clarify:
In your app-start you'll probably have the default routing:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index",
id = UrlParameter.Optional }
);
This means you can have URL's like:
/wetWashRequests/GetDetails/999
but then the 999 is bound to a parameter is called id.
For all other variables you'll need the
/wetWashRequests/GetDetails?someParameter=999
syntax.
Alternatively, you can modify your routing.
I am trying to get my product search URL to look like "Products/Search/{search term here}".
I am using attribute based routing and my controller action looks like this:
[HttpGet]
[Route("Products/Search/{searchTerm?}", Name="ProductSearch")]
public ActionResult Search(string searchTerm = "")
{
return View();
}
I have tried using the HTML Helper for BeginForm and BeginRouteForm (shown below) but have not had luck with either. The right action is being called, but my URL looks like "Products/Search?searchTerm"
BeginRouteForm
#using (Html.BeginRouteForm("ProductSearch", new { searchTerm = "" }, FormMethod.Get, new { Class = "navbar-form navbar-right", role = "search" }))
{
<div class="form-group">
#Html.TextBox("searchTerm", null, new { Class = "form-control", placeholder = "Item # or Name" })
</div>
<button type="submit" class="btn btn-default">Search</button>
}
BeginForm
#using (Html.BeginForm("Search", "Products", new { searchTerm = "" }, FormMethod.Get, new { Class = "navbar-form navbar-right", role = "search" }))
{
<div class="form-group">
#Html.TextBox("searchTerm", null, new { Class = "form-control", placeholder = "Item # or Name" })
</div>
<button type="submit" class="btn btn-default">Search</button>
}
I have gone through debugging and the right route is selected, the URL is just not displaying how I wanted it to. What am I missing?
Here is the solution I suggest -
You have the following controller Action -
[HttpGet]
public ActionResult Search(string searchTerm = "")
{
return View();
}
Let the view be -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$('#click').click(function (e) {
var name = $("#search").val();
var url = '#Url.Action("Search", "Action")' + '/' + name;
window.location.href = url;
});
});
</script>
<input type="text" name="searchText" id="search"/>
<input type="button" value="click" id="click"/>
And when you click the button -
Do not forget to have proper route to be added on to the route configuration -
routes.MapRoute(
name: "searchaction",
url: "{controller}/{action}/{searchTerm}",
defaults: new { controller = "Action", action = "Search" }
);
The problem you think you are experiencing isn't because of anything about ASP.Net MVC. All Html Forms that use the method GET will translate all input elements into QueryString parameters. This is just a W3C standard.
If you want this to work, you'll have to write jQuery to throw an event before the form is submitted, take the text value from the input store it temporarily, empty the input box, and then update the action by appending the temporary value.
I don't think that BeginRouteForm works the way that you're expecting it to. According to the documentation, all that the method does is insert a <form> using the arguments provided. If you had provided something other than an empty string for the route value such as , new { searchTerm = "somesearchterm" }, you would see that show up in the Url as "/product/search/somesearchterm". As it is now, however, the form will be processed as normal, putting the search term on the Url as a normal query parameter.