C#.NET MVC Ajax Form Submission - c#

Feel like I'm missing something simple here - When I submit this form it takes me to a white page with my encoded JSON model, rather than staying on the page I was on.
Form in a partial view, loaded on every page:
#using (Ajax.BeginForm("Inquiry", "Home", new AjaxOptions { HttpMethod = "POST", OnSuccess = "success" }))
And my actions:
public ActionResult Inquiry()
{
return PartialView("_Inquiry",new Inquiry());
}
[HttpPost]
public JsonResult Inquiry(Inquiry model)
{
if (ModelState.IsValid)
{
db.Inquiries.Add(model);
db.SaveChanges();
}
return Json(model);
}

Make sure you have referenced the following script in your page:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
It is what makes the Ajax.* helpers work.

Related

How to get the error message during a jquery post while using aps.net mvc?

I'm using 2019 ASP.NET MVC with jquery 3.4.1. I'm trying to get the error message when I make a jquery ajax post. To simulate an error I mispelled the method in the controller being called by ajax. The best I could do was to display an alert box with some HTML code. It looks like the title tag contains the correct error message: "The resource cannot be found." But it's nested inside of a bunch of html code.
Is there a way to get that error message out of that html code and into a string?
Edit: I figured it out. I just added a span tag and set the html property of it.
Controller
using System.Web.Mvc;
namespace Test
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
//view
return View();
}
[HttpPost]
public ActionResult DoSomething1111111111()
{
return Json("hello");
}
}
}
View
#{
Layout = null;
}
<input type="button" id="test-button" value="test" />
<span id="message"></span>
<script src="~/Scripts/jquery-3.4.1.js"></script>
<script>
//test-button click event
$(document).on("click", "#test-button", function () {
//post
$.ajax({
url: "/Home/DoSomething",
type: "POST",
success: function (res) {
alert("success");
},
error: function (res) {
$("#message").html(res.responseText);
}
});
});
</script>

Passing view from one controller to another controller's view

