返回一个包含HTML和JavaScript的部分视图
返回一个包含HTML和JavaScript的部分视图
我正在使用jQuery进行AJAX调用,以检索一个PartialView
。除了HTML之外,我还想返回一个JSON表示的View所显示的对象。我一直在使用一种糟糕的方法,将属性嵌入HTML中作为隐藏的输入,这样很快就变得难以控制,并且将太多的东西紧密地耦合在一起。
我可以将JavaScript放在HTML之后的标签中发送,但我非常注重将它们分开。这将如下所示:
<%@ Control Language="C#" AutoEventWireup="true" Inherits="System.Web.Mvc.ViewUserControl
姓: <%= Html.TextBox("FirstName", Model.FirstName) %>
名: <%= Html.TextBox("LastName", Model.LastName) %>
// JsonSerialized 对象在这里
我考虑的另一个选择是对返回JsonResult
的动作进行第二个AJAX调用,但这也感觉像是糟糕的设计。
问题原因:在返回一个PartialView时,希望能够包含HTML和JavaScript代码。
解决方法:创建一个继承自ViewPage的新类,并覆盖其Render方法来渲染页面本身,并将其插入到Andrew建议的输出中。这样所有的操作都发生在Render方法中。
具体步骤如下:
1. 创建一个继承自ViewPage的新类。
2. 在新类中覆盖Render方法,并在该方法中渲染页面本身。
3. 在新类中插入Andrew建议的输出。
在每个视图中,将原来的代码行:
<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
更改为:
<%@ Page Title="" Language="C#" Inherits="CustomViewPage" %>
以上是我的猜测,如果需要,我可以尝试构建并验证该解决方案。
问题的出现原因:
问题的出现是因为需要在返回的PartialView中同时包含HTML和JavaScript,但是目前的方法无法满足这一需求。返回Pure JSON只能返回数据,无法返回HTML和JavaScript;使用jQuery构建HTML则会比较麻烦。
解决方法:
一种解决方法是在Action方法中返回纯JSON数据,并将HTML和JavaScript的代码作为JSON对象的属性值进行传递。然后在Controller中通过特定的方法将JSON数据转换为HTML并返回。
具体实现方法如下:
1. 在Action方法中返回如下形式的JSON数据:
{ Html: "etc...", Json: { // your object here } }
2. 在Controller中通过以下代码将JSON数据转换为HTML:
var existingContext = HttpContext.Current; var writer = new StringWriter(); var response = new HttpResponse(writer); var httpContext = new HttpContext(existingContext.Request, response); var viewResult = myAction(bla); HttpContext.Current = httpContext; viewResult.ExecuteResult(this.ControllerContext) HttpContext.Current = existingContext; var viewAsHtml = writer.ToString();
3. 最后将转换后的HTML返回。
这种方法可能不是最优雅的解决方案,但可以满足同时返回HTML和JavaScript的需求。虽然在Controller中转换JSON数据为HTML的过程中使用了一些技巧,但是该方法仍然是一种可行的解决方案。
问题的出现原因:在返回一个PartialView时,需要同时返回HTML和JavaScript代码。但是,直接在HTML代码中嵌入JavaScript代码可能会导致代码混乱,可读性差。
解决方法:通过使用HtmlHelper扩展,将JSON数据封装在其中,再返回给前端页面。具体的解决方法如下:
首先,创建一个名为JsonExtensions的静态类,代码如下:
using System.Web.Script.Serialization; public static class JsonExtensions { public static string Json(this HtmlHelper html, string variableName) { return Json(html, variableName, html.ViewData.Model); } public static string Json(this HtmlHelper html, string variableName, object model) { TagBuilder tag = new TagBuilder("script"); tag.Attributes.Add("type", "text/javascript"); JavaScriptSerializer jsonSerializer = new JavaScriptSerializer(); tag.InnerHtml = "var " + variableName + " = " + jsonSerializer.Serialize(model) + ";"; return tag.ToString(); } }
然后,可以通过以下方式调用该扩展方法:
<%= Html.Json("foo") %> <%= Html.Json("bar", Model.Something) %>
这样,就可以将JSON数据封装在一个script标签中,并返回给前端页面。封装后的JSON数据可以被JavaScript代码访问和使用,同时保持了前端页面的可读性和干净的标记。
需要注意的是,这种方法并不是完全的分离;在HTML代码中仍然存在JavaScript代码。然而,这种方法避免了对服务器的额外调用,并且在IDE中的标记仍然非常清晰。