2

Web アプリケーション内のすべての画像を CDN に移動しようとしていますが、画像へのパスをハードコードすることなく、CDN のオンとオフを簡単に切り替えることができるようにしたいと考えています。

私が最初に考えたのは、web.config の変数 (のようなもの) がサーバーまたは CDN から画像を提供するかどうかに応じて、画像拡張機能の HttpHandler を追加することでした。しかし、これを少し与えた後、基本的にこれを除外したと思います.ASP.NETがすべての単一の画像の要求を処理するため、オーバーヘッドが追加され、実際にはCDNを使用する利点が完全に軽減される可能性があります.

別のアプローチとして、すべてのページが基本ページ クラスから継承されるため、web.config 変数に基づいてファイルを提供するパスを決定する関数を基本クラスに作成することができます。次に、マークアップで次のようにします。

<img src='<%= GetImagePath()/image.png' />

これはおそらく私がしなければならないことだと思いますが、少し不格好に思えます。また、"<%=" が原因でコントロール コレクションを変更できないという古い .NET エラーの問題も想定していますが、"<%#" ソリューションはおそらく機能します。

これを実装する方法についての考えやアイデアはありますか?

4

9 に答える 9

2

HttpHandler最適化前の仮定に基づいて を書くことを却下しました。私はこれを再検討し、間違いなく単純なものを書いてHttpHandlerテストします。特に ASP プリプロセッサを使用する場合は、Page メソッド ソリューションがさらに遅くなることがあります。

HttpHandlers は非常に金属に近いものです。IIS がリクエストを ASP.Net に渡すのに必要なオーバーヘッドはごくわずかです。それはあなたが提案しているものよりもエレガントなソリューションであり、おそらくよりスケーラブルであり、私は賭けても構わないと思っています.

于 2010-03-27T19:59:53.903 に答える
2

もう少し単純なアプローチを検討しましたか?

すべてのページが基本クラスから継承されている場合、CDN (または、CDN をオフにする場合はローカル サーバー) へのプリペンド URL を含むプロパティを公開できます。次に、プリペンド URL を web.config に保存するのは簡単なことです。

public string PrependURLPath() {
 get { return ConfigurationManager.AppSettings["ImagePrependURL"].ToString(); }
}

<appSettings/>要素では、先頭に追加する URL を簡単に選択できます。たとえば、次のようになります。

http://my.cdn.com/user/

また:

http://my.own.server.com/images/

ものすごく単純!

次に、例に従って画像参照をコーディングできますが、基本ページ プロパティを呼び出して目的のパスを公開します。

<img src='<%= this.BasePage.PrependURLPath() + [YourImagePath.png] %>'/>

インライン呼び出しで画像ソースを設定するのは面倒ですが、おそらく他の誰かが提案したようにして、ページの画像コントロールを繰り返し、先頭に追加する URL を変更することができます。

ページが現在 System.Web.UI.Page からしか継承していない場合でも、System.Web.Page を継承する独自の基本クラスを作成し、残りのすべてのページのソリューションで検索/置換を実行するのは簡単です。

お役に立てれば。

于 2010-03-29T16:04:05.980 に答える
2

ここでかなり遅く検討していますが、私は自分で同様の解決策を探していました。Googleで検索して、私が何をしたかを確認しました。アプローチを考慮していませんでしHttpHandlerた。私がしたことは、単に ASP.netImageコントロールを拡張することでした。

public class Img : Image
{
    public Img()
    {
        RelativePath = false;
    }

    public bool RelativePath { get; set; }

    public override string ImageUrl
    {
        get
        {
            if (RelativePath)
                return base.ImageUrl;

            return "http://some.configurable-value.com" + base.ImageUrl;
        } 
        set { base.ImageUrl = value; }
    }
}

それはラフで準備ができていますが、機能します:)明らかに、文字列リテラルではなく、構成可能な値に依存する必要がありますが、それは大きな変更ではありません

于 2011-03-07T12:52:23.873 に答える
1

