none
「.sql.resx」 これはバグ?それとも仕様? RRS feed

  • 質問

  • Connectのほうには(バグか?と思って)投げてあるですが、そうそう進捗がないので、一度みなさんのご意見を伺いたく投稿しました。

    1.VisualStudio 2015(できうる限り最新に更新済み)で言語をC#として、ASP.NET Webサイトを作成します。
    2.App_GlobalResourcesフォルダを作成します。
    3.App_GlobalResourcesフォルダに以下の適当の内容のリソースファイルをいくつか追加します。
    これらのリソースファイルにはString1というリソースが入っているものとします。

    a.b.c.resx
    a.b.sql.resx

    4.念のため、ソリューションエクスプローラでフォルダの更新を行ってリフレッシュします。
    5.default.aspx.csあたりから、3で追加したa.b.c.resxを参照してみます。

    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var s = Resources.a.b.c.String1;
        }
    }

    これは問題ありません。

    6.次にa.b.sql.resxを同様に参照しようとすると......

    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var s = Resources.a.b.sql.String1;
        }
    }

    重大度レベル    コード    説明    プロジェクト    ファイル    行    抑制状態
    エラー    CS0234    型または名前空間の名前 'sql' が名前空間 'Resources.a.b' に存在しません (アセンブリ参照があることを確認してください)。    WebSite1(1)    C:\xxxxxxxxxxxx\Default.aspx.cs    16    アクティブ

    となり、突然ビルドできなくなります。

    他のファイル名のリソースも追加して試したところ、どうも、「なんたら.sql.resx」というファイル名が鬼門のようなのですが、これは何かの仕様(制限)なのでしょうか?それともバグだと思われますか?
    (たまたまかもしれませんが、以前のバージョンのVisualStudio(2008)ではビルドできていました)


    magmagg

    2016年4月5日 8:21

