2013-10-08 18 views
19

は@usingステートメントがMVC4 Razor Viewに拡張メソッドが見つからないのはなぜですか?

@using JHS.ExtensionMethods; 

MVC4かみそりビューに加え、次の文字列値が

@Model.producer.phone.ToUSAPhone() 

た拡張メソッドを呼び出した次の文字列拡張メソッド

namespace JHS.ExtensionMethods 
{ 
    public static class StringExtensions 
    { 
    public static string ToUSAPhone(this String str) 
    { 
     return String.Format("{0:(###) ###-####}", Double.Parse(str)); 
    } 
    } 
} 

を考えます次のエラーが発生します。

'string' does not contain a definition for 'ToUSAPhone' 

また、/ Viewsフォルダのweb.configに名前空間を入れて同じエラーを受け取りました。私は、拡張メソッドを確認しました

<pages pageBaseType="System.Web.Mvc.WebViewPage"> 
    <namespaces> 
    <add namespace="System.Web.Mvc" /> 
    <add namespace="System.Web.Mvc.Ajax" /> 
    <add namespace="System.Web.Mvc.Html" /> 
    <add namespace="System.Web.Optimization"/> 
    <add namespace="System.Web.Routing" /> 
    <add namespace="JHS.ExtensionMethods"/> 
    </namespaces> 
</pages> 

は、C#クラスに

string test=producer.phone.ToUSAPhone(); 

を同じコールを置くことによって動作します「拡張メソッドへの参照がMVC4かみそりビューでは利用できないようですが、私はすることができますどうして?

+0

ビューのコードをさらに表示できますか?構文エラーがあるかもしれません。 'phone'は' string'型で、 'null'でもないと確信していますか? –

+1

サイドノート:*整数で定義された数値を 'double'に解析すると、ちょうど*狂気になります。... –

+1

2番目のメモ:' @ using' clausuleの後にセミコロンは必要ありません。 –

答えて

30

これは、拡張メソッドを使用しようとしているタイプが実際にdynamicである場合に発生します。例外がCSharp RuntimeBinderによって生成されているかどうかを確認します。もしそうなら、あなたは一般的なような方法を使用するか、または静的メソッド庭園することができ、次のいずれか

@StringExtensions.ToUSAPhone(Model.producer.phone) 

をそれとも、文字列に値をキャストすることができます(旧MSFTの)

@(((string)Model.producer.phone).ToUSAPhone()) 

According to Eric Lippert

ダイナミクスが拡張子 タイプをサポートしていないという理由は、通常では非動的コード拡張メソッドがすべてを検索するためですコンパイラが、拡張メソッドが一致する静的クラス のために知られているクラス。ネームスペースネストと、各ネームスペース内の利用可能な "使用" ディレクティブに基づいて、検索は となります。 が正しく解決動的拡張メソッドの呼び出しを得るために、何とかDLRはすべて 名前空間のネストと「使用」のディレクティブは、あなたのソースコード に何であったか、実行時に知っていなければならないことを意味

。その情報をすべて をコールサイトにエンコードするのに便利なメカニズムはありません。

+0

引用されたOPの誤りは次のとおりです: ''文字列'は 'ToUSAPhone'の定義を含んでいません。 Razorはすでにそれが文字列であることを知っています。 – haim770

+0

実際、Razorはデータ型について何も知らない。これはテンプレート言語であり、コンパイラではありません。私の答えで言ったように、タイプが動的であれば、文字列ではありません。 OPレポートがRuntimeBinderによって生成されているというエラーメッセージ。ここで何が起こっているのかについては、Eric Lippertの説明を参照してください:http://stackoverflow.com/questions/5311465/extension-method-and-dynamic-object-in-c-sharp –

+0

私はそれがコンパイル時のエラーだと考えました。 – haim770

0

ビューにエクステンションのカスタム名前空間を追加する前に、プロジェクトをビルドします。

1

拡張メソッドを呼び出すタイプが動的であるだけでなく、式内の何かが動的でキャストされていない場合。この例

は明らかに動的である:

@ViewBag.ToJSON() 

しかし、私はこれをやっていたので、私は最初にマイクの答えは私には適用されませんでしたと思った:

@(ViewBag.UserProfile.GetJSONProfile().ToJSON()) 

ToJSON()が私の拡張メソッドだけGetJSONProfile()ですobjectを返します。

私はちょうど離間していて、ばかげていましたが、これについて言及したいと思いました。

関連する問題