我正在进行AJAX调用(使用jQuery)来检索PartialView
。与HTML一起,我想发送一个View正在显示的对象的JSON表示。我一直在使用的糟糕方式是将属性作为隐藏输入嵌入到HTML中,这很快变得笨拙并且紧密地耦合了很多东西。
我可以在HTML之后的<script>
标记中发送JavaScript,但我真的很擅长将这些内容分开。这看起来像这样:
<%@ Control Language="C#" AutoEventWireup="true" Inherits="System.Web.Mvc.ViewUserControl<Person>" %>
<div class="person">
First Name: <%= Html.TextBox("FirstName", Model.FirstName) %>
Last Name: <%= Html.TextBox("LastName", Model.LastName) %>
</div>
<script type="text/javascript">
// JsonSerialized object goes here
</script>
我考虑的另一个选择是对返回JsonResult
的动作进行第二次AJAX调用,但这也感觉设计不好。
答案 0 :(得分:2)
我认为我找到了一个非常好的方法,只需将JSON
包裹在HtmlHelper
扩展名中。这是班级:
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) %>
我能想到的一个问题是它不是完全完美的分离;你仍然在技术上将JavaScript放在HTML中。 但是,它不会对服务器进行额外调用,IDE中的标记仍然非常干净。
答案 1 :(得分:1)
可能不是你会得到的最优雅的答案,只是把它扔到那里:
你可以从你的动作方法返回纯粹的json,
看起来像这样的东西:
{
Html: "<div class=\"person\"> etc...",
Json: { // your object here
}
}
在你的控制器中,你需要这样的东西来渲染你的观点:
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();
答案 2 :(得分:1)
和安德鲁一样的解决方案,但也许更多MVC'ish ......
创建一个继承自ViewPage的新类。重写其Render方法以呈现页面本身,然后将其填充到Andrew建议的输出中。因此,所有的黑客攻击都发生在Render方法中,它应该发生在哪里。
现在您创建的每个视图都会更改该行:
<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<MyModel>" %>
与
<%@ Page Title="" Language="C#" Inherits="CustomViewPage<MyModel>" %>
我自己没有检查,但猜猜它应该有效。如果你愿意,我可以尝试构建它。
答案 3 :(得分:0)
public static string RenderPartialToString(string controlName, object viewData, object model, System.Web.Routing.RequestContext viewContext)
{
ViewDataDictionary vd = new ViewDataDictionary(viewData);
ViewPage vp = new ViewPage { ViewData = vd };
vp.ViewData = vd;
vp.ViewData.Model = model;
vp.ViewContext = new ViewContext();
vp.Url = new UrlHelper(viewContext);
Control control = vp.LoadControl(controlName);
vp.Controls.Add(control);
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter tw = new HtmlTextWriter(sw))
{
vp.RenderControl(tw);
}
}
return sb.ToString();
}