从 C# 执行 JS 代码的异常:预期函数

本文关键字:函数 异常 执行 JS 代码 | 更新日期: 2023-09-27 18:36:49

我在我的C#代码中有这个javasccript表达式代码作为字符串,我需要使用Microsoft.JScript.Eval.JScriptEvaluate(c#)评估它(执行它)并返回结果。

string code = @"var roles=[];
roles.push('LOC_IND');
roles.push('MANAGERL3');
var country='CANADA';
var age=80;
eval(""roles.indexOf('Administrator')>=0||roles.indexOf('LOC_IND')>=0&&country=='CANADA'"")";
// Calling JScript.Eval to execute that code
var engine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
var result = Microsoft.JScript.Eval.JScriptEvaluate(code, engine);

javascript 代码本身工作正常,如果您在浏览器控制台中执行它,并按预期返回"true":

var roles=[];
roles.push('LOC_IND');
roles.push('MANAGERL3');
var country='CANADA';
var age=80;
eval("roles.indexOf('Administrator')>=0||roles.indexOf('LOC_IND')>=0&&country=='CANADA'")

但是,当我从 C# Eval.JScriptEvaluate(代码,引擎)调用它时;我得到这个异常:

预期功能。

不确定它期望什么功能,我该怎么做才能解决这个问题?最后,Eval.JScriptEvaluate(code, engine) 必须返回 true。

从 C# 执行 JS 代码的异常:预期函数

首先,你不需要调用 eval。
其次,您应该将代码包装在自调用函数中,因为您期望得到一个结果。
第三,看起来Microsoft JScript不支持JavaScript的Array.prototype的部分或全部方法,所以你不能使用indexOf()。试试这个代码:

string code = @"
function hasRole(roles,role){
    for(var i=0;i<roles.length;i++)
        if(roles[i]==role)return true;
    return false;
};
(function(){
    var roles=[],country='CANADA',age=80;
    roles.push('LOC_IND');
    roles.push('MANAGERL3');
    return hasRole(roles,'Administrator')||hasRole(roles,'LOC_IND')&&country=='CANADA';
})();";


附带说明一下,您的 return 语句中似乎缺少一对括号。

非常感谢狗狗:)

我找到了一种更简单的方法,使用另一个库 - Jint。

此位置是正确的:https://github.com/sebastienros/jint

string code = @"var roles=[];
roles.push('LOC_IND');
roles.push('MANAGERL3');
var country='CANADA';
var age=80;
function foo(){return roles.indexOf('Administrator')>=0||roles.indexOf('LOC_IND')>=0&&country=='CANADA';}";
// Using Jint - Javascript Interpreter for .NET
var result = new Jint.Engine().Execute(code).Invoke("foo");

附言另一种选择是使用自调用函数,但更难获得返回布尔值结果:

string code = @"var roles=[];
roles.push('LOC_IND');
roles.push('MANAGERL3');
var country='CANADA';
var age=80;
(function(){return roles.indexOf('Administrator')>=0||roles.indexOf('LOC_IND')>=0&&country=='CANADA';})();";
var result = new Jint.Engine()
    .Execute(code)
    .Boolean
    .PrototypeObject
    .PrimitiveValue
    .AsBoolean();