Is it possible to pass another controller's view to the first controller's view? I have controller1 with view1. I need to call another controller2 action method from view1 and pass the view2 to a div in view 1.
I tried #html.Action("action","controller"). This called controller 2, but was not passing the view2 to view1.
Am I doing it wrong? How can I do that?
This example is something you can use. I did not put it into an ASP.NET Fiddle because we are dealing with TWO view.
Controller/ViewModel of First
namespace Testy20161006.Controllers
{
//I'm showing how to pass data from one Controller Action to another Controller Action.
//With the data you can render your second view however you like with the data.
//We pass data NOT views. You could use a partial view, but I am showing the most basic way.
public class NewbieDevViewModel
{
public String DataToPassToNewControllerAction { get; set; }
}
public class HomeController : Controller
{
//I am using Tut145 for my first Controller/Action/View, but you could have called it Index
[HttpPost]
public ActionResult Tut145(NewbieDevViewModel passedData)
{
//passing simple string, so I can pass it using my QueryString
return RedirectToAction("MyAction2", "Home2", new { passedData = passedData.DataToPassToNewControllerAction });
}
public ActionResult Tut145()
{
return View();
}
View of First
#model Testy20161006.Controllers.NewbieDevViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tut145 - View 1</title>
</head>
<body>
#using (Html.BeginForm())
{
#Html.LabelFor(r=>r.DataToPassToNewControllerAction)
#Html.TextBoxFor(r => r.DataToPassToNewControllerAction, new { #Value = "ValueOfData" })
<input type="submit" value="Submit data - to send to new Controller Action" />
}
</body>
</html>
Controller of Second
namespace Testy20161006.Controllers
{
public class Home2Controller : Controller
{
//I named my Controller Home2 and Action MyAction2, but you can name it anything you want
public ActionResult MyAction2(string passedData)
{
//reconstruct the ViewModel and pass into second view
NewbieDevViewModel viewModel = new NewbieDevViewModel { DataToPassToNewControllerAction = passedData };
return View(viewModel);
}
View of Second
#model Testy20161006.Controllers.NewbieDevViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>MyAction2 </title>
</head>
<body>
<div>
- Final View - I passed data into here from different Controller Action -and-
I can render this page anyway I which
</div>
<p/>
#Html.LabelFor(r => r.DataToPassToNewControllerAction)
#Html.TextBoxFor(r => r.DataToPassToNewControllerAction)
</body>
</html>
Partial view can be used to render a view inside another view. Create a partial view for an action in controller 2. Call that partial view from the view of controller 1.
Here is the example :
First Controller :
public class Controller1Controller : Controller
{
public ActionResult Edit()
{
return View();
}
}
First Controller View :
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Controller 1 View</h4>
<hr />
<h1>Fisrt Controller</h1>
<div>
#{
Html.RenderAction("GetSubject", "Controller2");
}
</div>
</div>
}
Second Controller :
public class Controller2Controller : Controller
{
public ActionResult GetSubject()
{
Subject s = new Subject() { id = 2, SubjectName = "XYZ" };
return PartialView(s);
}
}
Second Controller View :
<div>
<h4>Controller 2 view</h4>
<hr />
<h1>Second Controller</h1>
</div>
After spending some time on the code and a bit of googling, I figured out my issue.
The child action method I was calling from parent view was an async method, so I did something like the below,
Parent view
<div id="childView"></div>
Ajax Call to populate the parent view
$(document).ready(function () {
$.ajax({
type: 'GET',
url : '#Url.Action(actionName: "ChildAction", controllerName: "ChildController")',
dataType: "html",
async:true,
success: function (result) { $("#childView").html(result); }
});
});
Hope it will be useful for some one.

Null model when posting data with Ajax.BeginForm

I've created a partial view that allows a user to enter their email and get added to a subscriber list. Originally I had this working as standard post and everything worked fine.
However now I'm trying to make this an ajax call and for some reason, even though the form is posting to the correct controller, the model is always coming through as null and I can't figure out why.
Here are my views:
Parent view:
#Html.Partial("Shared/Newsletter/NewsletterForm", new NewsletterSubscriber())
Form partial:
#using (Ajax.BeginForm("NewsletterSignUp", "Newsletter", new AjaxOptions { HttpMethod = "POST" }))
{
<input type="text" name="EmailAddress" id="newsletter-email" class="basic-input" placeholder="Email Address">
<button id="submit-newsletter" class="basic-submit">Sign Up</button>
<p id="status"></p>
}
Controller:
[HttpPost]
public ActionResult NewsletterSignUp(NewsletterSubscriber model)
{
if (!ModelState.IsValid)
{
return Content("Please enter a valid e-mail address");
}
// Do logic...
}
The model:
public class NewsletterSubscriber
{
[Required]
[EmailAddress]
[StringLength(300)]
public string EmailAddress { get; set; }
}
Scripts:
<script src="/scripts/jquery.validate.min.js"></script>
<script src="/scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="/scripts/jquery.unobtrusive-ajax.min.js"></script>
<script>
$(function() {
$('#submit-newsletter').on('click', function(e) {
e.preventDefault();
$.post('/umbraco/surface/Newsletter/NewsletterSignUp', function (data) {
console.log(data);
$('#status').show().text(data);
});
});
});
</script>
Like I said, when I step through the code the post is hitting the correct controller, however the model is always coming through as null.
Where am I going wrong?
I just realised I had the ajax form handling the submission for me and I was trying to manually post the form in another script. Once I removed the additional script it worked.
(It's the end of a long day and I missed this obvious mistake!)

Action is unreachable after submitting a form

I have the following problem (I spend many hours looking for a solution).
The ‘Create’ button has a click event which calls the ‘Test’ action on the ‘Home’ controller.
All works fine.
When I hit the ‘Save’ button, to submit the form, that works fine to.
But after I have submitted the form, my ‘Create’ button stops working. The ‘Create’ button does have the click event, but the ‘Test’ action is unreachable?
index.cshtml
<script type="text/javascript">
$(document).ready(function () {
$("#create").click(function () {
$.ajax({
type: "POST",
traditional: true,
url: 'Home/Test',
dataType: "html",
success: function (data) {
alert('Succes!')
},
error: function () {
alert('A problem ocurred!!');
}
});
});
});
</script>
<input id="create" type="button" value="Create" />
#using (Html.BeginForm("SaveForm", "Home"))
{
<input type="submit" value="Save" />
}
HomeController.cs
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult Test()
{
return Content("Test result");
}
public ActionResult SaveForm()
{
return View("Index");
}
public ActionResult About()
{
return View();
}
}
All of your actions are GET only. Either add [HttpPost] (POST only) or [AcceptVerbs(HttpVerbs.Post, HttpVerbs.Get)] (GET or POST) attributes to your POST actions.
[HttpPost]
public ActionResult Test()
{
return Content("Test result");
}
[HttpPost]
public ActionResult SaveForm()
{
return View("Index");
}
Theres 2 problems:
1) you dont have [HttpPost] above your methods
2) You are not sending any data to your controller
add an id to your form by using an anonymous class:
#using (Html.BeginForm("SaveForm", "Home", new {id = "testform"}))
then rewrite the ajax request:
<script type="text/javascript">
$(document).ready(function () {
$("#create").click(function () {
$.ajax({
type: "POST",
data: $("#testform").serialize();
url: 'Home/Test',
dataType: "html",
success: function (data) {
alert('Succes!')
},
error: function () {
alert('A problem ocurred!!');
}
});
});
});
</script>
Let me know if it works :)
To create an entity, you have to submit your data to server, either by post back or ajax as in your case. Now there are some contradictions in your code :)
1. Why are you calling one action as form action and another through
ajax? Because since your button will post back, your ajax call won't
fire the success and error handlers. To solve this either use <button> or
$("#create").click(function (e) { e.preventDefault();//Some code});
2. If you want to use ajax, write it like this. Also write [HttpPost] on
your action. This indicates that this action can be called by post requests.
This is a required step, whether or not you are using ajax.
I hope this solved your problem.
Eventually I used Ajax.BeginForm instead of Html.BeginForm, added the [HttpPost] attributes to my actions and I used the RedirectToAction("Index") instead of PartialView. That solved my problem. Thanks again for your tips!

Rendering Partial Views using ajax

I've checked this question and it solved my initial problems. But I don't want the partial view to be rendered only when the user clicks a link, I want to render partial views when the page is loaded and, possibly, show a progress indicator while the partial view is being loaded.
How to achieve that?
Thank you very much for reading this.
If you want to load the page and then load the partial view via ajax you could create an ActionMethod that does something like:
public ActionResult Create()
{
var model = new MyModel();
if (Request.IsAjaxRequest())
{
return PartialView( "_Partial", model.PartialModel );
}
else
{
return View( model );
}
}
and then in your page do something like:
$(function(){
$(document).ajaxStart(function () {
//show a progress modal of your choosing
showProgressModal('loading');
});
$(document).ajaxStop(function () {
//hide it
hideProgressModal();
});
$.ajax({
url: '/controller/create',
dataType: 'html',
success: function(data) {
$('#myPartialContainer').html(data);
}
});
});
Controller
public ActionResult GetModule(string partialName){
return PartialView("~/Views/Shared/"+partialName);
}
on the Default Page (using jquery ajax operation)
<div id='mod1'>Loading...</div>
<script type="text/javascript">
$("#mod1").load("/ControllerName/GetModule?partialName=test1");
</script>
You can render it in the initial page by writing #Html.Partial(...).

Categories