在ASP.NET MVC4中是否可以将C#或VB函数标记为Javascript?
|
我有一个 HtmlHelper扩展方法,它将javascript回调函数作为参数.例如: @Html.SomethingCool("containerName","jsCallbackFunction")
<script type="javascript">
function jsCallbackFunction(e,i) {
alert(e.target.name + ' / ' + i);
}
</script>
如您所见,JavaScript回调函数名称被传递给HtmlHelper扩展方法.这导致开发人员必须参考文档来找出jsCallbackFunction函数需要的参数. 我宁愿喜欢这样的东西: @Html.SomethingCool("containerName",New SomethingCoolCallbackDelegate(Address Of jsCallbackFunction))
<OutputAsJavascript>
Private Sub jsCallbackFunction(e,i)
' SOMETHING goes here. some kind of html dom calls or ???
End Sub
SomethingCoolCallbackDelegate将为目标函数提供代码合同. 有没有像这样内置的.NET 4 / ASP.NET MVC 4 / Razor 2?还是可以实现类似的任何其他技术? 示例在VB中,但C#中的解决方案也是可以接受的. 澄清: @gideon:注意jsCallbackFunction有两个参数e,而i.但是,HtmlHelper扩展方法只需要一个字符串(javascript回调函数的名称),并且不指示此函数可能需要哪些参数.我想解决的问题是双重问题. >首先,缺少参数提示.传递代替“javascript回调名称”字符串的.NET代理类型将完成此操作.我可以接受其他解决方案来实现这一点.我知道XML的意见.他们不是一个真正的解决方案. @TyreeJackson:SomethingCool是一个HtmlHelper扩展方法,我会写,输出html和javascript. JavaScript输出的一部分需要调用一个用户(程序员)来进行一些决定.想想它类似于您为ajax调用提供的成功或失败功能. 解决方法虽然我不能给你一个完整的transpiler /编译器选项,因为这将是一个巨大的工作量,我可以建议以下内容来协助智能感知支持和发出的功能和调用.这是基础设施代码.您需要完成getArgumentLiteral和getConstantFromArgument函数来处理您提出的其他情况,但这是一个体面的起点. public abstract class JavascriptFunction<TFunction,TDelegate> where TFunction : JavascriptFunction<TFunction,TDelegate>,new()
{
private static TFunction instance = new TFunction();
private static string name = typeof(TFunction).Name;
private string functionBody;
protected JavascriptFunction(string functionBody) { this.functionBody = functionBody; }
public static string Call(Expression<Action<TDelegate>> func)
{
return instance.EmitFunctionCall(func);
}
public static string EmitFunction()
{
return "function " + name + "(" + extractParameterNames() + ")rn{rn " + instance.functionBody.Replace("n","n ") + "rn}rn";
}
private string EmitFunctionCall(Expression<Action<TDelegate>> func)
{
return name + "(" + this.extractArgumentValues(((InvocationExpression) func.Body).Arguments) + ");";
}
private string extractArgumentValues(System.Collections.ObjectModel.ReadOnlyCollection<Expression> arguments)
{
System.Text.StringBuilder returnString = new System.Text.StringBuilder();
string commaOrBlank = "";
foreach(var argument in arguments)
{
returnString.Append(commaOrBlank + this.getArgumentLiteral(argument));
commaOrBlank = ",";
}
return returnString.ToString();
}
private string getArgumentLiteral(Expression argument)
{
if (argument.NodeType == ExpressionType.Constant) return this.getConstantFromArgument((ConstantExpression) argument);
else return argument.ToString();
}
private string getConstantFromArgument(ConstantExpression constantExpression)
{
if (constantExpression.Type == typeof(String)) return "'" + constantExpression.Value.ToString().Replace("'","'") + "'";
if (constantExpression.Type == typeof(Boolean)) return constantExpression.Value.ToString().ToLower();
return constantExpression.Value.ToString();
}
private static string extractParameterNames()
{
System.Text.StringBuilder returnString = new System.Text.StringBuilder();
string commaOrBlank = "";
MethodInfo method = typeof(TDelegate).GetMethod("Invoke");
foreach (ParameterInfo param in method.GetParameters())
{
returnString.Append(commaOrBlank + param.Name);
commaOrBlank = ",";
}
return returnString.ToString();
}
}
public abstract class CoreJSFunction<TFunction,TDelegate> : JavascriptFunction<TFunction,TDelegate>
where TFunction : CoreJSFunction<TFunction,new()
{
protected CoreJSFunction() : base(null) {}
}
以下是标准函数支持包装器的示例: public class alert : CoreJSFunction<alert,alert.signature>
{
public delegate void signature(string message);
}
这里有几个示例Javascript函数支持包装器: public class hello : JavascriptFunction<hello,hello.signature>
{
public delegate void signature(string world,bool goodByeToo);
public hello() : base(@"return 'Hello ' + world + (goodByeToo ? '. And good bye too!' : ''") {}
}
public class bye : JavascriptFunction<bye,bye.signature>
{
public delegate void signature(string friends,bool bestOfLuck);
public bye() : base(@"return 'Bye ' + friends + (bestOfLuck ? '. And best of luck!' : ''") {}
}
这是一个演示其使用的控制台应用程序: public class TestJavascriptFunctions
{
static void Main()
{
// TODO: Get javascript functions to emit to the client side somehow instead of writing them to the console
Console.WriteLine(hello.EmitFunction() + bye.EmitFunction());
// TODO: output calls to javascript function to the client side somehow instead of writing them to the console
Console.WriteLine(hello.Call(func=>func("Earth",false)));
Console.WriteLine(bye.Call(func=>func("Jane and John",true)));
Console.WriteLine(alert.Call(func=>func("Hello World!")));
Console.ReadKey();
}
}
这里是控制台应用程序的输出: function hello(world,goodByeToo)
{
return 'Hello ' + world + (goodByeToo ? '. And good bye too!' : ''
}
function bye(friends,bestOfLuck)
{
return 'Bye ' + friends + (bestOfLuck ? '. And best of luck!' : ''
}
hello('Earth',false);
bye('Jane and John',true);
alert('Hello World!');
更新: 您可能还想查看JSIL.我不隶属于该项目,不能说它的稳定性,准确性和效力,但它听起来很有趣,可能可以帮助您. (编辑:鄂州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 防止双击asp.net按钮
- asp.net中让Repeater和GridView支持DataPager分页
- asp.net – ASP MVC – 默认的HTTP标头有任何常量吗?
- asp.net-mvc – .Net 4.5.1框架的maxRequestLength
- NHibernate中对同一个对象的Lazyload要设置一致
- asp.net – IE8 Win7 Facebook Connect问题
- 在asp.net中使用eval(“”)
- asp.net-mvc – 如何组合两个dataTextFields的SelectList描
- asp.net-mvc – 在ClaimsIdentity上,BootstrapContext为nul
- ASP.NET Core中调整HTTP请求大小的几种方法详解
- .net – ELMAH对企业库异常处理块
- asp.net-mvc – 删除布局将默认为_ViewStart,为什
- asp.net – 如何从日历控件中获取所选日期?
- asp.net-mvc – 针对SAAS的多租户客户端特定定制
- asp.net-mvc – Url.Action生成查询字符串,以任何
- ASP.NET中的应用程序生存期
- asp.net-mvc – 允许asp.net mvc 2控制器名称的U
- asp.net-mvc-4 – 如何在asp.net MVC4查看页面中
- 具有多个ASP.NET Web应用程序的Visual Studio解决
- asp.net-mvc-3 – 如何在Razor中为Nullable创建编
