当前位置: 首页 > 面试题库 >

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

夏何平
2023-03-14
问题内容

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

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

我考虑过要让操作返回部分视图(已经绑定到模型),并且在部分视图中包含用于将.Net模型转换为Knockout对象的javascript。但是我觉得像这样散布JS是很麻烦且难以维护的。我宁愿一切都接近原始的ajax电话。

我猜另一种选择是进行两次操作。一个用于JSON,另一个用于部分视图。但是必须有一种巧妙的方法。

关于如何最好地做到这一点的任何想法?


问题答案:

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

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

public static class RenderHelper
{
    public static string PartialView( Controller controller, string viewName, object model )
    {
        controller.ViewData.Model = model;

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

            viewResult.View.Render( viewContext, sw );
            viewResult.ViewEngine.ReleaseView( controller.ControllerContext, viewResult.View );

            return sw.ToString();
        }
    }
}

在您的操作方法中:

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

return Json( obj );

请注意,我返回的是匿名类型。您可以返回所需的任何(可序列化的)类型,只要它具有呈现视图的字符串属性即可。

测试中

测试使用手动渲染的动作需要进行一些修改。这是由于渲染视图比在MVC管道中渲染视图要早一些。

手动渲染

  1. 输入动作方法
  2. 显式渲染视图<-这将使测试调用操作变得困难
  3. 退出动作方法

自动渲染

  1. 输入动作方法
  2. 创建查看结果
  3. 退出动作方法
  4. 处理视图结果(从而渲染视图)

换句话说,我们的手动渲染过程开始了许多其他的操作,这些操作使测试变得困难(例如与构建管理器进行交互以编译视图)。

假设您要测试操作方法而不是视图的实际内容,则可以检查代码是否在托管环境中执行。

    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
     }

检查HostingEnvironment.IsHosted是廉价的(在幕后,这只是一个空检查)。



 类似资料:
  • 问题内容: 有没有一种方法可以将部分呈现为MVC的JSON响应的一部分返回HTML字符串? 问题答案: PartialViewResult和ViewResult都从ViewResultBase派生,因此相同的方法应该对两者都起作用。 使用上面线程中的代码,您将可以使用:

  • 问题内容: 我有一个函数,可使用Pandas分析CSV文件并生成带有摘要信息的字典。我想从Flask视图返回结果作为响应。如何返回JSON响应? 问题答案: 将摘要数据传递给该函数,该函数返回JSON响应。 从Flask 0.11开始,你可以将任何JSON可序列化的类型(不仅是dict)传递为顶级对象。

  • 问题内容: 我正在尝试创建控制器操作,该操作将根据参数返回JSON或部分html。使结果异步返回到MVC页面的最佳方法是什么? 问题答案: 在您的操作方法中,返回Json(object)以将JSON返回到您的页面。 然后只需使用Ajax调用action方法即可。您可以使用ViewPage中的一种辅助方法,例如 SomeMethod将是一个javascript方法,然后评估返回的Json对象。 如果

  • 我有一个函数,可以使用Pandas分析CSV文件并生成包含摘要信息的编辑器。我想从Flask视图返回结果作为响应。如何返回JSON响应?

  • 声明我应该能够使用中选择s.message来查询实体,这确实适用于控制台。 然而,我真正想做的是在返回列表中只返回实体的特定属性,就像这样: 不过,这会出错,根本没有真正的错误消息。我可以看到Hibernate运行了这个查询: 的传统方法工作正常:

  • 问题内容: 我有一个函数,可使用Pandas分析CSV文件并生成带有摘要信息的字典。我想从Flask视图返回结果作为响应。如何返回JSON响应? 问题答案: 将摘要数据传递给该函数,该函数返回JSON响应。 从Flask 0.11开始,你可以将任何可序列化的类型(不仅是dict)传递为顶级对象。