Ajax .BeginForm запускает OnFailure без причины - PullRequest
0 голосов
/ 13 июля 2020

Я застрял с (кажется) простой проблемой.

Моя цель - создать модальное окно с формой Ajax. Дочернее действие получает модальное окно в частичном представлении, а при редактировании отправляет кнопку отправки Ajax форму, которая возвращает только Json данных. Встроенный код в Ajax .BeginForm должен запускать OnSuccess или OnFailure в зависимости от результата действия.

Проблема в том, что OnFailure запускается, а OnSuccess - нет, хотя действие завершается нормально и после возврата код 200. Параметр «data» в функции 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.cs html:

@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 голосов
/ 14 июля 2020

Я понял. Это было тонкое решение, как я едва догадался:

Если Javascript отключен, или в определенных обстоятельствах вам нужно явно передать действие в AjaxOptions, например:

    AjaxOptions ajaxOptions = new AjaxOptions()
    {
        HttpMethod = "POST",
        OnSuccess = "OnSuccess(data)",
        OnFailure = "OnFailure",
        OnBegin = "OnBegin",
        OnComplete = "OnComplete",
        Url = Url.Action("GetDialogV2")
    };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...