从 C# 执行 JS 代码时出现异常:预期的功能

Exception executing JS code from C#: Function expected

我的 C# 代码中有这个 javascript 表达式代码作为字符串,我需要使用 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 代码本身 工作正常,如果您在浏览器控制台中执行它,并且 returns "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(code, engine);我得到这个例外:

Function expected.

我不确定它需要什么功能,我需要做些什么来解决这个问题? 最后 Eval.JScriptEvaluate(code, engine) 必须 return true.

首先,您不需要调用 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");

P.S。另一种选择是使用自调用函数,但更难获得 return bool 结果:

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();