【问题标题】:Multiple submit buttons on a form from partial views, only the first of list submits the data来自部分视图的表单上的多个提交按钮,只有列表中的第一个提交数据
【发布时间】:2021-01-10 23:54:10
【问题描述】:

我有一个设备列表,我需要为每个设备执行两种不同的操作(因此我添加并创建了 2 个局部视图,每个视图都有其提交按钮)。我使用一个 for 循环来创建我的视图,在这个循环之外我需要在选择操作结束时提交。结论我有两个提交按钮在 for 循环中创建 X 次,第三个按钮让我验证我的表单。

我创建了一个多按钮属性,该属性非常有效地指导我采取良好的行动。但只有列表的第一个元素是提交数据。一旦我提交了第二个元素,action 方法上收到的视图模型会保留第一个元素的一些信息。

我不知道如何使我的提交按钮在循环中有所不同??,我知道我拥有多个按钮的方法运行良好。

我的主要观点EquipementVsZone

@model SiteReservationGestionPFL.Areas.Reservation.Data.EquipementsParZoneViewModel


@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@using (Html.BeginForm())
{
    for (int i = 0; i < Model.Equipements.Count(); i++)
    {
        <div class="form-row">
            <div class="col-sm-8 col-md-8">
                <div class="checkbox">

                    @Html.CheckBoxFor(m => m.Equipements[i].EstSelectionne)
                    <strong>@Html.LabelFor(m => m.Equipements[i].EstSelectionne, Model.Equipements[i].equipement.nom + "( Num GMAO: " + Model.Equipements[i].equipement.numGmao + " )")</strong>
                </div>
                <div class="row">
                    <div class="col-sm-6 col-md-6">
                        Emplacement pour la photo
                    </div>
                    <div class="col-sm-6 col-md-6">
                        Emplacement pour les liens résa!
                    </div>
                </div>
            </div>
            <br />
            <div class="col-sm-4 col-md-4">
                <a class="btn-link" href="#" onclick="showCalendar(@Model.Equipements[i].equipement.id.ToString())">Voir disponibilité @Model.Equipements[i].equipement.id.ToString()</a>
            </div>
            <br />
            <div class="row">
                <div class="col-sm-12 col-md-12">
                    <div id="@Model.Equipements[i].equipement.id.ToString()" class="hide" style="display:none">
                        <div class="form-group row">
                            <hr />
                            <div class="row">
                                <div class="col-sm-10 col-md-10 offset-1">
                                    @Html.Partial("~/Areas/Reservation/Views/Shared/_CalendrierEquipement.cshtml", Model.CalendrierChildVM[i])
                                </div>
                            </div>
                        </div>
                        <hr />
                        <div id="cren-content">
                            @Html.Partial("~/Areas/Reservation/Views/Shared/_Creneau.cshtml", Model.CalendrierChildVM[i])
                        </div>
                        <hr />
                        <div class="form-group row">
                            <div class="col-sm-12 col-md-12">
                                <h6>Récapitulatif équipement: @Model.Equipements[i].equipement.nom</h6>
                                <table class="table table-hover">
                                    <thead>
                                        <tr>
                                            <th scope="col">Date Début</th>
                                            <th scope="col">Date Fin</th>
                                            <th scope="col">Heure Début</th>
                                            <th scope="col">Heure Fin</th>
                                            <th scope="col">Action</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        @for (int j = 0; j < Model.CalendrierChildVM[i].ResaEquipement.Count(); j++)
                                        {
                                            <tr>
                                                <td>@Model.CalendrierChildVM[i].ResaEquipement[j].date_debut.ToShortDateString()</td>
                                                <td>@Model.CalendrierChildVM[i].ResaEquipement[j].date_fin.ToShortDateString()</td>
                                                <td>@Model.CalendrierChildVM[i].ResaEquipement[j].date_debut.ToShortTimeString()</td>
                                                <td>@Model.CalendrierChildVM[i].ResaEquipement[j].date_fin.ToShortTimeString()</td>
                                                <td>Supprimer</td>
                                            </tr>
                                        }
                                    </tbody>
                                </table>
                            </div>
                        </div>
                        <hr />
                    </div>
                </div>
            </div>
        </div>
    }
    <br />
    <div class="form-group row">
        <div class="col-md-2">
            <!--'javascript:history.go(-1)' pour revenir à la page précedente :) pas mal! voir pour le rajouter sur
                le formulaire projet et vérifier si le récapitulatif se met à jour-->
            <a href='javascript:history.go(-1)' class="btn btn-primary" role="button">
                Annuler
            </a>
        </div>
        <div class="offset-9 col-md-1">
            <input type="hidden" name="Index" value="@Model.NomZone" />
            <input type="submit" class="btn btn-default navbar-inra" value="Valider" name="action" />
        </div>
    </div>
}



