处理一个Html.BeginForm的2个提交按钮的最佳方法

时间:2013-05-02 08:58:48

标签: asp.net-mvc-4

我在视图中有一个Html.BeginForm,其中包含用户的详细信息:名字,姓氏,电子邮件等。 然后我有2个按钮。批准和拒绝

点击批准后,我转到一个视图。

拒绝时,我会去另一个人。

处理哪一个被点击的最佳方式是什么?

在我的观点中:

<% using (Html.BeginForm("PublishGroupsForRecommendedUser", "Recommend", FormMethod.Post, new { id = ViewBag.UserId }))
  { %>
   <div class="section _100">
    <%: Html.LabelFor(model => model.Email)%> 
    <div>                                      
      <%: Html.EditorFor(model => model.Email)%>  
      <%: Html.ValidationMessageFor(model => model.Email)%>    
    </div>
   </div>            

   //etc

 <input type="hidden" name="action">
 <div class="actions">
  <div class="actions-right">
    <input type="submit" value="Approve" class="submit_button" />
  </div>
  <div class="actions-left"> 
    <input type="submit" value="Reject" class="submit_button" />
  </div>
  </div>
  <% } %>

在我的控制器中:

   [HttpPost]
  public ActionResult PublishGroupsForRecommendedUser(int userId)
  {
    var recommendedUser = ZincService.UserService.GetRecommendedUserForId(userId);
    var visibleGroups = ZincContext.CurrentUserGroups.Get();
    var groupEntities = ZincService.GroupService.GetVisibleGroupsForUser(CurrentUser.UserId).ToList();

    var viewModel = GetGroupPublishingViewModelForSelectedGroups(
    recommendedUser.RecommendedUserId, Zinc.Enums.PublishingMode.ParticipatingGroupUsersOnly,
    recommendedUser.Email, groupEntities);

    return View(viewModel);
  }


  [HttpGet]
  public ActionResult RejectUser(RecommendUserViewModel model)
  {
    Entities.RecommendedUser user = new RecommendedUser();
    user.ReasonForRejection = model.ReasonForRejection;
    ZincService.UserService.UpdateRecommendedUser(user);
    return View(user);
  }

因此我无法再使用(Html.BeginForm("PublishGroupsForRecommendedUser", "Recommend", FormMethod.Post, new { id = ViewBag.UserId }))行,因为根据点击的按钮,我需要转到PublishGroupsForRecommendedUserRejectUser操作,然后调用相应的视图。

有人可以推荐我最好的方式吗?

3 个答案:

答案 0 :(得分:3)

我不完全确定你想要什么,但我认为稍微重组可以帮助你的代码:

ASP.NET-MVC通过使用特定的ViewModel为您的视图轻松处理表单输入。为您要发布的所有内容制作一个属性:

你制作一个简单的POCO对象,如:

public class Person {
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public bool IsApproved { get; set; }
}

与您在ViewBag中相比,ID在模型上的位置要好得多。它是模型的一部分,不要害怕把它放在那里。获得帖子的结果也将被填补。很方便。

让我们说你的第一个动作是:

public ActionResult PersonForm()
{
    var model = new Person()
    {
        ID = WhateverYouWant()
    };

    return this.View(model);
}

您可以将其用作视图中的模型:

<%@ Page Title="Anything" Language="C#" Inherits="System.Web.Mvc.ViewPage<MVC3ASPX.Models.Person>"... %>
...
...
<% using (Html.BeginForm())
   { %>
<%: Html.ValidationSummary(true) %>
<%: Html.HiddenFor(model => model.ID)%>
<div>
    <%: Html.LabelFor(model => model.Name)%>
    <div>
        <%: Html.EditorFor(model => model.Name)%>
        <%: Html.ValidationMessageFor(model => model.Name)%>
    </div>
</div>
<div>
    <%: Html.LabelFor(model => model.Age)%>
    <div>
        <%: Html.EditorFor(model => model.Age)%>
        <%: Html.ValidationMessageFor(model => model.Age)%>
    </div>
</div>
<% } %>

