我在使用名为 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# 的行为不同......所以我需要知道如何让这个条件独立于它被调用的语言而工作。
[编辑] - 示例 以下步骤重现了该问题:
- 使用 VB.NET 在 Visual Studio 2012 中创建一个新的 ASP.NET MVC 4 项目
- 通过包管理器控制台添加 Knockout MVC (Install-Package kMVC)
忽略错误(Methods 为 null),这是 NuGet Script 错误,手动在 Global.asax.vb (Application_Start) 中添加以下行:
ModelBinders.Binders.DefaultBinder = 新 PerpetuumSoft.Knockout.KnockoutModelBinder()
将以下配置添加到 BundleConfig.vb
bundles.Add(New ScriptBundle("~/bundles/knockout").Include("~/Scripts/knockout-{version}.js", "~/Scripts/knockout.mapping-latest.js", "~/Scripts /perpetuum.knockout.js"))
在 Modernizer 下方的 _layout.vbhtml 中渲染 ScriptBundle
@Scripts.Render("~/bundles/knockout")
将新模型添加到模型文件夹
导入 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
结束类
将新控制器添加到 Controllers 文件夹
公共类 HelloWorldController 继承 PerpetuumSoft.Knockout.KnockoutController
' ' GET: /HelloWorld Function Index() As ActionResult Return View(New HelloWorldModel With { .Firstname = "John", .Lastname = "Doe"}) End Function
结束类
编译项目,以便 MVC 扩展了解模型
- 右键单击控制器中的索引操作并选择“添加视图..”
- 保留视图名称并选择创建强类型视图,选择 HelloWorldModel 作为模型;将其余部分保留为默认选项,然后单击添加
在视图顶部添加 Imports 语句
@Imports PerpetuumSoft.Knockout
在代码部分创建淘汰赛上下文
Dim ko = Html.CreateKnockoutContext()
定义视图并在 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 项目时重复上述步骤,一切都会按预期进行。