<link href="~/Content/themes/base/jquery-ui.min.css" rel="stylesheet" />

@section Scripts
{
    <!-- JS includes -->
    <script src="~/Scripts/jquery-ui-1.12.1.min.js"></script>


    <script type="text/javascript">

        $('.datepick').datepicker({
            dateFormat: "dd/mm/yy",
            changeMonth: true,
            changeYear: true,
            yearRange: "2019:2040"
        });

        function showCalendar(parameter) {
            var divid = document.getElementById(parameter);
            if (divid.style.display == "") {
                divid.style.display = "none";
            } else {
                divid.style.display = "";
            }
        }
    </script>
}


局部视图_Creneau.cshtml

@model SiteReservationGestionPFL.Areas.Reservation.Data.CalendrierEquipChildViewModel


<h5>Réservation @Model.equiID</h5>
<div class="form-row">
    <div class="col-sm-8 col-md-8">
        <div class="row">
            <div class="col-sm-4 col-md-4">
                <!--Date picker -->
                <div class="input-group date">
                    @Html.Label("Date Début:  ")
                    @Html.EditorFor(m => m.DateDebut, new { htmlAttributes = new { @class = "datepick form-control col-7", @id = "ResaDebutDP_" + Model.equiID, @placeholder = "MM/DD/YYYY" } })
                    @Html.ValidationMessageFor(m => m.DateDebut, "", new { @class = "text-danger" })
                    <!--<input type="text" class="form-control" id="datepickerdebut" placeholder="MM/DD/YYYY">-->
                </div>
            </div>
            <div class="col-sm-3 col-md-3">
                @Html.RadioButtonFor(m => m.DatePickerDebut_Matin, "true")
                @Html.Label("Matin", new { @class = "col-md-4 control-label" })
                @Html.ValidationMessageFor(m => m.DatePickerDebut_Matin, "", new { @class = "text-danger" })
            </div>
            <div class="col-sm-3 col-md-3">
                @Html.RadioButtonFor(m => m.DatePickerDebut_Matin, "false")
                @Html.Label("Après-midi", new { @class = "col-md-8 control-label" })
                @Html.ValidationMessageFor(m => m.DatePickerDebut_Matin, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="row">
            <div class="col-sm-4 col-md-4">
                <div class="input-group date">
                    @Html.Label("Date Fin:  ")
                    @Html.EditorFor(m => m.DateFin, new { htmlAttributes = new { @class = "datepick form-control col-7", @id = "ResaFinDP_" + Model.equiID, @placeholder = "MM/DD/YYYY" } })
                    @Html.ValidationMessageFor(m => m.DateFin, "", new { @class = "text-danger" })
                    <!-- CHANGER LE m => m.NomZone et rajouter la vrai variable du viewModel<input type="text" class="form-control" id="datepickerdebut" placeholder="MM/DD/YYYY">-->
                </div>
            </div>
            <div class="col-sm-3 col-md-3">
                @Html.RadioButtonFor(m => m.DatePickerFin_Matin, "true")
                @Html.Label("Matin", new { @class = "col-md-4 control-label" })
                @Html.ValidationMessageFor(m => m.DatePickerFin_Matin, "", new { @class = "text-danger" })
            </div>
            <div class="col-sm-3 col-md-3">
                @Html.RadioButtonFor(m => m.DatePickerFin_Matin, "false")
                @Html.Label("Après-midi", new { @class = "col-md-8 control-label" })
                @Html.ValidationMessageFor(m => m.DatePickerFin_Matin, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>
    <!-- pour passer l'id equipement et l'id zone à la méthode AddReservation() -->
    @Html.HiddenFor(model => model.equiID)
    <div class="col-sm-4 col-md-4">
        <input type="submit" class="btn btn-outline-success" value="Ajouter Réservation" name="action" />
    </div>
</div>


部分视图_CalendrierEquipement

@model SiteReservationGestionPFL.Areas.Reservation.Data.CalendrierEquipChildViewModel

<div class="form-group">
    <h6> Sélectionnez les dates pour voir les créneaux disponibles pour l'équipement @Model.equiID</h6>
    <div class="form-group row">
        <br />
        @*@using(Html.BeginForm("GetPlanning", "Reservation", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
        {
            @Html.AntiForgeryToken()*@
            <div class="form-group row justify-content-center">
                <div class="col-sm-4 col-md-4 col-lg-4">
                <!--Date picker -->
                    <div class="input-group date">
                        @Html.Label("Du : ")
                        @Html.EditorFor(m => m.DatePickerDu, new { htmlAttributes = new { @class = "datepick form-control col-10", @id = "datPickDu_" + Model.equiID.ToString(), @placeholder = "MM/DD/YYYY" } })
                        @Html.ValidationMessageFor(m => m.DatePickerDu, "", new { @class = "text-danger" })
                        <!--<input type="text" class="form-control" id="datepickerdebut" placeholder="MM/DD/YYYY">-->
                    </div>
                </div>
                <div class="col-sm-4 col-md-4 col-lg-4">
                    <!--Date picker -->
                    <div class="input-group date">
                        @Html.Label("Au : ")
                        @Html.EditorFor(m => m.DatePickerAu, new { htmlAttributes = new { @class = "datepick form-control col-10", @id = "datPickAu_" + Model.equiID.ToString(), @placeholder = "MM/DD/YYYY" } })
                        @Html.ValidationMessageFor(m => m.DatePickerAu, "", new { @class = "text-danger" })
                        <!-- pour passer l'id zone de cette vue au controleur Reservation methode GetPlanning() -->
                        @Html.HiddenFor(model => model.zoneID) 
                        <!--<input type="text" class="form-control" id="datepickerdebut" placeholder="MM/DD/YYYY">-->
                    </div>
                </div>
                <div class="col-sm-4 col-md-4 col-lg-4">
                    <input type="submit" class="btn btn-outline-success" value="Afficher Planning" name="action" />
                </div>

            </div>
            
        @*}*@
        </div>
    <br />
    <div class="row">
        <table class="table table-bordered">
            <h5 class="text-center">Titre Calendrier Semaine ou (du x au x) </h5>
            <thead class="thead-dark">
                <tr>
                    <th scope="col">Créneaux</th> <!--Colonne pour ajouter les créneau matin et aprèm, pas besoin de head-->
                    @foreach (var x in Model.ListResasSemaine)
                    {
                        <th scope="col">@x.NomJour @x.JourResa.ToShortDateString()</th>
                    }
                </tr>
            </thead>
            <tbody>
                <tr>
                    <th scope="row">
                        <dl class="dl-horizontal text-center">
                            <br />
                            <dd>M</dd>
                            <dd>A</dd>
                            <dd>T</dd>
                            <dd>I</dd>
                            <dd>N</dd>
                        </dl>
                    </th>
                    @foreach (var y in Model.ListResasSemaine)
                    {
                        <td>
                            @foreach (var i in y.InfosResaMatin)
                            {
                                @i.essai.projet.titre_projet
                            }
                        </td>
                    }
                </tr>
                <tr>
                    <th scope="row">
                        <dl class="dl-horizontal text-center">
                            <br />
                            <dd>A</dd>
                            <dd>P</dd>
                            <dd>R</dd>
                            <dd>E</dd>
                            <dd>M</dd>
                        </dl>
                    </th>
                    @foreach (var y in Model.ListResasSemaine)
                    {
                        <td>
                            @foreach (var i in y.InfosResaAprem)
                            {
                                @i.essai.projet.titre_projet
                            }
                        </td>
                    }
                </tr>
            </tbody>
        </table>
    </div>
</div>


控制器方法:

        [HttpPost]
        [AllowMultipleButton(Name = "action", Argument = "Afficher Planning")]
        public ActionResult AfficherPlanning(CalendrierEquipChildViewModel model)
        {
            ViewBag.Message = "AfficherPlanning";

            return View();
        }

        [HttpPost]
        [AllowMultipleButton(Name = "action", Argument = "Ajouter Réservation")]
        public ActionResult AjouterResa(CalendrierEquipChildViewModel model)
        {
            // Récupérer la session "EquipementZone"
            EquipementsParZoneViewModel equipementZone = (EquipementsParZoneViewModel)this.HttpContext.Session["EquipementZone"];

            
            return View("EquipementVsZone", equipementZone);
        }

        [HttpPost]
        [AllowMultipleButton(Name = "action", Argument = "Valider")]
        public ActionResult Valider(EquipementsParZoneViewModel model)
        {
            // Récupérer la session "EquipementZone"
            EquipementsParZoneViewModel equipementZone = (EquipementsParZoneViewModel)this.HttpContext.Session["EquipementZone"];
            ViewBag.Message = "Valider les réservations";

            return View();
        }

我的多个按钮属性AllowMultipleButtonAttribute

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;

namespace SiteReservationGestionPFL.Areas.Reservation
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class AllowMultipleButtonAttribute: ActionNameSelectorAttribute
    {
        public string Name { get; set; }
        public string Argument { get; set; }

        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
        {
            var isValidName = false;
            isValidName = controllerContext.HttpContext.Request[Name] != null &&
                controllerContext.HttpContext.Request[Name] == Argument;

            return isValidName;
        }
    }
}

如果您有想法,请帮帮我吗?非常感谢您的任何帮助

【问题讨论】:

    标签: c# model-view-controller razor asp.net-mvc-5


    【解决方案1】:

    也许你需要修改你的 Attribute def 和 Razor 代码

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class MultipleButtonAttribute : ActionNameSelectorAttribute
    {
        public string Name { get; set; }
        public string Argument { get; set; }
    
        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
        {
            var isValidName = false;
            var keyValue = string.Format("{0}:{1}", Name, Argument);
            var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);
    
            if (value != null)
            {
                controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
                isValidName = true;
            }
    
            return isValidName;
        }
    }
    

    然后在您的提交按钮设置中

    <form action="" method="post">
     <input type="submit" value="Save" name="action:Save" />
     <input type="submit" value="Cancel" name="action:Cancel" />
    </form>
    

    和控制器

    [HttpPost]
    [MultipleButton(Name = "action", Argument = "Save")]
    public ActionResult Save(MessageModel mm) { ... }
    
    [HttpPost]
    [MultipleButton(Name = "action", Argument = "Cancel")]
    public ActionResult Cancel(MessageModel mm) { ... }
    

    希望对你有帮助

    【讨论】:

    • 在那种情况下,我的局部视图不会是真正的局部视图?当您说表单操作时,您的意思是@Html.BeginForm?我需要一个 POST 操作来提交我的部分视图。你能给我一个例子吗?提前致谢
    猜你喜欢
    • 2018-08-25
    • 2011-06-23
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    相关资源
    最近更新 更多