MVC Web Api返回序列化响应而不是css

时间:2012-08-21 23:30:07

标签: asp.net-mvc-4 asp.net-web-api mediatypeformatter

我遇到了从web api控制器返回css的问题。代码接受css文件的请求,并在从数据库中读取后返回它。

问题是web api代码似乎是序列化响应并返回而不是css本身。

在这里,您可以看到浏览器发送到应返回css的服务器的链接标记。您还可以看到响应看起来像是我的css的序列化,而不仅仅是css字符串。

enter image description here

我的请求和回复标题:

enter image description here

我的控制器看起来像这样:

public HttpResponseMessage Get(string fileName, string siteId, int id)
{
    var fileData = ReadSomeCssFromTheDatabase();

    var result = new HttpResponseMessage(HttpStatusCode.OK);
    result.Content = new ByteArrayContent(fileData);
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/css");

    result.Headers.CacheControl = new CacheControlHeaderValue();
    result.Headers.CacheControl.MaxAge = TimeSpan.FromHours(0);
    result.Headers.CacheControl.MustRevalidate = true;

    return result;
}

安装了一个“text / css”格式化程序,但是由于某种原因没有被命中。

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

    public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
    {
        var taskCompletionSource = new TaskCompletionSource<object>();
        try
        {
            var memoryStream = new MemoryStream();
            readStream.CopyTo(memoryStream);
            var s = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
            taskCompletionSource.SetResult(s);
        }
        catch (Exception e)
        {
            taskCompletionSource.SetException(e);
        }
        return taskCompletionSource.Task;
    }

    public override bool CanReadType(Type type)
    {
        return type == typeof(string);
    }

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

我做错了什么?

1 个答案:

答案 0 :(得分:1)

  • 您的格式化程序不会被点击,因为您没有经历内容协商过程(因为您在操作中返回HttpResponseMessage ...您可以使用Request.CreateResponse&lt;&gt;来使连接进程运行)

  • 你正在努力写作&#39; css内容对吗?...但是我看到CanWriteType正在返回&#39; false&#39;你似乎还在重写ReadFromStreamAsync而不是WriteToStreamAsync?

您可以做的一个例子(根据我对上述情况的理解):

public class DownloadFileInfo
{
    public string FileName { get; set; }
    public string SiteId { get; set; }
    public int Id { get; set; }

}

public HttpResponseMessage Get([FromUri]DownloadFileInfo info)
    {
        // validate the input

        //Request.CreateResponse<> would run content negotiation and get the appropriate formatter
        //if you are asking for text/css in Accept header OR if your uri ends with .css extension, you should see your css formatter getting picked up.
        HttpResponseMessage response = Request.CreateResponse<DownloadFileInfo>(HttpStatusCode.OK, info);

        response.Headers.CacheControl = new CacheControlHeaderValue();
        response.Headers.CacheControl.MaxAge = TimeSpan.FromHours(0);
        response.Headers.CacheControl.MustRevalidate = true;

        return response;
    }

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

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

    public override bool CanWriteType(Type type)
    {
        return type == typeof(DownloadFileInfo);
    }

    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        //use the 'value' having DownloadFileInfo object to get the details from the database.
        // Fead from database and if you can get it as a Stream, then you just need to copy it to the 'writeStream'
    }
}