注意我是如何为ID创建一个隐藏的输入字段。它会被发回。

另请注意,我没有指定方法(获取或发布)。邮政是默认的,它足以满足我们的需求。我也没有指定发布它的WHERE。默认情况下,表单将回发到它所在的URL。在我们的例子中,这将是行动PersonForm

发布2种方式不是ASP.NET中的最佳实践。发布到一个操作并在那里if决定该做什么。

所以制作2个按钮。 <button>提交内容比<input>更灵活,因为它们可以有不同的文字和价值。

<div class="actions">
    <div class="actions-right">
        <button type="submit" name="IsApproved" value="True" class="submit_button">Approve</button>
    </div>
    <div class="actions-left">
        <button type="submit" name="IsApproved" value="False" class="submit_button">Reject</button>
    </div>
</div>

请注意,按钮的文字为"Approve""Reject",但发回的值为TrueFalse,具体取决于您点击的位置。

您处理帖子的操作应如下所示:

    [HttpPost]
    public ActionResult PersonForm(Person model)
    {
        if (this.ModelState.IsValid) // Validation never hurts
        {
            if (model.IsApproved)
            {
                return this.PersonFormApproved(model); // Your first method goes here
            }
            else
            {
                return this.PersonFormRejected(model); // Your second goes here
            }
        }

        return this.View(model); // If the model's state is invalid, let's try this one more time!
    }

model变量中,您将从表单的值中填充每个属性。此外,由于存在名为IsApproved的属性,因此它将由同名的表单元素填充。按钮。而且只有压制的。

请注意,我已将大部分内部逻辑提取到方法:PersonFormApprovedPersonFormRejected。这些应该是私密的,以避免程序意外调用错误地认为它们是可赎回的行为。

他们应该返回ActionResult,因为PersonForm操作会返回结果。

同时检查ModelState.IsValid。只有处理有效的信息才能处理。查看DataAnnotations,了解您希望如何验证模型。

答案 1 :(得分:0)

如果使用jquery,可以使用一个解决方案,

为表单指定一个id,并将元素中提交按钮的操作URL设置为数据属性。

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "my-form" }))
{
    //form elements

    <input type="submit" name="action" value="Approve" data-action="@Url.Action("Approve", "YourController")" />
    <input type="submit" name="action" value="Reject" data-action="@Url.Action("Reject", "YourController")"/>
}

然后使用jquery附加提交按钮单击事件,并将操作添加到表单中。

$(function () {
    $('#my-form :submit').click(function (e) {
        var button = $(this);
        button.closest('form').attr('action', button.attr('data-action'));
    });
});

希望这会有所帮助。

答案 2 :(得分:0)

在我看来:

<asp:Content ID="Content2" ContentPlaceHolderID="ScriptPlaceHolder" runat="server">

<script type="text/javascript">
 function RejectUser(userId) {
   $.ajax({
     url: '<%= Url.Action("RejectUser", "Recommend") %>',
     type: 'GET',
     dataType: 'json',
     data: { id: userId, reasonForRejection: $('#textarea').val() },
     success: function (data) {
       window.location.href = data.redirectTo;
     }
    });
 }
</script>

</asp:Content>

<div class="actions">
   <div class="actions-right">
      <input type="submit" value="Approve" class="submit_button" />
   </div>
   <div class="actions-left">      
      <a href="javascript:RejectUser(<%: Model.RecommendedUserId %>);" class="button" id="submit_button">Reject</a>
   </div>
</div>

并在控制器中:

   [HttpGet]
  public JsonResult RejectUser(int id, string reasonForRejection)
  {
    if (!String.IsNullOrWhiteSpace(reasonForRejection))
    {
      Entities.RecommendedUser user = new RecommendedUser();
      user = ZincService.UserService.GetRecommendedUserForId(id);
      user.ReasonForRejection = reasonForRejection;
      ZincService.UserService.UpdateRecommendedUser(user);
      ZincService.SaveChanges();
    }
    return Json(new
    {
      redirectTo = Url.Action("RecommendedUsers"),
    }, JsonRequestBehavior.AllowGet);
  }

谢谢大家!