0

別の開発者は、Crystal レポートの大規模なコレクションを維持しています。完全な Crystal Reports Server 製品を必要とせずに、ASP.NET MVC3 ページでこれらのレポートを利用できるようにする必要があります。

現在のレポート サイトは、Prompt0&Prompt1 など、すべての引数が渡された従来の ASP ページです。

そのために、MVC アプリにある aspx ページを作成し、これらのレポートをアプリのディレクトリから次のように提供します。

パブリック部分クラス レポート: System.Web.UI.Page {

    protected void Page_Load(object sender, EventArgs e)
    {
        iLogger logger = LoggingFactory.CreateLogger();

        ReportDocument rd = new ReportDocument();

        string fileName = Request.QueryString["reportfile"];


        if(!Regex.IsMatch(fileName,@"^[ 0-9a-zA-Z-_\\]+.rpt$"))
        {
      //log and throw
        }



        if(Path.IsPathRooted(fileName))
        {
           //log and throw
        }

        string rootPath = Server.MapPath("~/Reports/");

        string path = Path.Combine(rootPath, fileName);



        if (File.Exists(path))
        {
            rd.Load(path);
        }

        //get all keys starting with Prompt
        var prompts = Request.QueryString.AllKeys.Where(q => q.StartsWith("Prompt"));

        foreach (string promptKey in prompts)
        {
            //try to convert the rest of the string to an int  
            //yes, this should probably not just be a replace here...
                string withoutPrompt = promptKey.Replace("Prompt", "");

                int promptVal;
                if (int.TryParse(withoutPrompt, out promptVal))
                {
                    rd.SetParameterValue(promptVal, Request.QueryString[promptKey]);
                }
                //rd.SetParameterValue(promptKey, Request.QueryString[promptKey]);

        }


        CrystalReportViewer1.ReportSource = rd;

    }
}

これは、労力の割に驚くほどうまく機能します (レポート デザイナーは、レポート/クエリ ページ内のリンクを、たとえば mywebserver.foo/Report1.rpt?Prompt....etc.etc から mywebserver.foo/mymvcreport/ に変更するだけで済みます)。 report.aspx?Filename=report1.rpt&Prompt... など

とてもすばらしいので、すぐに MVC アプリに移行して、10 のサイトを出向いて Crystal Server を購入する必要がなくなります。

私の明らかな懸念は、ファイル名の引数に、「C:\foo\bar」や「../bla/blah」など、誰かがそこに何でも入れることができるということです。これらのファイル名をエスケープし、それがアプリへのローカル パスであることを確認するための単一のベスト プラクティスはありますか?

たとえば、 /Sales/Quarterly/Quarterly.rpt のパラメーターを取得できるようにしたいと思います

私の最初の考えは、たとえば [0-9a-zA-z-_\]+ の正規表現を使用して、コロンまたはドット文字を使用できないようにすることです。これを処理する最も完全な方法に関する提案はありますか?

ありがとう!

編集:

私が入れた予備チェックで更新されました...

4

1 に答える 1

0

アプリケーション プール ユーザーに適切なアクセス許可を割り当てている限り、これは心配する必要はありません。

于 2012-07-25T23:03:11.267 に答える