0

Knockout MVC というライブラリに問題があります。Knockout.js の .NET ラッパーです。C# ベースの ASP.NET MVC プロジェクトで使用する場合はかなりうまく機能しますが、VB.NET ベースのプロジェクトでは機能しないため、その理由がわかりました。

protected virtual string VisitMethodCall(MethodCallExpression m)
{
  ...
  if (typeof(Expression).IsAssignableFrom(m.Method.ReturnType))
    return VisitMemberAccess(m.Object, m.Method.Name);
  throw new NotSupportedException();
}

ライブラリを呼び出すプロジェクトが VB.NET で記述されている場合、条件は常に False と評価されます。C# で同じこと: 完全に動作します。

この異なる動作の原因がよくわからないので、コミュニティに尋ねるのは良い考えだと思いました. この行を C# と VB.NET の両方で動作するものに変換する方法を誰かが知っているかもしれません。

コードは ~ 行 260にあります

[編集]

明確にするために: 上記のコードを VB.NET に変換する必要はありません。問題はむしろ、C# または VB.NET コードから呼び出されたかどうかに基づいて、含まれている条件が異なる結果を返すことです。IsAssignableFrom は VB.NET と C# では動作が異なると思います...そのため、どの言語から呼び出されたかに関係なく、この条件を機能させる方法を知る必要があります。

[編集] - 例 次の手順で問題を再現します。

  1. VB.NET を使用して、Visual Studio 2012 で新しい ASP.NET MVC 4 プロジェクトを作成します。
  2. パッケージ マネージャー コンソール (Install-Package kMVC) を介して Knockout MVC を追加します。
  3. エラー (メソッドが null) を無視します。これは NuGet スクリプト エラーです。次の行を Global.asax.vb (Application_Start) に手動で追加します。

    ModelBinders.Binders.DefaultBinder = 新しい PerpetuumSoft.Knockout.KnockoutModelBinder()

  4. 次の構成を BundleConfig.vb に追加します。

    bundles.Add(New ScriptBundle("~/bundles/knockout").Include( "~/Scripts/knockout-{バージョン}.js", "~/Scripts/knockout.mapping-latest.js", "~/Scripts /perpetuum.knockout.js"))

  5. モダナイザーの下の _layout.vbhtml で ScriptBundle をレンダリングします。

    @Scripts.Render("~/bundles/knockout")

  6. モデル フォルダーに新しいモデルを追加します。

    DelegateDecompiler をインポートします

    パブリック クラス HelloWorldModel

      Public Property Firstname As String
      Public Property Lastname As String
    
      <Computed>
      Public ReadOnly Property Fullname As String
          Get
              Return Firstname + " " + Lastname
          End Get
      End Property
    

    クラス終了

  7. Controllers フォルダーに新しいコントローラーを追加します。

    Public Class HelloWorldController Inherit PerpetuumSoft.Knockout.KnockoutController

      '
      ' GET: /HelloWorld
    
      Function Index() As ActionResult
          Return View(New HelloWorldModel With {
                      .Firstname = "John",
                      .Lastname = "Doe"})
      End Function
    

    クラス終了

  8. MVC 拡張機能がモデルを認識できるようにプロジェクトをコンパイルします。

  9. コントローラーで Index アクションを右クリックし、[ビューの追加] を選択します。
  10. ビュー名はそのままにして、[厳密に型指定されたビューを作成] を選択し、HelloWorldModel をモデルとして選択します。残りはデフォルトのオプションのままにして、[追加] をクリックします。
  11. ビューの上部に Imports ステートメントを追加します。

    @Imports PerpetuumSoft.Knockout

  12. コード セクションでノックアウト コンテキストを作成する

    Dim ko = Html.CreateKnockoutContext()

  13. ビューを定義し、モデルを h2 タグの下に適用します

    <p>名前: @ko.Html.TextBox(Function(m) m.Firstname)</p>
    <p>姓: @ko.Html.TextBox(Function(m) m.Lastname)</p>
    <h2>こんにちは、@ko.Html.Span(Function(m) m.Fullname)!</h2>

    @ko.Apply(モデル)

ここで、アプリケーションをコンパイルして実行し、HelloWorld コントローラー (localhost:nnnnn/HelloWorld) を呼び出すと、行 ko.Apply(Model) で NotImplementedException が発生します。

C# で ASP.NET MVC プロジェクトを作成するときに上記の手順を繰り返すと、すべてが期待どおりに機能します。

4

1 に答える 1

0

これを試してください

Vb.net では、コードの構文が変更されています。

    Protected Overridable Function VisitMethodCall(m As MethodCallExpression) As String

    If GetType(Expression).IsAssignableFrom(m.Method.ReturnType) Then
        Return VisitMemberAccess(m.[Object], m.Method.Name)
    End If
        Throw New NotSupportedException()
    End Function

現在のアセンブリが参照するタイプ IPlugin を含むアセンブリ間に不一致があると思います。

使用する必要があります

 typeof (IPlugin).Module.FullyQualifiedName

 foreach (var type in t.GetInterfaces ()) 
 {    
     Console.WriteLine (type.Module.FullyQualifiedName)
 }

特定の不一致がどこにあるかを確認します。

于 2013-08-26T06:18:04.923 に答える