Hi I'm new to MVC so please bear with me.
I'm trying to do a simple ajax form that just accepts inserts and lets the user know the record has been saved off into a DB.
My problem is two fold.
The data is being inserted into the DB twice
The editors don't get cleared and the message isn't displayed.
I can get this working using straight HTML form posts but wanted to use ajax and then introduce some sort of loading gif or use spin.js.
my code:
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Styles.Render("~/Content/kendo")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/kendo")
@Scripts.Render("~/bundles/jqueryval")
</head>
<body>
<div id="wrapper" style="width:100%; text-align:center">
<img src="~/Content/Header.PNG" alt="MyHeader" />
</div>
@RenderBody()
@RenderSection("scripts", required: false)
</body>
</html>
AboutController
public class AboutController : Controller
{
private readonly IMailRepository repository;
public AboutController(IMailRepository repo)
{
repository = repo;
}
public ActionResult AboutUs()
{
return View();
}
public ActionResult CreateMailing()
{
return View(new MailRequest());
}
[HttpPost]
public PartialViewResult CreateMailing(MailRequest model)
{
if (model == null)
{
return PartialView("_MailingData",new MailRequest());
}
if (ModelState.IsValid)
{
repository.SaveMailRequest(model);
ModelState.Clear();
TempData["message"] = string.Format("{0} has been added to the mailing list.", model.Email);
return PartialView("_MailingData",new MailRequest());
}
else
{
return PartialView("_MailingData",model);
}
}
}
_MailingDate.cshtml
@model MyProj.Models.MailRequest
@Html.EditorForModel()
<br/>
<input type="submit" value="Save"/>
<input type="button" value="Cancel"
onclick="location.href='@Url.Action("AboutUs", "About")' " />
@if (TempData["message"] != null)
{
<div>@TempData["message"]</div>
}
CreateMailing.cshtml
@model MyProj.Models.MailRequest
@{
ViewBag.Title = "Mailing List";
AjaxOptions ajaxOpts = new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "ajaxreplace"
};
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Mailing List Request</title>
</head>
<body>
<div id="ajaxrequest">
@using (Ajax.BeginForm(ajaxOpts))
{
@Html.Partial("_MailingData")
}
</div>
</body>
</html>
----UPDATE
Here is my BundleConfig.cs
public static class BundleConfig
{
// For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
public static void RegisterBundles(BundleCollection bundles)
{
if (bundles == null) return;
// The jQuery bundle
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
//bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
// "~/Scripts/jquery-{version}.js",
// "~/Scripts/jquery-migrate-1.1.1.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
"~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
// The Kendo JavaScript bundle
bundles.Add(new ScriptBundle("~/bundles/kendo").Include(
"~/Scripts/kendo.all.min.js",
// or kendo.all.min.js if you want to use Kendo UI Web and Kendo UI DataViz
"~/Scripts/kendo.aspnetmvc.min.js"));
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
"~/Content/themes/base/jquery.ui.core.css",
"~/Content/themes/base/jquery.ui.resizable.css",
"~/Content/themes/base/jquery.ui.selectable.css",
"~/Content/themes/base/jquery.ui.accordion.css",
"~/Content/themes/base/jquery.ui.autocomplete.css",
"~/Content/themes/base/jquery.ui.button.css",
"~/Content/themes/base/jquery.ui.dialog.css",
"~/Content/themes/base/jquery.ui.slider.css",
"~/Content/themes/base/jquery.ui.tabs.css",
"~/Content/themes/base/jquery.ui.datepicker.css",
"~/Content/themes/base/jquery.ui.progressbar.css",
"~/Content/themes/base/jquery.ui.theme.css"));
// The Kendo CSS bundle
bundles.Add(new StyleBundle("~/Content/kendo").Include(
"~/Content/kendo.common.*",
"~/Content/kendo.uniform.*"));
// Clear all items from the ignore list to allow minified CSS and JavaScript files in debug mode
bundles.IgnoreList.Clear();
// Add back the default ignore list rules sans the ones which affect minified files and debug mode
bundles.IgnoreList.Ignore("*.intellisense.js");
bundles.IgnoreList.Ignore("*-vsdoc.js");
bundles.IgnoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled);
}
}
I think my DB issue may have something to do with the fact I end up with the following in the html of my page
<script src="/bundles/modernizr"></script>
<script src="/Scripts/jquery-2.0.0.js"></script>
<script src="/Scripts/jquery-2.0.3.js"></script>
<script src="/Scripts/kendo.all.min.js"></script>
<script src="/Scripts/kendo.aspnetmvc.min.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>
I'm guessing I shouldn't have both the full and min js scripts registered but am not sure the best way to prevent this whilst still using bundles
My EFMailRepository
public class EFMailRepository : IMailRepository, IDisposable
{
private EFDbContext context = new EFDbContext();
public void SaveMailRequest(MailRequest mailRequest)
{
context.MailingList.Add(mailRequest);
context.SaveChanges();
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// dispose managed resources
context.Dispose();
}
// free native resources
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
You forgot to put an #ajaxreplace
div around the partial:
<div id="ajaxrequest">
@using (Ajax.BeginForm(ajaxOpts))
{
<div id="ajaxreplace">
@Html.Partial("_MailingData")
</div>
}
</div>
You have used this id in your AjaxOptions so you should have a corresponding element in your DOM that will get updated by the result of the AJAX request:
AjaxOptions ajaxOpts = new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "ajaxreplace"
};
As far as your first question about the data being inserted twice into the database is concerned, you haven't provided enough details about your DAL layer so that we could be able to further diagnose the issue. Maybe there's something wrong with your repository.SaveMailRequest
method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.