Ajax.BeginForm ignores action and controller defined in parameters in MVC 5 - ajax

I am using attribute routing for get action of the page. But when I post it, ajax form ignores action and controller which I defined in parameters and tries to post to same url with get method.
This is my get action:
[AllowAnonymous]
[HttpGet]
[Route("path")]
public ActionResult Action()
{
return View();
}
This is my post action:
[AllowAnonymous]
[HttpPost]
public JsonResult Action(Model model)
{
return Json(true);
}
This is my view:
#using (Ajax.BeginForm("Action", "Controller", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "someDiv" }))
{
#SomeInput
<input type="submit" value="send" />
}
This the generated HTML:
<form action="/path" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#someDiv" id="form0" method="post">
<input value="submit" type="submit">
</form>
When the button is clicked. A post to domain/path is firing. Why the action I defined is ignored?

I was able to solve this issue by adding a null RouteValues after the Controller/ Action:
#using (Ajax.BeginForm("Action", "Controller", null, new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "someDiv" }))
{
#SomeInput
<input type="submit" value="send"/>
}
In my example I have an EditorTemplate with its own Ajax.BeginForm defined. When I render that EditorTemplate from within a DisplayTemplate it overrides the child EditorTemplate's Controller destination to the one the parent DisplayTemplate uses, however it keeps the same Action. So it looks like, at least in my instance, the RouteValues was being overridden if not provided.

routes.MapRoute(
name: "Any Name",
url: "Any URL",
defaults: new { Controller = "Your Ajax Controller Name ", action = "Your Ajax action Name" }
);
Or Try This
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Add this to the last of all routes in RouteConfig.cs

Related

ASP.NET MVC ViewBag values not being displayed in view after Ajax call

I have following view and controller code:
Index.cshtml
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<span style="color:green; font-weight:bold;" id="Message">#ViewBag.Message</span>
<input type="text" id="txtMessage" />
<input type="submit" id="btnSubmit" value="Submit" />
}
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$('#btnSubmit').click(function (event) {
$.ajax({
type: "POST",
url: "/Home/Create",
dataType: "json",
contentType: "application/json; charset=utf-8",
async: false,
data: JSON.stringify({
'message': $('#txtMessage').val()
})
});
});
</script>
Controller code:
public class HomeController : Controller
{
public ActionResult Index(string message)
{
return View();
}
[HttpPost]
public ActionResult Create(string message)
{
ViewBag.Message = message;
return View("Index");
}
}
After clicking the button and making ajax call I'm not able to see the message set in the Create method to ViewBag.Message inside the index view.
If you are using Begin form and button type as submit then why write ajax method?
Remove your btnSubmit click from javascript code and use textbox as TextBoxFor,
#Html.TextBoxFor(m => m.message, new { #class = "form-control" })
it should work.
Update Answer for without strongly type
As per code, you are using Begin Form so not required to ajax call.
So first remove javascript code or if you keep that code so no meaning of that.
Now need to update the following line:
<input type="text" id="txtMessage" **name = "txtMessage"** />
And in the controller code post method the following name should be the same.
[HttpPost]
public ActionResult Create(**string txtMessage**)
{
ViewBag.Message = **txtMessage**;
return View("Index");
}

ASP.net MVC 5 partial view Ajax POST not updating just the partial

I have a partial view that is not updating just the partial, it redirects to the action for the entire page.
In the partial view, _registerAccount.cshtml, that contains a post request to register, the request is made via Ajax in a view named _registerAccount as so:
#model LoginDemo.Models.LdapAccountModel
#using (Ajax.BeginForm("RegisterLdapAccount", "Account", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace
}))
{
#Html.ValidationSummary()
#Html.LabelFor(x => Model.Email) #Html.TextBoxFor(x => Model.Email, new { id = "reg-ytu-email" })
<br />
#Html.LabelFor(x => Model.Password) #Html.PasswordFor(x => Model.Password, new { id = "reg-pw" })
<input type="submit" value="Register" class="btn" />
}
In the parent page, Register.cshtml I have:
#model LoginDemo.Models.RegisterModel
...
<div class="panel hide register-type register-ytu">
#Html.Partial("_registerAccount")
</div>
In the Account Controller the ajax request goes to the RegisterAccount action:
[HttpPost]
public async Task<ActionResult> RegisterLdapAccount(LdapAccountModel model)
{
if (model.exists()) // pseudo code
{
return Json(new {foo: "bar"}); // return address to redirect to
}
else
{
ModelState.AddModelError("", "You must have a valid account.");
return PartialView(model); // return error
}
}
The problem I have is that whatever gets returned wipes out the entire page as opposed to updating just the partial within the parent page. That is, if successful the JSON return only returns the JSON, if failed the partial view return only returns the partial.
n.b. I have <add key="UnobtrusiveJavaScriptEnabled" value="true" /> in my web.config.
Amend the following code as follows:
#using (Ajax.BeginForm("RegisterLdapAccount", "Account", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "updatearea",
Amend the div to add the id:
<div id="updatearea" class="panel hide register-type register-ytu">
#Html.Partial("_registerAccount")
</div>
Now make sure you have unobtrustive ajax as a script on the page if you don't already.
<script type="text/javascript" src="#Url.Content("/scripts/jquery.unobtrusive-ajax.min.js")"></script>
To add this script it must be in the scripts folder for your project.
Amend the controller so that you are loading the correct partial view, if you don't state the name of the partial view the partial view loaded will be whatever matches the name of the action, if no partial view matches the name of the action no partial view will be loaded. So explicitly state which partial view you want to load like this:
return PartialView("_RegisterAccount", model)