回答

  • designer.csファイルの探り当て方がどうにもわからなかったので、resgenとやらでコマンドライン(/str:cs)から吐かせてみましたが、これでも良いのでしょうか?a.b.resx(一応問題なし)の場合とa.b.sql.resx(ビルドできない)の両者の中身を比較したところ.....

    25: internal class a_b {  
          internal class a_b_sql { 
    32: internal a_b() {  
          internal a_b_sql() { 
    42: global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("a_b", typeof(a_b).Assembly);  
          global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("a_b_sql", typeof(a_b_sql).Assembly); 

    のようにクラス名が異なる以外は一致しているようです。

    *.sql.resxなどというファイル名に特段こだわりはなく、VS2008では通っていた(==正しいではありませんが)ことからの単純な疑問でした。すみません。

    a.b.sql.resxからのcs:

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     このコードはツールによって生成されました。
    //     ランタイム バージョン:2.0.50727.8670
    //
    //     このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
    //     コードが再生成されるときに損失したりします。
    // </auto-generated>
    //------------------------------------------------------------------------------

    using System;

    /// <summary>
    ///   ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。
    /// </summary>
    // このクラスは StronglyTypedResourceBuilder クラスが ResGen
    // または Visual Studio のようなツールを使用して自動生成されました。
    // メンバを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に
    // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class a_b_sql {
       
        private static global::System.Resources.ResourceManager resourceMan;
       
        private static global::System.Globalization.CultureInfo resourceCulture;
       
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal a_b_sql() {
        }
       
        /// <summary>
        ///   このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("a_b_sql", typeof(a_b_sql).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
       
        /// <summary>
        ///   厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、
        ///   現在のスレッドの CurrentUICulture プロパティをオーバーライドします。
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
       
        /// <summary>
        ///   AAAAAAA に類似しているローカライズされた文字列を検索します。
        /// </summary>
        internal static string String1 {
            get {
                return ResourceManager.GetString("String1", resourceCulture);
            }
        }
    }


    magmagg

    • 回答としてマーク MAGMAG 2016年4月5日 16:32
    2016年4月5日 13:17
  • SurferOnWwwさんに同意見です。

    バグか仕様かと聞かれればどちらでもなく、不適切なカルチャ名を指定した際の挙動については何も定められていない、かと。

    • 回答としてマーク MAGMAG 2016年4月6日 3:52
    2016年4月5日 20:50

すべての返信

  • バグか仕様かは Microsoft でないとわからないのでその話はできませんが・・・

    > a.b.c.resx
    > a.b.sql.resx

    何故そのような変則的な名前を使っているのですか? 命名規則は下の記事にもあるように、

    ベース名[.カルチャ名].resx

    です。(カルチャ名が省略されたリソース・ファイルはデフォルトのリソースと見なされる)

    [ASP.NET]リソース・ファイル活用で国際化対応ページを構築するには?
    http://www.atmarkit.co.jp/fdotnet/dotnettips/445aspmultilangres/aspmultilangres.html

    想像ですが、変則的な名前が想定外の結果を生んでいるような気がします(.sql がカルチャ名とみなされたとか?)。普通に命名したら回避できる問題だと思いますが、a.b.sql.resx のような命名をしなければならない理由があるのでしょうか?

    Web アプリケーションプロジェクトで、アプリケーションルート直下に App_GlobalResources フォルダを作り、その中に例えば MyResource.resx という名前のリソースファイルを配置し、それに Welcome という key 名で文字列を保存するとします。

    そうすると、MyResource.Designer.cs という名前の「厳密に型指定されたリソースクラス」が自動的に生成されます。(Web サイトプロジェクトでは Visual Studio から見えないところに「厳密に型指定されたリソースクラス」が生成されるので注意)

    「厳密に型指定されたリソースクラス」の名前空間は Resources、クラス名は MyResource となり、その中に Welcome という名前のプロパティが定義されます。

    だから、Resources.MyResource.Welcome でリソースファイルに設定した当該文字列を取得できるという仕組みです。

    a.b.sql.resx という名前にした場合はどうなるかは調べてませんので、質問者さんの方で調べていただけませんか? 「厳密に型指定されたリソースクラス」のコードを Visual Studio で開いて見ていただくのが簡単です。それで何故ダメだったのか分かるかもしれません。

    2016年4月5日 9:35
  • designer.csファイルの探り当て方がどうにもわからなかったので、resgenとやらでコマンドライン(/str:cs)から吐かせてみましたが、これでも良いのでしょうか?a.b.resx(一応問題なし)の場合とa.b.sql.resx(ビルドできない)の両者の中身を比較したところ.....

    25: internal class a_b {  
          internal class a_b_sql { 
    32: internal a_b() {  
          internal a_b_sql() { 
    42: global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("a_b", typeof(a_b).Assembly);  
          global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("a_b_sql", typeof(a_b_sql).Assembly); 

    のようにクラス名が異なる以外は一致しているようです。

    *.sql.resxなどというファイル名に特段こだわりはなく、VS2008では通っていた(==正しいではありませんが)ことからの単純な疑問でした。すみません。

    a.b.sql.resxからのcs:

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     このコードはツールによって生成されました。
    //     ランタイム バージョン:2.0.50727.8670
    //
    //     このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
    //     コードが再生成されるときに損失したりします。
    // </auto-generated>
    //------------------------------------------------------------------------------

    using System;

    /// <summary>
    ///   ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。
    /// </summary>
    // このクラスは StronglyTypedResourceBuilder クラスが ResGen
    // または Visual Studio のようなツールを使用して自動生成されました。
    // メンバを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に
    // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class a_b_sql {
       
        private static global::System.Resources.ResourceManager resourceMan;
       
        private static global::System.Globalization.CultureInfo resourceCulture;
       
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal a_b_sql() {
        }
       
        /// <summary>
        ///   このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("a_b_sql", typeof(a_b_sql).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
       
        /// <summary>
        ///   厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、
        ///   現在のスレッドの CurrentUICulture プロパティをオーバーライドします。
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
       
        /// <summary>
        ///   AAAAAAA に類似しているローカライズされた文字列を検索します。
        /// </summary>
        internal static string String1 {
            get {
                return ResourceManager.GetString("String1", resourceCulture);
            }
        }
    }


    magmagg

    • 回答としてマーク MAGMAG 2016年4月5日 16:32
    2016年4月5日 13:17
  • > designer.csファイルの探り当て方がどうにもわからなかったので、

    Web アプリケーションプロジェクトか Web サイトプロジェクトのどちらで作ってますか?

    先のレスで "Web サイトプロジェクトでは Visual Studio から見えないところに「厳密に型指定されたリソースクラス」が生成されるので注意" と書きましたが読んでいただいているでしょうか?

    Web アプリケーションプロジェクトなら以下のようになっているはずです。


    そんなことよりも、命名を見直す気はないのですか?変則的な命名の理由を教えていただけませんか?(確たる理由がなければ「変」としか見えません。聞いたのに説明もないし)




    • 編集済み SurferOnWww 2016年4月5日 14:13 一部訂正
    • 編集済み 星 睦美 2016年4月6日 4:31 スレッドの内容に適した表現に変更
    2016年4月5日 14:13
  • SurferOnWwwさんに同意見です。

    バグか仕様かと聞かれればどちらでもなく、不適切なカルチャ名を指定した際の挙動については何も定められていない、かと。

    • 回答としてマーク MAGMAG 2016年4月6日 3:52
    2016年4月5日 20:50
  • 星さん>

    「変な命名」 ⇒ 「変則的な命名」に直したようですが、それが「スレッドの内容に適した表現」と言うのであれば、訂正前の表現が適してないと言ってますか? であればその理由を書いてください。

    2016年4月7日 4:55
  • SurferOnWww さんの返信のなかで命名の規則をもとに説明をされていますので、規則と異なるという意味で「変則的」とさせていただきました。

    フォーラム オペレーター 星 睦美 - MSDN Community Support


    • 編集済み 星 睦美 2016年4月7日 5:04 編集
    2016年4月7日 5:03
  • 星さん>

    できれば直す前に了解を求めていただくか、それが無理なら、直す際にでも結構ですので、

    > SurferOnWww さんの返信のなかで命名の規則をもとに説明をされていますので、
    > 規則と異なるという意味で「変則的」とさせていただきました。

    と説明を書いていただければと思います。それも無理でしょうか?

    2016年4月7日 5:20
  • SurferOnWww さん、説明が不足しており申し訳ございませんでした。誤解の無いように今後させていただきます。よろしくお願いいたします。

    フォーラム オペレーター 星 睦美 - MSDN Community Support

    2016年4月7日 5:27
  • 星さん>

    お手数をおかけしますが、よろしくお願いします。

    2016年4月7日 5:36