简体   繁体   中英

MVC4 ajax form not working

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.

  1. The data is being inserted into the DB twice

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM