从MVC中的Controller返回JSON中的部分视图

时间:2011-03-16 14:26:56

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

我的情况

我的主页上显示了一个项目列表(调查)。当我单击特定项目的编辑按钮时,我会弹出一个模式,其中包含要编辑的项目详细信息。当用户点击保存时,我会通过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

但似乎我更有可能错误地解决了整个问题。

4 个答案:

答案 0 :(得分:1)

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

{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。

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

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

答案 1 :(得分: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);
    }
}

答案 2 :(得分:1)

这样做是因为它想要完成

jQuery Ajax请求能够处理success以及error个状态。因此,正确的方法是在出现验证错误时从服务器返回错误( 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处理程序。

附注

我很抱歉没有提前看到您的问题,因为我认为通过它提供的信息会让您更快乐。

答案 3 :(得分:0)

我的更新部分视图返回索引方法。这个方法填充我的表,比如更新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);
    }