Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery 部分视图与Json(或两者兼而有之)_Jquery_Asp.net Mvc_Json - Fatal编程技术网

Jquery 部分视图与Json(或两者兼而有之)

Jquery 部分视图与Json(或两者兼而有之),jquery,asp.net-mvc,json,Jquery,Asp.net Mvc,Json,我将ASP.NETMVC与jQuery结合使用,并且对我的控制器有很多Ajax请求 加载页面时,使用局部视图(usercontrols)构建初始视图。然后,如果需要根据Ajax请求追加/替换数据,我将根据Json响应构建HTML 这种方法给了我完全的控制权,也就是说,如果出现问题,我可以从我的控制器那里获得额外的信息,然后在此基础上显示错误消息 然而,最近我对在我的部分视图和从Json生成HTML的部分中维护HTML结构的所有额外工作感到非常恼火 我喜欢发出jqueryajax请求,然后让控制器

我将ASP.NETMVC与jQuery结合使用,并且对我的控制器有很多Ajax请求

加载页面时,使用局部视图(usercontrols)构建初始视图。然后,如果需要根据Ajax请求追加/替换数据,我将根据Json响应构建HTML

这种方法给了我完全的控制权,也就是说,如果出现问题,我可以从我的控制器那里获得额外的信息,然后在此基础上显示错误消息

然而,最近我对在我的部分视图和从Json生成HTML的部分中维护HTML结构的所有额外工作感到非常恼火

我喜欢发出jqueryajax请求,然后让控制器返回PartialView(“mypartialview”),然后在视图中使用jQuery替换为HTML

然而,这样我就不能从控制器附加额外的数据——要么是局部视图给我的数据——要么什么都没有。至少这是我目前的看法

如果在我的控制器操作的某个点上验证出错,我不想返回部分视图的HTML

那么你如何着手处理这个问题呢


感谢阅读。

我相信您可以将呈现的html作为字符串返回-也可以是包含要显示的错误消息的html字符串?

基于stackoverflow anwser,我刚刚开始做同样的事情

首先为控制器类创建一个扩展方法

public static string RenderViewToString(this Controller controller, string viewName, object model)
{
    using (var writer = new StringWriter())
    {
         var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
         controller.ViewData.Model = model;
         var viewCxt = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, writer);
         viewCxt.View.Render(viewCxt, writer);
         return writer.ToString();
     }
}
然后在controllers操作方法中返回json

return Json(new {
  Html = this.RenderViewToString("MyView", model),
    SomeExtraData = data
});
您的ajax请求现在将接收包含html的json。仍在对返回的纯Html片段进行这种方法的实验

希望有帮助


编辑已更新以使用razor

以下是一种利用每个结果返回的
内容类型
的方法。我们用它来发回错误信息,而且已经有了JS来显示消息,所以我们要么得到我们想要的部分视图,要么得到错误报告的控制信息等等

作为参考,局部视图返回
text/html
,JSON响应应返回
application/JSON

和往常一样,有趣的部分在javascript方面,JQuery
ajax()
在这里不会让人失望

在控制器中,只需根据需要返回
PartialView()
Json(model,)
;我们使用的是
try/catch
格式

public ActionResult Edit(int id) {
    try {
        var model = getYourModel();
        return PartialView("Edit", model);
    }
    catch (Exception ex) {
        var mi = new MessageInfo(MessageType.Error, String.Format("Edit failed: {0}", ex.Message), true);
        return Json(mi, "application/json", JsonRequestBehavior.AllowGet);
    }
}
在JS方面,我们使用以下函数。请注意,您需要从初始页面级别GET重新建立挂接在
$(document).ready()
中的任何JQuery事件,因此我们有一个回调参数

function getPartialView(action, controller, model, divId, callback) {
    var url = "/" + controller + "/" + action + "/";
    $.ajax({
        type: "GET",
        url: url,
        data: model,
        success: function (data, textStatus, jqXHR) {
            var ct = jqXHR.getResponseHeader("Content-Type");
            var mx = ct.match("text\/html");
            if (mx != null) {
                $(divId).html(data);
                if (callback) {
                    callback($(divId));
                }
            }
            else {
                addMessage(data.type, data.title, data.text, data.sticky);
            }
        },
        error: function (jqXHR, textStatus, errorThrown) {
            addMessage(3, "\"" + url + "\": Failed", textStatus + ": " + errorThrown, false);
        }
    });
}
唯一棘手的一点是检查响应中的
内容类型
标题,并相应地进行操作。请注意,如果JSON不是HTML,那么我们假设它是“欺骗”的。我们正在调用我们预先存在的
addMessage()
函数,执行您需要的任何操作

最后,这里是一个示例锚元素,上面有
onclick
targeting
getPartialView()

<a href="#" onclick="getPartialView('Action', 'Controller', model, '#partialviewdivid', function(dvx) { connectJqueryEvents(dvx); })">Cancel</a>
在OOTB版本中,缺少第二条
if
语句;添加它是防止它将JSON负载猛击到DOM中所必需的修复

有了这个补丁,JSON负载将传递到您的
AjaxOptions.OnSuccess
Javascript中,您可以根据需要继续

是的,您可以同时获得这两个


希望您知道,既然您发送的是Json,那么您可以发回任何类型的模型,并让Javascript对其进行排序
hasOwnProperty()
在那里很方便。显然,您可以通过前面提到的
RenderViewToString()

发回一些视图HTML。您也可以这样做,将其放在控制器中

protected string RenderPartialViewToString(string viewName, object model)
{
    if (string.IsNullOrEmpty(viewName))
        viewName = ControllerContext.RouteData.GetRequiredString("action");

    ViewData.Model = model;

    using (StringWriter sw = new StringWriter()) {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}

事实上,这正是部分观点的反应。尽管您没有详细说明,但这是解决方案:让AJAX方法使用最初用于呈现页面该部分的相同用户控件返回呈现的PartialView。您可以通过编写returnpartialview(model)而不是returnjson(model)来实现这一点。谢谢。这确实是一个更好的解释:)克雷格,这就是我现在所做的。我的问题是,我想返回Html和Json——或者换个说法:我想要从return PartialView返回的结果Html,然后用Json包装,这样我也可以发送其他数据。有点像这个家伙:我想上面的方法会奏效,但我想知道其他人是如何处理的。你可以(轻松地)返回与部分视图(HTML片段)或JSON相同的模型。构建模型,然后调用您需要的任何方法。但是不要编写JavaScript,它会从同一模型的JSON序列化复制部分视图。
protected string RenderPartialViewToString(string viewName, object model)
{
    if (string.IsNullOrEmpty(viewName))
        viewName = ControllerContext.RouteData.GetRequiredString("action");

    ViewData.Model = model;

    using (StringWriter sw = new StringWriter()) {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}