2013-09-05 109 views
2

嗨,我是MVC的新手,请耐心等待。MVC4 ajax窗体不能正常工作

我正在尝试做一个简单的ajax窗体,只接受插入并让用户知道记录已被保存到数据库中。

我的问题是两倍。

  1. 的数据被插入到数据库两次

  2. 的编辑没有得到清除,并且不显示的消息。

我可以得到这个工作使用直HTML表单帖子,但想要使用ajax,然后引入某种加载gif或使用spin.js.

我的代码:

_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

这里是我的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); 
     } 


    } 

我觉得我的数据库问题可能有一些做的其实我结束了在以下我的网页HTML

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

我猜我不应该有两个注册的充分分钟的js脚本,但我不知道,以防止该W的最佳方式休斯特依然采用捆绑

我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); 
     } 
    } 
+1

这看起来很容易[简单地重现问题](http://sscce.org/)。 –

+0

第一个建议是使用'Html.beginform'而不是'Ajax。BeginForm',然后使用jQuery来Ajax化表单,看看那里[这里](http://stackoverflow.com/questions/5410055/using-ajax-beginform-with-asp-net-mvc-3-razor) (它是MVC 3,但它的工作原理是一样的),也是一个很快的问题:我没有在视图中看到带'ajaxreplace' id的元素,它在哪里? –

+0

为什么你会推荐使用jquery的ajax而不是'Ajax.BeginForm'? – WannaCSharp

回答

1

你忘了周围的部分的#ajaxreplace格:

<div id="ajaxrequest"> 
    @using (Ajax.BeginForm(ajaxOpts)) 
    { 
     <div id="ajaxreplace"> 
      @Html.Partial("_MailingData") 
     </div> 
    } 
</div> 

你已经在你的AjaxOptions使用这个ID,所以你应该有一个相应的元素在您的DOM中,将通过AJAX请求的结果进行更新:

AjaxOptions ajaxOpts = new AjaxOptions 
{ 
    InsertionMode = InsertionMode.Replace, 
    UpdateTargetId = "ajaxreplace" 
}; 

只要您关于数据在数据库中插入两次的第一个问题涉及到,您尚未提供有关DAL图层的足够详细信息,以便我们能够进一步诊断问题。也许你的repository.SaveMailRequest方法有问题。

+0

感谢堆,工作!我已经更新了关于双数据库条目的帖子。有任何想法吗??? –

+0

为什么你包含所有的脚本两次?你应该只包括他们一次。如果你包含两次,你可能会得到2个AJAX调用。这是你的脚本内容完全混乱。例如,你有2个不同版本的jQuery,包括无法工作。只保留'.min.js'版本。在你的代码中也没有任何地方可以看到'repository.SaveMailRequest'方法的实现。 –

+0

我已更新帖子以包含** bold ** SaveMailRequest方法。脚本捆绑注册(就不显眼的&验证.js去)来自vs2012基本的MVC4模板。我将从我的脚本文件夹中删除所有非min .js脚本,其中包含最小版本,并尝试使用 –