将视图模型实例发布回几个动作方法

时间:2015-04-24 18:10:56

标签: c# asp.net-mvc asp.net-mvc-4 razor

我有一个ViewModel,它有8个属性,其中6个是复杂类型。我必须在3组中显示它们,并最终将所有数据保存到数据库中。现在,我已经为此创建了两种方法,第一种方法将使用HttpGet进行修饰,第二种方法将使用HttpPost进行修饰。我已经在一个.cshtml中创建了所有这三个组。这是第一次只有第一组可见。点击 NEXT 按钮后,我会显示第二组,并且在 Javascript / Jquery 即可。然后第三组将是可见的。在最后一部分中,必须出现提交按钮。点击这个后,我会将整个模型发布回动作方法。但是,在这种情况下,我有两个问题:

  • 我必须仅验证客户端验证的可见字段
  • 如果以某种方式客户端验证通过而服务器端不通过,那么我必须找到并显示未验证的部分。

因此,为了解决这些问题,我决定创建两个动作方法,将viewmodel发布回另一个。 为了说清楚,我想这样表达:

  1. CreateViewModel [HttpGet]
  2. GoToSecondPart [HttpPost]
  3. GoToThirdPart [HttpPost]
  4. SaveToDatabase [HttpPost]
  5. 1会将我的viewmodel实例返回到2,而2依次将它发布到3,而3会将其发布到4。

    这是好的方法吗?如果没有,你会推荐我什么?

2 个答案:

答案 0 :(得分:1)

您当前的方法意味着多个帖子/重定向和某种形式的临时存储库或模仿视图状态的东西。更好的方法是在一个表单中执行每个操作,并使用Validator.element(element)

验证每个部分中的各个控件

在“下一步”按钮.click()事件

  1. 选择关联的<section>中的所有控件 - 例如var controls = $(this).closest('section').find('input, textarea, select');
  2. $.each循环中,请致电$('form').validate().element($(this));
  3. 测试该部分中的控件是否对$(this).valid();
  4. 有效
  5. 如果一切有效,请隐藏当前部分并显示下一个
  6. 最后一部分包含“保存”按钮,可以正常提交

    查看

    <section>
        <h2>Section 1</h2>
        @Html.LabelFor(m => m.SomeProperty)
        @Html.TextBoxFor(m => m.SomeProperty)
        @Html.ValidationMessageFor(m => m.SomeProperty)
        ....
        <div class="error"></div>
        <button type="button" class="next">Next</button>
    </section>
    <section>
        <h2>Section 2</h2>
        // Your inputs and validation
        <div class="error"></div>
        <button type="button" class="next">Next</button>
    <section>
    <section>
        <h2>Section 3</h2>
        // Your inputs and validation
        <div class="error"></div>
        <button type="submit" class="next">Submit</button> // submit button for last section
    </section>
    

    css(隐藏第一部分除外)

    section:not(:first-of-type) {
        display:none;
    }
    

    脚本

    $('button').click(function () {
      var container = $(this).closest('section');
      var isValid = true;     
      $.each(container.find('input'), function () { // include select, textarea as required
        $('form').validate().element($(this));
        if (!$(this).valid()) {
          isValid = false;
          return false;
        }
      });
      if (isValid) {
        container.next('.section').show().find('input').first().focus();
        container.hide();
      } else {
        container.find('.error').text('please complete');
      }
    });
    

    这将解决所有客户端验证,而无需多个帖子/重定向。至于在罕见的必须返回视图的情况下会发生什么,因为模型仍然无效(将生成错误消息,但可能在隐藏的部分中,因此最初不可见)

    1. 让用户单步执行&#39;向导&#39;再次(可能会令人困惑 如果在第一部分中看不到错误)
    2. 例如,使用jquery查找生成的错误 $('span.field-validation-error)并取消隐藏相关联的内容 父母部分

答案 1 :(得分:-1)

听起来你正试图做一个巫师。使用相同的视图模型将页面分成部分更容易,但只显示该页面所需的字段(将其他字段抛出到隐藏字段中以保存数据)。然后,您可以将AJAX调用回到控制器以呈现下一个/上一个页面,这将阻止屏幕闪烁,使其看起来像页面未更改。