Controller's get and post method
[HttpGet]
public ActionResult Index()
{
SoSession.Authenticate("pierre", "pierre");
return View();
}
[HttpPost]
public ActionResult Index(CompanySearch model)
{
return RedirectToAction("Companies",new{searchString=model.SearchString});
}
in view
#using (Html.BeginForm("Index", "Company"))
{
<div class="input-block-level">
#Html.TextBoxFor(m => m.SearchString)
#Ajax.ActionLink(
"Submit",
"Index",
new{},
new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "partialDiv" })
</div>
}
<div id="partialDiv"></div>
Problem
Whenever user clicks submit link i get forwarded to get method and not post method. How do i forward the call to post method of my controller?
Make sure you have the unobutrusive ajax library file (and it's dependencies (jQuery)) loaded to your view properly. If you do not have this file loaded to your page, Clicking on the link produced by Ajax.ActionLink helper method will do a GET request instead of the asynchronous POST you were expecting.
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
It sounds like you are trying to use an ajax form:
#using Ajax.BeginForm("Submit", "Company", FormMethod.Post, new AjaxOptions { UpdateTargetId = "partialDiv", InsertionMode = InsertionMode.Replace}) {
#Html.TextBoxFor(m => m.SearchString)
}
If you include the ajax js libraries that should work.
You can also use JQuery for the partial load although the controller would return a partial. I do agree with mayabelle that Ajax.BeginForm() is another route to take.
[HttpGet]
public ActionResult Companies(string searchString)
{
return this.PartialView("MyView", MyObject)
}
inside of the cshtml javascript:
var searchString = $("#SearchString").val();
$("#partialDiv").load('#Url.Content("~/Home/Companies/")' + searchString, function(){ DoSomething(); });
Related
I recently came upon this question as I have a solution I need to work on.
I have a controller which does some logic, with some method:
public Controller1: MvcController
{
public ActionResult SomeLogic(Model model)
{
return view();
}
public ActionResult SomeLogic2(Model model)
{
return view();
}
}
And I have a second controller which does different logic:
public Controller2: MvcController
{
public ActionResult SomeLogic(Model model)
{
return view();
}
public ActionResult SomeLogic2(Model model)
{
return view();
}
}
Both are working on the same view:
MyView.cshtml
The view contains a begin form that works on submit:
#using(Html.BeginForm("SomeLogic", "Controller1", FormMethod.Post)
and 4 submit buttons:
<input type='submit' formaction='SomeLogic' value='submit' />
<input type='submit' formaction='SomeLogic2' value='submit2' />
<input type='submit' formaction='SomeLogic' value='submit3' />
<input type='submit' formaction='SomeLogic2' value='submit4' />
I know I can control the action to which I am redirecting the submit using the:
formaction attribute.
I there a way to change the controller as well? meaning that:
<input type='submit' formaction='SomeLogic' value='submit3' />
<input type='submit' formaction='SomeLogic2' value='submit4' />
Will submit to controller2 instead of Controller1 which is defined in my begin form.
This will solve my debate whether to create a new controller or use the existing one, which is already full of complex logic.
You need to include controller name in the formaction attribute.
Note that your controller names are not valid, but assuming your have
public FirstController: Controller
{
[HttpPost]
public ActionResult SomeLogic(Model model)
{
return view();
}
}
public SecondController: Controller
{
[HttpPost]
public ActionResult SomeLogic(Model model)
{
return view();
}
}
Then you can post to the correct controller using
// Post to the SomeLogic method of FirstController
<input type="submit" formaction="#Url.Action("SomeLogic", "First")" value="submit" />
// Post to the SomeLogic method of SecondController
<input type="submit" formaction="#Url.Action("SomeLogic", "Second")" value="submit3" />
Just intercept the submit with jQuery
You can add an ID to your form, to be able to select it easily in jQuery
#using(Html.BeginForm("SomeLogic", "Controller1", FormMethod.Post, new { #id = "yourForm" })
Then
$("#yourForm").submit(function(e){
e.preventDefault();
var url1 = '#(Url.Action("SomeLogic1", "SomeController", null, Request.Url.Scheme))';
var url2 = '#(Url.Action("SomeLogic", "SomeController2", null, Request.Url.Scheme))';
//Whatever logic should you do to select which URL you want to POST to
$.ajax({
type: 'POST',
url: url_selected_above,
data: $('#yourForm').serializeArray(),
success: function (xhr, response) {
//...
},
error: function (xhr, response) {
//...
}
});
});
This should work if all the methods expect the same view model.
Alternatively, if you do not want to mess around in the UI, you can do something as such in the action that generates the form.
var controllerName = "SomeController";
var actionName = "Action1";
//do your logic to select whichever controller/action.
viewModel.ControllerName = controllerName;
viewModel.ActionName = actionName;
And in the view that has the form:
#using(Html.BeginForm(#Model.ActionName, #Model.ControllerName, FormMethod.Post)
Again, if all the actions expect the same view model, that should work.
How do you hook up a textbox to a method in MVC5 using attribute routing, with areas?
This is view:
#using (Html.BeginForm())
{
#Html.TextBox("searchpara")
#Html.ActionLink("Search", "SearchMethod", "Home", new { area = "Timetables" }, null)
}
Controller:
[RouteArea("Timetables")]
[RoutePrefix("Home")]
public class HomeController : Controller
{
Method:
[Route("SearchMethod/{searchpara=Test}")]
public ActionResult SearchMethod(string searchpara)
{
It doesn't work. The problem may not be routing?
I believe you want a submit button, and not an action link and you may need to update the form to post to a specific action if it is not the current action.
#using (Html.BeginForm("SearchMethod", "Home", new { area = "Timetables" }))
{
#Html.TextBox("searchpara")
<button type="submit">Search</button>
}
Ive just started to play around with ASP MVC and I come from a background of Web Forms.
Ive started a MVC internet application and wanted to know how a button calls an action from a controller. Here I would like to use the log in example that is provided with an MVC Internet application.
AccountController:
Lots of methods
Login View:
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Log in Form</legend>
<ol>
<li>
#Html.LabelFor(m => m.UserName)
#Html.TextBoxFor(m => m.UserName)
#Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
#Html.LabelFor(m => m.Password)
#Html.PasswordFor(m => m.Password)
#Html.ValidationMessageFor(m => m.Password)
</li>
<li>
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe, new { #class = "checkbox" })
</li>
</ol>
<input type="submit" value="Log in" />
</fieldset>
so when I hit the sumbit button on the view, which method in the AccountController class will be called? and how do you work it out?
Thanks all :)
When you click submit button you send a post request,and in your AccounController this Controller Action should called:
[HttpPost]
public ActionResult Login(Usermodel model)
{
}
I suggest you to watch this tutorial to learn MVC Controllers,Actions and some other stuff.It is a good training.
Edit: In MVC when you type a URL like localhost/Home/Index first it goes Home Controller and looking for an Index action, and it must be [HttpGet] action because your request is a Get request. But you don't need to mark your Action with HttpGet Attribute because it's default behaviour.It works like this way because of your RouteConfig.Your controllers return Views, if you look at your HomeController and AccountController you will see all actions returning a View, and if you Right click your action and click Go To the View you will see your View which belongs to your controller.
I presume you're talking about the default ASP.NET MVC Template, in this case you'll see that in the Login.cshtml view, you have a model defined at the top:
#model MyApp.Models.LoginModel
This will bind your view to this model. When you do a POST it will gather html elements from your form with names corresponding to the model properties.
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
...
}
This here creates a html form that will do a post to /Account/Login. However you can specify a different location:
#using (Html.BeginForm("Index", "Home", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) {
...
}
On the server side you'll be expecting the same model:
public ActionResult Login(LoginModel model, string returnUrl)
{
// awesomeness ...
}
Ive just started to play around with ASP MVC and I come from a
background of Web Forms
use ajax post on button click as same in aspx with url as action name and controller name, this is the closest you can get with webforms
$.ajax({
url: '#Url.Action("SendMail", "Contact")',
type: 'POST',
data: { listID: selected.toString(), flag: flag },
traditional: true,
success: function (result) {
}
});
or you can use whole form post using default way in MVC
[HttpPost]
public ActionResult SendMail(Mail model)
{
}
coz you have defined
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
on your view, which will point to default action through route, However you can change the default action explicitly defining desired action name and controller name using
#using (Html.BeginForm("ActionName", "ControllerName", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) {
I have a view called drawGraph , this is accessed through the controller via;
#Html.ActionLink("DrawGraph", "drawGraph", new {id =item.data})
When i use this link the page loads on a new page (as it would) i would like to display it as a part of the page that the link is on, is there any easy way to achive this?
my controller looks like this;
public ActionResult drawGraph(string data)
{
*Bunch of code
return View(chart);
}
Yes you can, however you need to use Ajax, luckily ASP.NET MVC provides some nice convenience methods like Ajax.ActionLink
#Ajax.ActionLink("DrawGraph", "drawGraph", new {id =item.data},
new AjaxOptions
{
UpdateTargetId = "yourDiv",
InsertionMode = InsertionMode.Replace,
})
<div id="yourDiv"> </div>
Then you need to return a partial view from your action with PartialView:
public ActionResult drawGraph(string data)
{
//Bunch of code
return PartialView(chart);
}
You should not forget to include the jquery.unobtrusive-ajax.min.js in your layout/view in order to the Ajax helpers work.
For example I am on page http://localhost:1338/category/category1?view=list&min-price=0&max-price=100
And in my view I want to render some form
#using(Html.BeginForm("Action", "Controller", new RouteValueDictionary { { /*this is poblem place*/ } }, FormMethod.Get))
{
<!--Render some controls-->
<input type="submit" value="OK" />
}
What I want is to get view parameter value from current page link to use it for constructing form get request. I tried #using(Html.BeginForm("Action", "Controller", new RouteValueDictionary { { "view", ViewContext.RouteData.Values["view"] } }, FormMethod.Get)) but it doesn't help.
I've found the solution in this thread
#(ViewContext.RouteData.Values["view"])
You should still have access to the Request object from within the view:
#using(Html.BeginForm(
"Action",
"Controller",
new RouteValueDictionary {
{ "view", Request.QueryString["view"] } }, FormMethod.Get))
You can't access Request object directly in ASP .NET Core. Here is a way to do it.
#ViewContext.HttpContext.Request.Query["view"]
From an MVC perspective, you would want to pass the value from the controller into the page e.g.
public ActionResult ViewCategory(int categoryId, string view)
{
ViewBag.ViewType = view;
return View();
}
Then in your view you an access #ViewBag.ViewType, you will need to cast it to a string though as it will by default be object (ViewBag is a dynamic object).