【问题标题】:ASP.Net WebAPI Get current controller name from inside MediaTypeFormatterASP.Net WebAPI 从 MediaTypeFormatter 中获取当前控制器名称
【发布时间】:2012-06-11 21:01:29
【问题描述】:

我正在为 HTML 编写媒体类型格式化程序,以根据用户的 html 请求自动生成 Razor 视图。我这样做是为了在 SelfHosted 服务中使用。我需要检测请求了哪些控制器/操作以允许我选择要渲染的视图。

 public class RazorHtmlMediaTypeFormatter : MediaTypeFormatter
    {
        public RazorHtmlMediaTypeFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        }

        public override bool CanWriteType(Type type)
        {
            return true;
        }

        public override bool CanReadType(Type type)
        {
            return false;
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, System.Net.TransportContext transportContext)
        {
            return Task.Factory.StartNew(() =>
                {
                    var view = Razor.Resolve(String.Format("{0}.{1}.cshtml", something.Controller, something.Action), value);

                    byte[] buf = System.Text.Encoding.Default.GetBytes(view.Run(new ExecuteContext()));
                    stream.Write(buf, 0, buf.Length);
                    stream.Flush();
                });
        }
    }

【问题讨论】:

  • 您没有很好的方法来访问 HttpContext。也许你可以用 global.asax 做点什么?
  • @JoeTuskan 喜欢在开始请求时设置一些静态? IE基本上建立了自己的httpcontext

标签: c# asp.net-web-api mediatypeformatter


【解决方案1】:

为什么不将返回的对象包装在 Metadata<T> 中?

即返回,而不是 MyCustomObjectMetadata<MyCustomObject>。作为元数据属性,您可以设置控制器名称和操作。然后在格式化程序中,只需解耦元数据和您的自定义对象,并仅序列化该自定义对象。

我在这里写了关于这种方法的博客 - http://www.strathweb.com/2012/06/extending-your-asp-net-web-api-responses-with-useful-metadata/。虽然这篇文章的目的有点不同,但我相信您可以将其与您的需求联系起来。

编辑:或者如果您对小技巧没问题,请使用自定义过滤器和标题:

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        actionContext.Response.Headers.Add("controller", actionContext.ActionDescriptor.ControllerDescriptor.ControllerName);
        actionContext.Response.Headers.Add("action", actionContext.ActionDescriptor.ActionName;);
        base.OnActionExecuting(actionContext);
    }

然后从格式化程序的标题中读取它,并删除标题条目,以便它们不会被发送到客户端。

【讨论】:

  • 我考虑过这种方法,但缺点是它在内容协商方面效果不佳。您需要为要发布的每种类型的内容实现格式化程序,而不是依赖默认提供程序。顺便说一句,我真的很喜欢你的博客,你那里有很多非常好的东西:)
  • 非常感谢卢克,你的评论真的让我很开心:)
【解决方案2】:

Web API Contrib 在here 中有一个可用的 RazorViewFormatter。

【讨论】:

  • 很高兴知道有人已经这样做了,但与 filips 方法一样,它不能很好地处理内容协商。当您返回一个非 poco 类时,您需要为其编写自定义格式化程序以允许客户端协商 XML 或 HTML
猜你喜欢
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
相关资源
最近更新 更多