Using a query string with an form in MVC3 - c#

I have an MVC3 view with a form and i want to pass in a parameter via query string. Heres my form
#using (Html.BeginForm("LogOn", "Account", new { db = #Request.QueryString["db"] }, FormMethod.Post))
Heres my Controller
[HttpPost]
public ActionResult LogOn(LogOnModel model,string db)
When I click my Login button, and step through the code, the param db is null. Im passing it in like this:
http://localhost:64632/?db=someValue
My route looks like this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{db}", // URL with parameters
new { controller = "Account", action = "LogOn", db = UrlParameter.Optional } // Parameter defaults
);
What am i doing wrong?

Your route is expecting db to be a token in the url:
http://localhost:64632/Account/LogOn/someValue
You could grab the value from the querystring in your controller and store the db parameter in a ViewBag and it will be available on your form.

If that's the only route you have, then presumably the page you're currently on looks like "/controller/action/dbValue". In this case,
#Request.QueryString["db"]
won't fetch anything because db is a route value, it's not part of the query string. You could use
#ViewContext.RouteData.Values["db"]
instead.

It works. I am doing the same thing. I can retrieve the query string values on a http post: Request["queryparametername"]

well, this is a get method link : "http://localhost:64632/?db=someValue"
and you used the HttpPost attribute.

Related

Asp.net get submit method not working when url is mapped

I have a asp.net mvc form and i want to submit it to same page via get method, it's used for search purpose.
The url is mapped with route key value id.
#using (#Html.BeginForm("Contact", "Home",FormMethod.Get))
{
#Html.TextBox("id", null,
new
{
type = "time"
}
);
<input type="submit" />
}
When the form is generated the action attribute is containing the key value like /Home/Contact/myname.
Here myname is value of id present in url.
When form is submitted value key value for id is getting appended to URL like
http://localhost:57247/Home/Contact/myname?id=11%3A11
The action method is reading myname value instead of 11%3A11.
Action Method:
public ActionResult Contact(string id)
{
ViewBag.Message = id;
return View();
}
It's working fine with post method.
How to fix this?
replace #Html.BeginForm("Contact", "Home",FormMethod.Get)
with #Html.BeginForm()
By default forms are sent to same url they are rendered on and default method is get.
#Html.BeginForm() by default produces a METHOD="POST"
As for your parameter you might want to name it differently.
Default Mvc route is configured like this
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Depending on mvc version it can be in global.asax or App_Start\routeconfig.cs
So your "MyName" in url perfectly matches default id parameter and it has higher priority than query string parameters.
If you name your parameter differently (not id).
Change it to "q" for example in action and in view.
Your URLs will change to /Home/Contact?q=myname and everything should start working as expected.
Now you say that you want a solution with url mapping.
So you have to figure out for yourself what url scheme you want.
If you have a form and want it to post to /home/contact/myname?id=notyourname, than you have a conflict which to solve you will have to somehow change binding priorities in mvc.
Now you can inspect querystring on your own in your action and figure out new id passed without binding. After that you can return RedirectToAction("Contact", new{id = figuredId}) and the url in browser will be what you want it to be.
You can change the query parameter name and have your action recieve 2 parameters
public ActionResult Contact(string id, string q){
if (!string.IsNullOrWhitespace(q)){
return RedirectToAction("Contact",new{id=q});
}
}
To send request to /Home/Contact you should use #Html.BeginForm("Contact","Home",new{id=null}, FormMethod.Get)

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.

How to call Action on Button click from JQuery

