Jquery 从ASP.NET MVC操作返回部分视图和JSON

Jquery 从ASP.NET MVC操作返回部分视图和JSON,jquery,asp.net-mvc,json,knockout.js,Jquery,Asp.net Mvc,Json,Knockout.js,我正在将KnockoutJS引入现有的应用程序中。我的计划是修改/利用我们已经创建的现有局部视图,并使用Knockout的声明性属性将它们绑定到JS视图模型。当我对一个动作进行AJAX调用时,理想情况下,我希望该动作同时返回部分视图的HTML和JSON对象。然后我可以用HTML填充一个div,将JSON转换为一个Knockout对象并将其绑定到HTML。但我不知道如何从行动中同时返回 我需要完整视图模型,因为我将更新它并最终将其发送回服务器 我考虑让操作返回部分视图(已经绑定到模型),并在部分视

我正在将KnockoutJS引入现有的应用程序中。我的计划是修改/利用我们已经创建的现有局部视图,并使用Knockout的声明性属性将它们绑定到JS视图模型。当我对一个动作进行AJAX调用时,理想情况下,我希望该动作同时返回部分视图的HTML和JSON对象。然后我可以用HTML填充一个div,将JSON转换为一个Knockout对象并将其绑定到HTML。但我不知道如何从行动中同时返回

我需要完整视图模型,因为我将更新它并最终将其发送回服务器

我考虑让操作返回部分视图(已经绑定到模型),并在部分视图中包含javascript以将.Net模型转换为淘汰对象。但是我觉得像那样把JS分散在周围是混乱的,无法维护的。我希望一切都接近最初的ajax调用

我想另一种选择是打两个行动电话。一个用于JSON,另一个用于部分视图。但必须有一个更巧妙的方法


关于如何最好地做到这一点,您有什么想法吗?

您可以在partial上创建一个隐藏的
,并将值设置为ViewModel的JSON字符串。然后在呈现局部视图之前,从该字段中获取JSON值,并对其进行解析。然后将其从部分视图中删除,插入页面,然后执行
ko.applybindingstosubstands(viewModel,$(“#parentElement”)[0])

我不完全确定我对这种方法的看法,这只是一种理论。我还没有测试出来,但我怀疑它会起作用。你必须注意的一点是浏览器试图缓存你的GET请求。在ajax请求中,您希望执行以下操作:

$.ajax({
  url: "/",
  type: 'GET',
  cache: 'false'
});
或者只需执行一个
$.post
请求。 ()


所以这是一种选择。

我相信有多种方法可以做到这一点。我从控制器手动渲染视图,然后将渲染视图作为JSON响应的一部分传递回去

这保留了每个实体的责任。视图仍然使用视图引擎定位,可以重用。除了名称和模型类型之外,控制器对视图知之甚少或一无所知

手动渲染 在您的行动方法中:

object model = null; // whatever you want
var obj = new { 
    someOtherProperty = "hello", 
    view = RenderHelper.PartialView( this, "_PartialName", model ) 
};

return Json( obj );
请注意,我返回的是匿名类型。可以返回所需的任何(可序列化)类型,只要它具有渲染视图的string属性

测试 测试使用手动渲染的操作需要稍加修改。这是由于渲染视图的时间比在MVC管道中渲染视图的时间稍早

手动渲染

  • 输入操作方法

  • 为选项显式呈现视图+1…但我也不确定我对此的感受。+1从未考虑过帮助器类。这可能是最优雅的解决方案。我试试看。谢谢。您不想这样做:
    var obj=new{view=RenderHelper.PartialView(这个,“\u PartialName”,viewModel),model=koViewModel}?还是“foo”就是这个意思?还是我遗漏了什么?@Dennis-是的,“foo”表示您需要返回的任何其他数据。我不确定客户机上到底需要什么,但是视图也需要一个模型(即使它是空的)。
    
    object model = null; // whatever you want
    var obj = new { 
        someOtherProperty = "hello", 
        view = RenderHelper.PartialView( this, "_PartialName", model ) 
    };
    
    return Json( obj );
    
        public static string PartialView( Controller controller, string viewName, object model )
        {
            // returns false from a VS 2013 unit test, true from IIS
            if( !HostingEnvironment.IsHosted )
            {
                // return whatever you want here
                return string.Empty;
            }
    
            // continue as usual
         }