How to pass data from View in Asp.NET MVC

i want to get the value of textbox for Controller
I used Ajax.ActionLink("Search","Result",new{id="**VALUE**"}, new AjaxOptions{...})
#* This is the Index.cshtml *#
<input id="cityName" type="text" class="form-control" placeholder="Enter a CityName">
#Ajax.ActionLink("Search", "Result", new { id = "I want to get the cityName" }, new AjaxOptions { HttpMethod = "Get", UpdateTargetId = "cityInfo", LoadingElementId = "loading" }, new { #class = "btn btn-default" })
<div id="cityInfo"> #When I click the actionlink , the controller will return a partialview
#Html.Partial("Result", Model)
</div>
#*This is the Result.cshtml*#
<p>
#if (#Model!=null)
{
#Model.cityInfo
}
</p>
this is the index.cshtml ->>
enter image description here
Thanks
public PartialViewResult Result(string cityName)//this is the controller
{
CityModel city = new CityModel(cityName);
city.getInfo();
return PartialView("Index",city);
}
You can write a function like below:
Ajax.ActionLink("Search","Result",new{id="id"}, new AjaxOptions{...}) //set temp value
$(document).ready(function(){
//init value
var value = $('#cityName').val();
var href = $('a').attr('href').replace('id', value);
$('a').attr('href', href);
});

Load/Refresh only part of a page (View) using AJAX in ASP.NET MVC

I am trying to achieve the same result as mentioned by the OP in this post However when I try to render partial view by checking if it was an AJAX request in my Index action, its evaluating to false.
My Index View:
#using (Ajax.BeginForm("Index", "Home",
new AjaxOptions()
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "restaurantList"
}))
{
<input type="search" name="searchTerm" />
<input type="submit" value="Search By Name" />
}
#Html.Partial("_Restaurant",Model)
My Partial View:
<div id="restaurantList" style="border:2px dotted red; padding-left:2em; margin-top:4px;">
#foreach (var item in Model)
{
<div>
<h4>#item.Name</h4>
<div>#item.City, #item.Country</div>
<div>#item.CountOfReviews</div>
<hr />
</div>
}
</div>
My Index Action:
public ActionResult Index(string searchTerm = null)
{
var model = ...//Building model object here
if (Request.IsAjaxRequest())
{
return PartialView("_Restaurant", model);
}
return View(model);
I would prefer not to dive into use of any jQuery or javascript as I am in the process of learning ASP.NET MVC, and would want to know why the approach I took is not working? The second answer by Dennis, in the post that I referenced also suggested similar approach.
Could someone kindly tell me what I am doing wrong?
Thanks
This is just an example how you can load view from AJAX without page refresh, it may help you.
It send text value to controller by ajax call and load that value in other view which replace main view, if you don't want to replace main view then you can take other div instead same div to load content.
Controller:
public ActionResult Index()
{
return View();
}
[HttpPost]
public PartialViewResult TestAjax(string Name)
{
ViewBag.Name = Name;
return PartialView();
}
Index.cshtml:
<input type="button" id="btnSearch" class="btn btn-warning" style="height:35px;width:120px" value="Search"/>
<label>Name:</label><input type="text" id="txtName" name="txtName" />
<script>
$('#btnSearch').click(function () {
$.ajax({
url: '#Url.Action("TestAjax", "Home")',
data: { Name: $("#txtName").val() },
type: 'POST',
success: function (data) {
$("#divContent").html(data);
}
});
});
</script>
TestAjax.cshtml:
#ViewBag.Name
As #StephenMuecke pointed out in his comments, the libraries not being loaded correctly was the problem. While creating a new bundle of all libraries and adding it in the BundkeConfig.cs I had missed ~/Scripts/jquery.unobtrusive-ajax.js*. Got it working now.

Submitting a form view to controller

I have a form in my form view defined as
using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
This form contins a number of input of type button and button
<input type="submit" value="val1" name="action">
<input type="submit" value="val2" name="action">
<input type="submit" value="val3" name="action" />
<button class="button" type="submit" name="action" value="val4">Val4</button>
I have 2 controllers for this view
Public ActionResult form{
}
and
[HttpPost]
public ActionResult form(String button)
{
switch (actionType)
{
case "val1":
return RedirectToAction("AnotherView");
case "val2":
return RedirectToAction("AnotherView2");
default:
return RedirectToAction("AnotherView3");
}
}
But whichever button I click, I am being redirected to the Home defined in the form
using (Html.BeginForm("Index", "Home",
My question is how can I fix this and how can I be certain that this post method is bound to my view as i just typed it in?
using (Html.BeginForm("action_name", "controllername", FormMethod.GET, new { enctype = "multipart/form-data" }))
use input type select:
<select name="action">
<option value="val1" >val1</option>
<option value="val2" >val2</option>
<option value="val3" >val3</option></select>
and method at controller
public ActionResult action_name(String action){
switch (action)
{
case "val1":
return RedirectToAction("AnotherView");
case "val2":
return RedirectToAction("AnotherView2");
default:
return RedirectToAction("AnotherView3");
}
}
If you specify a form field named action MVC will interpret this as the action on the controller to route to. Thus clicking val1 will ultimately execute the method:
public ActionResult val1()
{
}
If this method does not exist, your error handling will take over.
Solution: Don't use action as a name of a form field.

Resources