0

Web API コントローラーから css を返す際に問題が発生しています。このコードは、css ファイルの要求を受け取り、データベースから読み取った後にそれを返します。

問題は、Web API コードが応答をシリアル化し、css 自体ではなくそれを返しているように見えることです。

ここでは、ブラウザが css を返すサーバーに送信しているリンク タグを確認できます。また、応答が単なる css 文字列ではなく、私の css のシリアル化のように見えることもわかります。

ここに画像の説明を入力

私の要求と応答ヘッダー:

ここに画像の説明を入力

私のコントローラーは次のようになります。

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;
    }
}

私は何を間違っていますか?

4

1 に答える 1

1
  • コンテンツ ネゴシエーション プロセスを実行していないため、フォーマッタはヒットしません (アクションで HttpResponseMessage を返しているため... Request.CreateResponse<> を使用して conneg プロセスを実行できます)。

  • cssコンテンツを正しく「書き込もう」としていますか? ...しかし、CanWriteTypeが「false」を返していることがわかり、WriteToStreamAsyncではなくReadFromStreamAsyncをオーバーライドしているようです?

あなたができる方法の例(上記のシナリオについて私が理解したことから):

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'
    }
}
于 2012-08-22T00:20:09.037 に答える