タグを使用して画像を表示する場合、コントロール アダプターを作成できます。これらにより、.net コントロールのレンダリング方法を変更したり、次のように全体的に変更したりできます。

using System.Web.UI.WebControls.Adapters;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ExampleCode
{
    public class ImageAdapter : WebControlAdapter
    {
        private bool UseCdn
        {
            get { return true; } // Get value from config or anywhere else
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            Image image = (Image)Control;

            if (UseCdn)
            {
                // If using relative urls for images may need to handle ~
                image.ImageUrl = String.Format("{0}/{1}", "CDN URL", image.ImageUrl);
            }
         }
      }
 }

次に、以下のように Web プロジェクトの App_Browsers フォルダーにブラウザー ファイルを追加します。

<browsers>
    <browser refID="Default">
      <controlAdapters>
        <adapter
          controlType="System.Web.UI.WebControls.Image"
          adapterType="ExampleCode.ImageAdapter"
          />
      </controlAdapters>
    </browser>
</browsers>
于 2010-03-30T22:42:14.310 に答える
0

すべてのコントロールをループして、基本クラスの prerender イベントで画像の URL を変更できます...

于 2010-03-27T19:59:34.067 に答える
0

画像制御には @Rhys アプローチを使用します。

ほとんどの場合、画像コントロールを使用するよりも背景画像 css を使用しようとします。

その後、css と画像の両方を一緒にクラウドにアップロードし、相対パスで正常に動作します。

于 2011-01-14T03:37:25.747 に答える
0

HTTP ハンドラー アプローチの良い点は、再利用可能で構成可能であることです。場所に基づいて処理する img パスを識別できます。それらの構造がこれに役立つと仮定します。

考えられる欠点は、画像ファイルの拡張子 (.jpg、.png など) が自動的に asp.net パイプラインに渡されないことです。そのように IIS を簡単に構成できますが、IIS に対して一定レベルの制御が必要です。そのため、共有ホスティング環境を使用している場合は選択肢にならない可能性があります。

于 2010-03-29T00:13:21.447 に答える
0

私はあなたの問題と別の問題を解決しなければなりませんでした。つまり、開発中に CDN からリソースを取得したくありませんが、Web サイトが運用サーバーにデプロイされている場合にのみ使用します。これを解決するために、本番環境でのみ CDN URL を先頭に追加する ExpressionBuilder を開発しました。

<asp:Image ImageUrl="<%$ CdnUrl:/images/myimage.png %>" runat="server" />

前のコードでは、本番環境でのみ CDN URL が付加されます。

namespace IdeaR.Web.Compilation
{
[ExpressionPrefix("CdnUrl")]
public class CdnUrlExpressionBuilder : ExpressionBuilder
{
    public static object GetCdnUrl(string expression, Type target, string entry)
    {
        var retvalue = expression;
        var productionUri = new Uri("http://www.myproductionurl.com",
            UriKind.Absolute);
        var currentUri = HttpContext.Current.Request.Url;
        var cdnUrl = "http://cdn.mycdn.com";

        // If this is a production website URL
        if (currentUri.Scheme == productionUri.Scheme &&
            currentUri.Host == productionUri.Host)
            retvalue = cdnUrl + expression;

        return retvalue;
    }

    public override CodeExpression GetCodeExpression(BoundPropertyEntry entry,
        object parsedData, ExpressionBuilderContext context)
    {
        var componentType = entry.DeclaringType;
        var expressionArray = new CodeExpression[3]
        {
            new CodePrimitiveExpression(entry.Expression.Trim()),
            new CodeTypeOfExpression(componentType),
            new CodePrimitiveExpression(entry.Name)
        };

        var descriptor = TypeDescriptor.GetProperties(componentType)
            [entry.PropertyInfo.Name];
        return new CodeCastExpression(descriptor.PropertyType,
            new CodeMethodInvokeExpression(
                new CodeTypeReferenceExpression(GetType()),
                "GetCdnUrl", expressionArray));
    }       
}
}

詳細については、この How to use a CDN in production but not during developmentに関する記事を書きました

于 2015-12-19T18:38:40.883 に答える