我正在使用ASP.NET MVC 4 Web API创建一个RESTful Web服务。对于API访问,我返回JSON,但一旦一切正常,默认情况下,内容协商应该适用于XML和JSON。
由于我正在致力于一个真正以RESTful资源为中心的web服务,所以我的URI将指向实际的资源。如果Accepts: text/html
出现在请求中(比如在浏览器中抛出链接),我希望通过返回资源的HTML表示来利用这一点。
我希望能够利用MVC 4 Web API的内容协商来插入使用Razor模板的text/html渲染器。有没有这样做的例子?
是的,这是连接"常规"MVC页面和Web API。基本上,我想创建一个渲染器,它使用基于约定的方法来查找和渲染Razor视图,就像"常规"MVC一样。我可以提出基于约定的视图查找逻辑我只是在寻找a)将我的text/html
渲染器全局插入到内容谈判中,以及b)手动使用Razor引擎将我的模型渲染到HTML中。
Fredrik Normén有一篇关于这个主题的博客文章:
http://weblogs.asp.net/fredriknormen/archive/2012/06/28/using-razor-together-with-asp-net-web-api.aspx
基本上,您需要创建一个MediaTypeFormatter
using System;
using System.Net.Http.Formatting;
namespace WebApiRazor.Models
{
using System.IO;
using System.Net;
using System.Net.Http.Headers;
using System.Reflection;
using System.Threading.Tasks;
using RazorEngine;
public class RazorFormatter : MediaTypeFormatter
{
public RazorFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xhtml+xml"));
}
//...
public override Task WriteToStreamAsync(
Type type,
object value,
Stream stream,
HttpContentHeaders contentHeaders,
TransportContext transportContext)
{
var task = Task.Factory.StartNew(() =>
{
var viewPath = // Get path to the view by the name of the type
var template = File.ReadAllText(viewPath);
Razor.Compile(template, type, type.Name);
var razor = Razor.Run(type.Name, value);
var buf = System.Text.Encoding.Default.GetBytes(razor);
stream.Write(buf, 0, buf.Length);
stream.Flush();
});
return task;
}
}
}
然后在Global.asax:中注册
GlobalConfiguration.Configuration.Formatters.Add(new RazorFormatter());
以上代码是从博客文章中复制的,不是我的作品
你可以看看WebApiContrrib.Formatting.Razor。它与Kyle的答案非常相似,但它是一个全面的开源项目,具有更多的功能、单元测试等。你也可以在NuGet上获得它。
我会说它肯定需要更多的功能,但他们似乎设计得很好,所以很容易为它做出贡献。