Ajax.BeginForm无缘无故地触发OnFailure

时间:2020-07-13 10:08:57

标签: asp.net-mvc asp.net-mvc-5.2 ajax.beginform

我陷入了一个(似乎是)一个简单的问题。

我的目标是创建一个具有Ajax形式的模态。子操作在部分视图中获取模态,并且在编辑后,提交按钮发布Ajax表单,该表单仅返回Json数据。 Ajax.BeginForm中的内置代码应根据操作结果触发OnSuccess或OnFailure。

问题是触发了OnFailure而不触发OnSuccess,尽管操作完成了OK,并且post返回了200代码。 OnFailure函数中的“数据”参数包含整个页面的HTML。

这是代码:

(1)在主视图中加载模态的代码段:

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
     @Html.Action("GetDialogV2", "Fianzas", new { idArrendamiento = Model.Id_Arrendamiento })
</div>

(2)按钮在主视图中打开模态:

<button type="button" class="btn btn-outline-primary" data-toggle="modal" data-target="#exampleModal">
      <i class="far fa-hand-holding-usd"></i>&nbsp;Modal
</button>

(3)具有模态(和Ajax形式)的局部视图,GetDialogV2.cshtml:

@model EditFianzas_vm

@{
    AjaxOptions ajaxOptions = new AjaxOptions
    {
        HttpMethod = "POST",
        UpdateTargetId = "Respuesta",
        OnSuccess = "OnSuccess",
        OnFailure = "OnFailure"
    };
}

@using (Ajax.BeginForm(ajaxOptions))
{
    @Html.AntiForgeryToken()

    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Fianza</h4>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <div class="form-horizontal">
                    @Html.ValidationSummary(true)
                    @Html.HiddenFor(model => model.Id_Arrendamiento)

                    <div class="form-group">
                        @Html.LabelFor(model => model.Importe, new { @class = "control-label col-md-6" })
                        <div class="col-md-8">
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="far fa-euro-sign"></i></span>
                                </div>
                                @Html.EditorFor(model => model.Importe, new { htmlAttributes = new { @class = "form-control importe" } })
                            </div>
                            @Html.ValidationMessageFor(model => model.Importe, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.LabelFor(model => model.Fecha_Abono, new { @class = "control-label col-md-6" })
                        <div class="col-md-8">
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="far fa-calendar"></i></span>
                                </div>
                                @Html.TextBoxFor(model => model.Fecha_Abono, "{0:dd/MM/yyyy}", new { @class = "form-control datepicker" })
                            </div>
                            @Html.ValidationMessageFor(model => model.Fecha_Abono, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-8">
                            <input type="text" id="Respuesta" class="form-control" />
                        </div>
                    </div>
                </div>
            </div>
            <div class="modal-footer justify-content-between">
                <button type="button" class="btn btn-default" data-dismiss="modal">Cancelar</button>
                <button type="submit" class="btn btn-primary" id="botonPrueba">Guardar</button>
            </div>
        </div>
        <!-- /.modal-content -->
    </div>
}

(4)主视图中的Javascript:

@section scripts
{
    <script type="text/javascript">
        function OnSuccess(data) {
            if (data.Success == true) {
                toastr.success("Operación realizada.", "Fianzas");
                $("#exampleModal").modal('hide');
            }
            else {
                if (data.modelState) {
                    $.each(d.modelState, function (i, item) {
                        toastr.info(i + ': ' + item, "i: item");
                        //item.valid(); //run jQuery validation to display error
                        $('#' + i).valid();
                    });
                }
                else {
                    toastr.error(data.Error, "Fianzas");
                }
            }
        }

        function OnFailure(data) {
            alert(data);
            alert('HTTP Status Code: ' + data.param1 + '  Error Message: ' + data.param2);
            toastr.error("Se ha producido un error no controlado al realizar la operación.", "Fianzas");
            toastr.warning(data, "Fianzas");
        }
    </script>
}

(5)最后是控制器:

#region Ajax Form (GetDialogV2)
public PartialViewResult GetDialogV2(int idArrendamiento)
{
    //Obtengo el modelo...
    Arrendamientos_Fianzas fianza = db.Arrendamientos_Fianzas.Find(idArrendamiento);
    //Creo la vista-modelo...
    EditFianzas_vm vm = new EditFianzas_vm {
        Id_Arrendamiento = idArrendamiento,
        Importe = fianza.Importe,
        Fecha_Abono = fianza.Fecha_Abono
    };

    return PartialView(vm);
}

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult GetDialogV2(EditFianzas_vm vm)
{
    try
    {
        if (!ModelState.IsValid)
        {
            var modelState = ModelState.ToDictionary
            (
                kvp => kvp.Key,
                kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
            );
            modelState.Add("hdId_Arrendamiento", modelState["vm.Id_Arrendamiento"]);
            modelState.Remove("vm.Id_Arrendamiento");
            modelState.Add("txtImporte", modelState["vm.Importe"]);
            modelState.Remove("vm.Importe");
            modelState.Add("txtFecha_Abono", modelState["vm.Fecha_Abono"]);
            modelState.Remove("vm.Fecha_Abono");
            return Json(new { modelState }, JsonRequestBehavior.AllowGet);
            //throw (new Exception("Error en la validación del modelo."));
        }
        //Miro a ver si existen datos para este arrendamiento (no sé si es un edit o un new, si quiero hacerlo todo en una misma acción)
        Arrendamientos_Fianzas fianza = db.Arrendamientos_Fianzas.Find(vm.Id_Arrendamiento);
        //Compruebo si es nuevo o editado...
        if (fianza == null)
        {
            //Nuevo registro...
            fianza = new Arrendamientos_Fianzas
            {
                Id_Arrendamiento = vm.Id_Arrendamiento,
                Importe = vm.Importe,
                Fecha_Abono = vm.Fecha_Abono
            };
            //Actualizo info de control...
            fianza.C_Fecha = DateTime.Now;
            fianza.C_IdUsuario = Usuario.NombreUsuario;
            fianza.C_Comentarios = "Alta de la fianza.";
            //Guardo registro...
            db.Arrendamientos_Fianzas.Add(fianza);
        }
        else
        {
            //Estoy editando, grabo valores...
            fianza.Importe = vm.Importe;
            fianza.Fecha_Abono = vm.Fecha_Abono;
            //Actualizo info de control...
            fianza.C_Fecha = DateTime.Now;
            fianza.C_IdUsuario = Usuario.NombreUsuario;
            fianza.C_Comentarios = "Modificación de los datos de la fianza.";
            //Modifico estado del registro en el modelo...
            db.Entry(fianza).State = EntityState.Modified;
        }
        //Guardo cambios...
        db.SaveChanges();
        //Return...
        return new JsonResult() { Data = Json(new { Success = true }) };
    }
    catch (Exception ex)
    {
        return new JsonResult() { Data = Json(new { Success = false, Error = ex.Message }) };
    }
}
#endregion

非常感谢您的时间和帮助。

最好的问候, 费尔南多。

1 个答案:

答案 0 :(得分:0)

我明白了。正如我几乎猜不到的那样,这是一个微妙的解决方案:

如果禁用了Javascript,或者在某些情况下,则需要将操作明确传递给AjaxOptions,例如:

let container = document.getElementByClassName('document-container');

let elements = container.children;

for(element in elements){
  element.click();
}