1

イメージ http 要求に対する MVC のデフォルトのルーティング動作を変更する必要があるプロジェクトがあります。

たとえば、RouteConfig.cs のこのサンプル

Route ImagesRoute = new Route("{controller}/{folderName}/{fileName}", new ImageRouteHandler());
string regexWindowsFilePattern = @"^([^\x00-\x1f\\?/%*:|" + "\"" + @"<>]+)\.(?:jpeg|jpg|tiff|gif|png)";

ImagesRoute.Constraints = new RouteValueDictionary { { "fileName", regexWindowsFilePattern } };
routes.Add(ImagesRoute);

ルートを変更する必要があります

http://localhost/home/contents/image.jpg

ディスク上のパス (c:\cache\[フォルダー名][ファイル名]) へ。私の場合の「再ルーティング」は、リクエストに基づいて正しい http 応答を書き込むことです。1 つのプロジェクト (「テスト」プロジェクトと呼びましょう) では、このコードは通常の動作をトリガーします。ImageRouteHandler クラスの GetHttpHandler メソッドがヒットし、画像がブラウザーに表示されますが、RouteConfig.cs と ImageRouteHandler の同一コードを持つ別のプロジェクトでは、単純に GetHttpHandler が挿入されます。起動しないため、404 NOT FOUND http エラーが発生します。この他のプロジェクト (「宛先」プロジェクト) の構成はほぼ同じで (関連する相違点を確認しました)、同じ IIS Express サーバーで実行されています。新しいプロジェクトを作成し、宛先およびテスト プロジェクトのコンテンツを取り込むと、通常の動作になります (つまり、画像がブラウザに表示されます)。

update_1:
アクションが意図的に使用されていないことを忘れていました。HTMLファイルの本文をレンダリングする部分ビューに含める必要があるHTMLファイルがあります。このファイルの作成方法を制御することはできませんが、[htmlFileName] という名前の html ファイルと [htmlFileName].files という名前のリソース フォルダー名という構造が定義されています。特定の URL (localhost/[Controller]/[Action] など) を要求すると、HTML マークアップでのリソースへの参照が間違った URL (http:// localhost/[Controller]/[folderName]/[fileName]) になるので、これらの URL を書き換えて、ブラウザの http イメージ リクエストが適切に応答されるようにする必要があります。そのため、このカスタム ハンドラーが必要だと思います。

using System;
using System.Net;
using System.Web;
using System.IO;
using System.Web.Routing;

namespace MyProject.WebUI.Interface.Utility
{
    public class ImageRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            string fileName = requestContext.RouteData.Values["fileName"] as string;
            string folderName = requestContext.RouteData.Values["folderName"] as string;

            if (string.IsNullOrEmpty(fileName))
            {
                // return a 404 NOT FOUND HttpHandler here
                requestContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
            }
            else
            {
                requestContext.HttpContext.Response.Clear();

                if (requestContext.HttpContext.Request.Url != null)
                {
                    requestContext.HttpContext.Response.ContentType =
                        GetContentType(requestContext.HttpContext.Request.Url.ToString());
                }
                else
                {
                    requestContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    requestContext.HttpContext.Response.End();
                }

                // find physical path to image here.  
                string filepath = @"c:\Cache" + @"\" + folderName + @"\" + fileName;

                /*If file exists send the response, otherwise set HTTP 404 NOT FOUND status code for response.*/
                if (File.Exists(filepath))
                {
                    requestContext.HttpContext.Response.WriteFile(filepath);
                    requestContext.HttpContext.Response.End();
                }
                else
                {
                    requestContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    requestContext.HttpContext.Response.End();
                }


            }
            return null;
        }


        private static string GetContentType(String path)
        {
            switch (Path.GetExtension(path))
            {
                case ".bmp": return "Image/bmp";
                case ".gif": return "Image/gif";
                case ".jpg": return "Image/jpeg";
                case ".jpeg": return "Image/jpg";
                case ".png": return "Image/png";
                default: break;
            }
            return "";
        }
    }
}
4

1 に答える 1

3

あるプロジェクトでは、Web.config に「modules」要素があるようです。

<modules runAllManagedModulesForAllRequests="true" />

これにより、ルーティング モジュールがイメージ リクエストで適切に動作するようになりました。これはデフォルトで Web.config に配置され、何らかの理由で他のプロジェクトにそのような xml 要素がありません。これは問題の解決策ですが、より良いものを見つけました:

<modules>
  <remove name="UrlRoutingModule-4.0" />
  <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>

これにより、任意の種類の要求に対して (すべてではなく) 1 つのマネージド モジュールのみが有効になります。これらの xml 要素を Web.config に追加すると、ImageRouteHandler の GetHttpHandler が意図したとおりにヒットします。

于 2012-12-19T11:56:51.803 に答える