我的搜索没有找到我认为是一个很好的主题。下面列出的选项反映了我发现的一些东西。
我需要从服务器端呈现视图作为ViewModel或通过JSON对象。JSON对象将来自服务器。
在客户端,我使用ajax,有时我根据页面上的其他id/属性来确定插入,以确定我是否追加/预结束/替换或忽略放置到目标元素。
我必须为ViewModels或JSON对象使用相同的视图哪些选项?
我曾经考虑过,在编译时,呈现一个File.Js版本的视图。将其作为页面上的资源包含,并在var ViewHtmlTemplate = "<div>@Model.Message</div>
上执行替换。我必须非常严格地将所有格式化/if语句逻辑移动到视图模型,这也将是JSON序列化。
或者,视图有一个脚本标签来绑定序列化到js变量的ViewModel,然后在document就绪时运行一个函数。
第三个选项不是返回一个JSON对象,而是返回一个服务器端已经html渲染的视图数组。
我所做的是在我的视图模型中,我将有一个字段,它是一个字符串,它是一个序列化的json结构。
public class SomeVM
{
/* other properties */
public string jsonString { get; set; }
}
在控制器中,我将把一些数据序列化到jsonString中。然后在视图中,将字符串赋值给变量
@model SomeVM
<script>
var jsonVM = @( Html.Raw(Model.jsonString) );
</script>
我正在使用在json对象中返回Html的解决方案。如果有任何问题,请告诉我。我是这样做的。
渲染部分视图的控制器扩展(包含但未在此解决方案中使用的RenderViewToString)。这可以在不同的答案中以各种形式找到,这些答案似乎与我的定制版本不匹配,我不认为这是功劳。
namespace System.Web.Mvc
{
using System.IO;
public static class MvcControllerExtension
{
public static string RenderPartialViewToString(this Controller controller, string viewName = null, object model = null)
{
if (string.IsNullOrEmpty(viewName))
{
viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
}
controller.ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
public static string RenderViewToString(this Controller controller, string viewName = null, object model = null, string masterName = null)
{
if (string.IsNullOrEmpty(viewName))
{
viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
}
controller.ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, masterName);
ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
}
}
在控制器动作中返回JsonResult
public JsonResult _DisplayByFoo(int catId)
{
var myRealModel = new MyRealModel(catId);
// .... omitted the construction of MyRealModel
var jsonModel = new JsonModel(myRealModel);
jsonModel.Html = this.RenderPartialViewToString("_Display", myRealModel);
return Json(jsonModel);
}
我还在json对象中包含了其他属性,这些属性可以帮助我确定插入模式。
在Js中;在我的AjaxCall到Json动作之后。运行OnSuccess方法,除其他逻辑外,该方法执行以下操作:
$("#" + targetId).append(MyJson.Html);