【问题标题】:MVC Html.BeginForm and page reloadMVC Html.BeginForm 和页面重新加载
【发布时间】:2018-09-19 14:32:11
【问题描述】:

我曾经在 C#/Winforms 中开发一些应用程序,现在我正在尝试学习使用 MVC 进行 Web 开发。

很多新概念(JS、Ajax、ASP.net等...),请多多包涵...

看了很多,开始努力尝试,但有一点我还是不明白。

例如,我想通过Form在数据库中插入数据,只需要插入即可。

插入的方法在控制器中。

明显的方法是使用Html helper @Html.BeginForm。在这一步,如果不重新加载整个页面,我将无法做到这一点。

由于我没有找到任何明确的答案,请您帮帮我。

1-@Html.BeginForm 是否可以在发布表单后什么都不做以便插入数据库(可能在控制器中具有特定的操作返回类型)或Ajax.BeginForm 是唯一的解决方案?

2-同样更新页面的一部分,ajax是唯一的解决方案吗?

非常感谢。

【问题讨论】:

    标签: ajax model-view-controller actionresult ajax.beginform html.beginform


    【解决方案1】:

    您可以使用 Razor 或 ajax 将部分视图加载到视图中。当页面的同一部分可以有不同的视图时,我会使用这种技术 - 例如,像一个选项卡式控件

    您以 MVC 的通常样式创建一个 URL。在此示例中,我假设对某些现有数据执行 HTTP GET。对于您的 CREATE GET 选项,只需控制器和操作就足够了。请注意,从操作返回的 HTML 会替换页面上其他位置的 DIV 的内容

    var targetUrl = "/MyController/MyAction/" + id + "?extraParameter=" + 123;
    
    //-----------------------------------------
    // get content from URL using Ajax
    //-----------------------------------------
    $.ajax({
             url: targetUrl,
             type: "get",
             success: function (result) {
             $("#divPageContent").html(result);
             }
    });
    

    您可以从控制器加载您的 CREATE 视图,如上所示。你需要一个保存按钮,点击后会调用 Ajax 将你的值发送回服务器。

    您应该在视图中使用带有 AntiForgeryToken 的 FORM 并使用 Ajax POST。我不建议使用 HTTP GET 来添加或更改数据。

    有很多资源可以向您展示如何做到这一点。

    假设您的 CREATE 过程有效,您可以返回任何您喜欢显示结果的视图,返回到用于创建的同一 DIV。

    许多开发人员都使用这种技术,甚至使用动态加载所有内容的单页网站。

    对于我的网站,我发现大多数流程都可以在不使用 Ajax 的情况下正常工作。现代浏览器可以很好地处理内容变化和闪烁。我在更复杂的页面中使用 Ajax 来获取部分视图。如果您要使用 Ajax 路线,请考虑使用繁忙指示器 - 当 Ajax 工作时,它会弹出您选择的图标,以便您的用户知道页面正在执行某些工作。

    $(function () {
        $(document).ajaxStart(function () {
            $(".processSpinner").show();
        });
    
        $(document).ajaxStop(function () {
            $(".processSpinner").hide();
        });
    
        $(document).ajaxError(function () {
            $(".processSpinner").hide();
        });
    
        $(".processSpinner").hide();
    });
    

    include antiforgerytoken in ajax post ASP.NET MVC

    【讨论】:

      【解决方案2】:

      我在 asp.net 核心中创建了一个表单,其中包含使用 ajax 的发布数据 它正在工作 创建局部视图

      @model Department
      
      <h2>Create</h2>
      <script src="~/lib/jquery/dist/jquery.js"></script>
      <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
      <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
      <div class="form-horizontal">
          <form asp-action="Create" role="form" asp-controller="Department" asp-antiforgery="true"
                data-ajax-success="Bindgrid"
                data-ajax="true"
                data-ajax-method="POST">
              <div class="form-group">
                  <label class="control-label" asp-for="DepartmentName"></label>
                  <input class="form-control" type="text" asp-for="DepartmentName" />
                  <span asp-validation-for="DepartmentName" class="text-danger"></span>
              </div>
              <input class="btn btn-primary" type="submit" value="Save" />
          </form>
      </div>
      

      控制器逻辑

      [ValidateAntiForgeryToken()]
              [HttpPost]
              public JsonResult Create(Department department)
              {
                  if (ModelState.IsValid)
                  {
                      Context.Department.Add(department);
                      Context.SaveChanges();
                  }
                  return Json(department);
              }
      

      【讨论】:

      • 感谢您的帮助和时间,我会跟随这条赛道
      【解决方案3】:

      有很多概念可以让您了解。让我们从两个基本选择开始。使用简单的回发或 JavaScript 和 Ajax 更新日期?

      好的,让我们开始第一个,一个简单的创建过程。

      您需要更新数据库表。您可以从数据库创建实体框架模型。您的应用程序将与此交互更新表。这是 MVC 中的“M”或模型。您还需要创建一个控制器(MVC 中的“C”)和一个视图(MVC 中的“V”)。

      控制器通常包含两种执行工作的方法。当用户导航到网页时,他们会获取初始数据。所有这一切都是返回带有空模型的视图,因此任何编辑控件都处于默认状态 - 例如空文本框

      [HttpGet]
      public ActionResult Create()
      {
          return View();
      }
      

      当用户保存视图时,会调用另一个方法(同名)。请注意,这是 POST 方法,因此 FORM 中的所有数据都被打包到 ModelState 中。 MVC 将为您将模型绑定到方法的参数中——您甚至可以说出要包含哪些参数。这里的版本使用 Async。

      您视图中的 FORM 也应该有一个防伪令牌,这是 MVC 系统返回和使用的第一个(隐藏)字段 - 您通常看不到它。

      假设数据是有效的,它被保存到数据库中(我通常有一个底层的业务模型来做这个工作来保持控制器的干净)。如果模型无效(例如缺少字段),则现有模型将与任何错误消息一起传递回视图以供用户再次使用。查看 Data-Annotations 以了解如何定义有效值范围。

      [HttpPost]
      [ValidateAntiForgeryToken]
      public async Task<ActionResult> Create([Bind(Include = "YourName")] MyData model)
              {
                  if (ModelState.IsValid)
                  {
                      await _bs.MyData_UpdateAsync(model);
                          return RedirectToAction("Index");
                  }
      
                  // return with any errors
                  return View(model);
              }
      

      最后,您需要一个动态生成 HTML 并将其传递给客户端浏览器的视图

      @model MyApp.Models.MyData
      @{
          ViewBag.Title = "Create Something";
          Layout = "~/Views/Shared/_Layout.cshtml";
      }
      
      <div class="container w-50">
          @using (Html.BeginForm())
          {
              @Html.AntiForgeryToken()
      
              <div class="form-horizontal">
                  @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                  <div class="form-group">
                      @Html.LabelFor(model => model.YourName, htmlAttributes: new { @class = "control-label" })
                      @Html.EditorFor(model => model.YourName, new { htmlAttributes = new { @class = "form-control" } })
                      @Html.ValidationMessageFor(model => model.YourName, "", new { @class = "text-danger" })
                  </div>
      
                  <div class="d-flex">
                      <div class="ml-auto">
                          <input type="submit" value="Create" class="btn btn-primary btn-sm btn-default" />
                      </div>
                  </div>
              </div>
          }
      </div>
      

      【讨论】:

      • 好的,感谢您抽出宝贵时间,但这一点我明白了。在您的示例中,用户被重定向到此控制器(索引)的主页。只是为了澄清我的问题,现在想象我想要(我不知道为什么,但我想要)留在Create 视图上并保持绑定的YourName 显示在文本框中。而不是return RedirectToAction("Index"),我会放什么?
      • 只需删除重定向行,它就会返回视图。您可以添加类似 ViewBag.Message = "Created";相反,在视图中,检查 Viewbag 元素是否不为空,然后显示该文本。您也可以改为重定向到 EDIT 方法。我倾向于做的是重定向并在视图数据中设置一条消息(不是视图包,它不能跨重定向工作)。例如,ViewData["Message"] = "Created";
      • 是的,我想所有页面都会重新加载,这是我想避免的......
      猜你喜欢
      • 2016-03-18
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      • 2014-07-14
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      相关资源
      最近更新 更多