With ASP.NET MVC, I want to call action of controller on Button Click from JQuery.
Controller:
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
public ActionResult PersonInfo(string name, string city)
{
// other code for assign ViewData
return View();
}
}
I have two textBox and one Button in Index.chtml page. I want to display Url like 'http://localhost:2526/PersonName'. for city I want optional perameter and don't want in Url. so, I mapped route as below:
routes.MapRoute(
"Default", // Route name
"",
new { controller = "Home", action = "Index" } // Parameter defaults
);
routes.MapRoute(
"PersonInfo", // Route name
"{name}", // URL with parameters
new { controller = "Home", action = "PersonInfo", name= "" , city = ""} // Parameter defaults
From browser if I enter Url like 'http://localhot:2526/John' then PersonInfo view displayed successfully.
I visited link related my question. But I also want to pass parameters.
Anyone help me How can I call action on button click from JQuery.
you can pass parameters as query string for example:
$('#buttonId').click(function(){
document.location =
'#Url.Action("MyAction","MyController")'+'?'+'parameterToSend = #value';
});
your link will be like
MyController/MyAction?parameterToSend=value
You want to add the paramaters inside the Url.Action Method to avoid the / at the end of your host.
#Url.Action("PersonInfo","Home" , new {name=Model.Name, city=Model.City })
//I believe this will look at your routes and generate localhost:2526/John/JohnsCity
Are your paramaters part of your model? If so the above will work. If not than you can use 1AmirJalali answer but replace the / before appending the paramaters since if they paramaters are not part of your model then they are probably coming via javascript variables.

asp.net mvc correctly get json data but can not show on the view page

I am beginner for .net MVC. I guess my problem is related to route setting.
What I want to do is :I get data from database, in controller transfer data to json format and pass to view, use javascript decode json data and show on the html.
When I write methods under TechnologyController, type localhost:portnumber/Technology/Index, no decoded json data in html format, but if I type localhost:portnumber/Technology/GetJson
It show me a page with pure json data (which means if I call GetJson() method separately, it works)
I write the same code in HomeController, it runs correct, all the route setting is default:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
//This is my controller
public class TechnologyController : Controller
{
public ActionResult Index()
{
return View();
}
public JsonResult GetJson()
{
Technology myTech = new Technology(); //get data from database (Tested correct)
return Json(myTech.select(), JsonRequestBehavior.AllowGet);
}
}
//This is Javascript:
<script type="text/javascript">
$(document).ready(function() {
$.getJSON("Technology/GetJson/", null, function(data) {
sss.innerHTML+=data["title"];// this part is correct (I already tested,please ignore), the purpose is to parse json data to html.
.......
}
)};
)};
I understand if I call "localhost:portnumber/Technology/Index", it only execute index method, that is why GetJson method is not called, but what url should I call in order to call index() as well as GetJson.
something like:
$.getJSON("#Url.Action("GetJson","Technology"), null, function(data) {
edit 2-
Without Razor it would look like this:
$.getJSON("<%= Url.Action("GetJson","Technology") %>, null, function(data) {
Edit-
Wait you want to call Index AND GetJson? That should already be happening, just load the /index page which calls index controller action, then in the rendered script from there your invoking the GJson action. Why would you think you need to call Index again?
I imagine your method isnt getting hit because the url is incorrect. Grab fiddler*, and take a look at the acutal http traffic and see if it is 404'ing on the request.
*(once fiddler is running change your url to http://localhost:port/..... to http://localhost.:port/.....)
I guess you could modify the "index" method inorder to get the data from "GetJSon" method something like below.
public ActionResult Index()
{
return View("GetJson");
}
Hope this helps!!

ASP.NET MVC2 Custom routing with wildcard or free text url

I have a requirement to add specific functionality to an asp.net mvc2 web site to provide addtional SEO capability, as follows:
The incoming URL is plain text, perhaps a containing a sentence as follows
"http://somesite.com/welcome-to-our-web-site" or
"http://somesite.com/cool things/check-out-this-awesome-video"
In the MVC pipeline, I would like to take this URL, strip off the website name, look up the remaining portion in a database table and call an appropriate controller/view based on the content of the data in the table. All controllers will simply take a single parameter bieng the unique id from the lookup table. A different controller may be used depnding on different urls, but this must be derieved from the database.
If the url cannot be resolved a 404 error needs to be provided, if the url is found but obsolete then a 302 redirect needs to be provided.
Where the url is resolved it must be retained in the browser address bar.
I have had a look at the routing model, and custom routing and can't quite work out how to do it using these, as the controller would not be predefined, based on a simple route. I am also unsure of what to do to provide 404, 302 back to the headers also. Perhpas I need a custom httpmodule or similar but going there went beyond my understanding.
This must be possible somehow... we did it years ago in Classic ASP. Can anyone help with some details on how to achieve this?
Well, the simplest way would be to have an id somewhere in the url (usually the first option)
routes.MapRoute(
"SEORoute", // Route name
"{id}/{*seostuff}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional, seostuff = UrlParameter.Optional } // Parameter defaults
);
In your controller you'd have something like
public class HomeController {
public ActionResult Index(int id) {
//check database for id
if(id_exists) {
return new RedirectResult("whereever you want to redirect", true);
} else {
return new HttpNotFoundResult();
}
}
}
If you don't want to use the id method you could do something else like...
routes.MapRoute(
"SEORoute", // Route name
"{category}/{page_name}", // URL with parameters
new { controller = "Home", action = "Index", category = UrlParameter.Optional, pagename = UrlParameter.Optional } // Parameter defaults
);
public ActionResult Index(string category, string page_name) {
//same as before but instead of looking for id look for pagename
}
The problem with the latter is that you would need to account for all types of routes and it can get really difficult if you have a lot of parameters that match various types.
This should get you in the right direction. If you neeed some clarification let me know and I'll see if I can write a specific route to help you
Additional
You could probably do what you're looking for like
public ActionResult Index() {
//Create and instance of the new controlle ryou want to handle this request
SomeController controller = new SomeController();
controller.ControllerContext = this.ControllerContext;
return controller.YourControllerAction();
}
but I don't know any of the side effects by doing that...so it's probably not a good idea - but it seems to work.

Categories