在我的整个应用程序中,我使用强类型的视图模型。现在,我的任务是正常显示视图,或者如果存在特定参数,则提供序列化的ViewModel。
所以,我首先想到的是:
public ActionResult SomeAction(int id, string apiMode)
{
var model = new ViewModel(); //Obtain model
if (apiMode == "json")
{
return Json(model);
}
return View(model)
}
现在我想知道是否有更通用的解决方案?
答案 0 :(得分:0)
完全有可能。
我们可以通过以下方式扩展RazorViewEngine
:
public class AppViewEngine : RazorViewEngine
{
private const string ApiModeParam = "API__MODE";
public AppViewEngine()
{
//Performance optimization, if we do not need to lookup for vbhtml
FileExtensions = new[] {"cshtml"};
}
public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
var apiMode = controllerContext.HttpContext.Request.Params[ApiModeParam];
if (apiMode == null)
{
return base.FindPartialView(controllerContext, partialViewName, useCache);
}
return GetApiResult(apiMode);
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
var apiMode = controllerContext.HttpContext.Request.Params[ApiModeParam];
if (apiMode == null)
{
return base.FindView(controllerContext, viewName, masterName, useCache);
}
return GetApiResult(apiMode);
}
private ViewEngineResult GetApiResult(string apiMode)
{
switch (apiMode)
{
case "json":
return new ViewEngineResult(new ApiJsonView(), this);
case "xml":
return new ViewEngineResult(new ApiXmlView(), this);
default:
return new ViewEngineResult(new[] { "API__MODE is not supported" });
}
}
}
现在我们只需要一些视图:
public class ApiJsonView : IView
{
public void Render(ViewContext viewContext, TextWriter writer)
{
viewContext.HttpContext.Response.AddHeader("Content-Type", "application/json");
//Json.NET, normaly included in MVC
var serializer = JsonSerializer.Create();
serializer.Serialize(writer, viewContext.ViewData.Model);
}
}
public class ApiXmlView : IView
{
public void Render(ViewContext viewContext, TextWriter writer)
{
viewContext.HttpContext.Response.AddHeader("Content-Type", "application/xml");
var model = viewContext.ViewData.Model;
var serializer = new DataContractSerializer(model.GetType());
using (var xmlWriter = new XmlTextWriter(writer))
{
serializer.WriteObject(xmlWriter, model);
}
}
}
最后一件事:我们需要使用global.asax
方法在Application_Start
中注册它:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new AppViewEngine());
现在,每个附加了?API__MODE=json
的请求都显示序列化的ViewModel而不是HTML页面。最好的是,它很简单:
public ActionResult SomeAction(int id)
{
var model = new ViewModel(); //Obtain model
return View(model)
}