【问题标题】:Return a Partial View In JSON from a Controller in MVC从 MVC 中的控制器返回 JSON 中的部分视图
【发布时间】:2011-03-16 14:26:55
【问题描述】:

我的情况

我的主页上显示了一个项目列表(调查)。当我单击特定项目的编辑按钮时,我会弹出一个模式,其中包含要编辑的项目详细信息。当用户点击 Save 我通过 ajax 提交表单。根据是否 ModelState.IsValid == true 我想使用验证信息更新模式或关闭模式并使用新信息更新项目列表。

这就是我提交表单的方式:

    $('#editSurveyForm form').live('submit', function () {
        var f = $("#saveSurvey").parents("form");
        var action = f.attr("action");
        var serializedForm = f.serialize();
        $.ajax({
            type: "POST",
            url: action,
            dataType: "html",
            data: serializedForm,
            success: function (result) {
                //TODO - I need an indicator that validation was successful

                //If Validation Failed reload form with validation errors
                $('#editSurveyModal').html(result);

                //If Successful, reload Survey Partial View
                //$('#surveyBox').html(result);
            }
        });
        return false;
    });

我的问题

我唯一能想到的就是从我的控制器返回 JSON,并带有一个标志,指示 ModelState.IsValid 的状态以及我应该显示的相应部分。

1) 我该怎么做?

2) 有没有更好的方法?

更新

我发现了这个: http://www.klopfenstein.net/lorenz.aspx/render-partial-view-to-string-in-asp-net-mvc

但我似乎更可能错误地处理整个事情。

【问题讨论】:

  • 你能不能只使用一个 Ajax 表单 - @Ajax.BeginForm("Action", "Controller")

标签: asp.net asp.net-mvc ajax json


【解决方案1】:

跳过使用 JSON 的一种方法是在返回的 HTML 中查找某些元素。如果您使用任何 html 帮助程序来验证消息 (Html.ValidationSummary(), Html.ValidationMessageFor()),这些将呈现具有特定类的元素,您可以寻找来决定结果。如果没有,您可以制定自己的标准。

例如,如果您使用Html.ValidationSummary-方法,它将呈现一个具有validation-summary-errors 类的列表。所以你可以像这样设置一个变量,然后相应地处理响应。

var isValid = $(response).find(".validation-summary-errors").length == 0;

所以在你的情况下:

success: function (result) {
    var isValid = $(result).find(".validation-summary-errors").length == 0;

    //If Successful, reload Survey Partial View
    if (isValid) {
         $('#surveyBox').html(result);
    }
    //If Validation Failed reload form with validation errors
    else {
        $('#editSurveyModal').html(result);
    }
}

【讨论】:

  • 这可能是我最终要做的。看起来很hackish。我会及时通知你。
【解决方案2】:

你可以返回一个标志来告诉你是否有错误,并且根据这个标志,一组不同的数据。 如果是错误,则返回如下内容:

{success: false, errors: ['Name invalid','email invalid']}

如果它是正确的:

{success: true, Name:'new name',email: 'new email'}

和你的脚本

....
$.ajax({
        type: "POST",
        url: action,
        dataType: "html",
        data: serializedForm,
        success: function (result) {
            if(!result.success)
            {
                  //Show errors     
            }
            else
            {
                  // Update data
            }
        }
    });
.....

要显示错误,您可以在模态弹出窗口中添加一个 div,然后对于 result.errors 上的每个项目,在错误 div 中附加一个 div。

如果成功,请找到您单击的项目,并使用结果中的日期对其进行更新。

如果您不知道该怎么做,请告诉我。

【讨论】:

  • 这正是我想要避免的。我想利用模型上的 TextBoxFor(..) 和属性对我的部分进行 MVC 验证。
【解决方案3】:

按预期去做

jQuery Ajax 请求能够处理successerror 状态。因此,正确的方法是在出现验证错误时从服务器实际返回错误(not HTTP 200 状态)。除非您应该显示它们,否则不要返回视图。但即使在这种情况下,它们也应该是由不同客户端功能(error 处理函数)显示的错误结果的一部分。

my blog post 中阅读有关此内容的所有详细信息。那里也提供了所有代码,并且一步一步地解释了所有内容,因此很容易理解。

它使用一个自定义异常类,当有任何模型状态错误时被抛出,一个自定义错误操作过滤器使用这个异常并向客户端返回一个错误边。这使得以正确的方式执行 Ajax 请求变得非常容易:

$.ajax({
    type: "POST",
    data: /* your data */,
    success: function(data, state, xhr) {
        // do wahetever required
    },
    error: function(xhr, state, err) {
        // do something about the error ie. inform the user about it
    }
});

这比在success 状态中检测错误并在其中包含不必要的分支要好得多。 jQuery 应该以这种方式使用,而不仅仅是 success 处理程序。

附注

很抱歉没有早点看到你的问题,因为我想它提供的信息会让你更开心。

【讨论】:

  • 您不能以这种方式利用 MVC 的验证。这就是我的问题所在。 “如何在不进行完整回发的情况下利用 MVC 验证?”这是为了避免不得不在 javascript 中处理验证通知,这很糟糕。
【解决方案4】:

我的更新局部视图返回索引方法。这个方法填充我的表,比如更新 ajax jquery?

我喜欢只更新PartialView 中的 mu 表。这种情况:

    <div class="container container-Top">
        <h4>Lista de categorias produtos</h4>
        <p>
            <hr />
            <br />
            @using (Html.BeginForm())
            {
                <div class="form-group">
                    <div class="col-lg-4">
                        @Html.TextBox("NomeCategoria", null, new { @class = "form-control" })
                    </div>
                    @Html.ActionLink("Pesquisar", null, null, new { @class = "btn btn-default", @id = "Pesquisar" })
                </div>
            }                       
            <br />
            <br />
            <br />
            <div id="DvDetalheCategoria" class="form-group">
                @Html.Partial("_DetalhesCategoria", Model)
            </div>
    </div>

我的 Jquery

    <script type="text/javascript">

            $(function () {
                $("#Pesquisar").click(function () {
                    var $btnPesquisar = $(this);
                    var idCategoria = $("#NomeCategoria").val();                
                    $.ajax({
                        url: '@Url.Action("_DetalhesCategoria", "VntCategoria")',
                        data: { pName: idCategoria },
                        type: 'POST',
                        success: function (data) {
                            $("#DvDetalheCategoria").html(data);                        
                        },
                        error: function (ex) {
                            alert('Falha ao carregar categorias' + item.Id);
                        }
                    });
                });
            });
        </script>

我的控制器:

     // GET: /VntCategoria/
    public ActionResult Index()
    {
        return View(db.VntCategoriaProdutos.ToList());
    }

    [HttpPost]
    public ActionResult _DetalhesCategoria(string pName)
    {
        ListaCategorias = new List<VntCategoriaProdutos>();
        ListaCategorias = db.VntCategoriaProdutos.ToList().FindAll(f => f.DescricacaoCategoria == pName);
        return View(ListaCategorias);
    }

【讨论】:

  • 这是一个答案吗?在目前的状态下,我不相信它是。
  • 抱歉,这是个问题。我的 jquery 总是执行 index 方法。我希望你只执行 _DetalhesCategoria 方法。
猜你喜欢
  • 2017-01-30
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多