如何从不带引号的 WebAPI 控制器发送带有 javascript 函数的 JSON

Posted

技术标签:

【中文标题】如何从不带引号的 WebAPI 控制器发送带有 javascript 函数的 JSON【英文标题】:How to send JSON with javascript function from WebAPI controller without quotes 【发布时间】:2020-01-20 11:32:12 【问题描述】:

我们有

    C# WebAPI 服务器后端 node JS 客户端 SPA 前端

我们的一个 API 会生成一个 C# 对象,它代表一个 ChartJS 模型。像这样

public virtual IActionResult Chart()

        var chartModel = GetChart();
        return new ObjectResult(chartModel);

简化后的 ChartModel 类如下所示

public class ChartJSModel

    ...
    public string callback  get; set;  //FUNCTION
    ...

客户端收到此 JSON ObjectResult(再次简化)


    "callback": "function(value, index, values)  return Number(value.toString());"        

回调函数用引号引起来。这会破坏 ChartJS。

问题

    所以 JSON 是 purely meant for data description language 但我如何让 C# WebAPI 发送回不带引号的回调? 我可以在客户端处理 JSON,但也许还有其他选择。

【问题讨论】:

JSON 中不能有函数 - 在 JSON 中,值只能是...对象、数组、字符串、数字、null、true 或 false 每当响应发生时,模型将转换为 json,以便更好地处理 UI 端或作为替代使用 xml 作为媒体格式化程序而不是 json,然后在 ui 端将 xml 转换为 json。我知道它不是最佳解决方案,只是为了实现您的目的。 这并不是说你想做的事情是无法实现的——你只需要跳出框框思考......例如。在服务器上发送 "callback": "fn1" ...在客户端,处理解析的JSON(即您现在拥有的javascript对象)并查找callback键,并相应地更改值...“fn1”为function(.... @HarshadVekariya - XML(也是纯文本响应)如何提供帮助 检查答案以返回 xml:***.com/questions/18266952/…。虽然它用于 json,但您可以相应地更改代码。 【参考方案1】:

您不能在 JSON 中使用函数 - 在 JSON 中,值只能是...对象、数组、字符串、数字、null、true 或 false

这并不是说你想做的事情是无法实现的——你只需要跳出框框思考......例如。在服务器上发送 "callback": "fn1" ... 在客户端,处理解析的 JSON(即您现在拥有的 javascript 对象)并查找回调键,并相应地更改值... "fn1" 到函数(.. 等

所以,如果你改变你的服务器代码来发送类似的东西


    "type": "line",
    "data": 
        "datasets": [
        ]
    ,
    "options": 
        "scales": 
            "xAxes": [
                    "type": "logarithmic",
                    "position": "bottom",
                    "ticks": 
                        "beginAtZero": false,
                        "min": 0.0,
                        "max": "NaN",
                        "stepSize": "NaN",
                        "callback": "fn1"
                    ,
                
            ],
            "yAxes": [
                    "type": "logarithmic",
                    "position": "left",
                    "ticks": 
                        "beginAtZero": false,
                        "min": 0.0,
                        "max": "NaN",
                        "stepSize": "NaN",
                        "callback": "fn1arrow"
                    ,
                
            ]
        ,

    

然后你可以写一个类似的函数

function fixCallbacks(obj) 
    const fns = 
        fn1: function(value, index, values)  return Number(value.toString());,
        fn1arrow: (value, index, values) => Number(value.toString()),
    ;
    Object.entries(obj).forEach(([k, v]) => 
        if (typeof v === 'object' || typeof v === 'array') 
            fixCallbacks(v);
         else if (k === 'callback') 
            obj[k] = fns[v] || obj[k];
        
    );

注意:fn1 和 fn1arrow 做同样的事情,只是表明你可以使用函数和箭头函数作为解决方案

它应该可以工作 - 像这样

const data = 
    "type": "line",
    "data": 
        "datasets": [
        ]
    ,
    "options": 
        "scales": 
            "xAxes": [
                    "type": "logarithmic",
                    "position": "bottom",
                    "ticks": 
                        "beginAtZero": false,
                        "min": 0.0,
                        "max": "NaN",
                        "stepSize": "NaN",
                        "callback": "fn1"
                    ,
                
            ],
            "yAxes": [
                    "type": "logarithmic",
                    "position": "left",
                    "ticks": 
                        "beginAtZero": false,
                        "min": 0.0,
                        "max": "NaN",
                        "stepSize": "NaN",
                        "callback": "fn1arrow"
                    ,
                
            ]
        ,

    
;

function fixCallbacks(obj) 
    const fns = 
        fn1: function(value, index, values)  return Number(value.toString());,
        fn1arrow: (value, index, values) => Number(value.toString()),
    ;
    Object.entries(obj).forEach(([k, v]) => 
        if (typeof v === 'object' || typeof v === 'array') 
            fixCallbacks(v);
         else if (k === 'callback') 
            obj[k] = fns[v] || obj[k];
        
    );


// here we "fix" the data
fixCallbacks(data);
//
console.log(data);

【讨论】:

感谢中间的 Javascript。 @robor78 - 不知道“中间的那个 Javascript”是什么意思 - 这是你需要的代码,sn-p 是为了证明它有效: 我指的是 fixCallbacks。我的 javascript 有点生疏,所以我已经想知道如何在 JSON 对象中找到所有“回调”。您的函数 fixCallbacks 可以做到这一点。谢谢。

以上是关于如何从不带引号的 WebAPI 控制器发送带有 javascript 函数的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

从 XML 转换后,如何在 JSON 中获取不带引号的数值

如何将带有字节数组的 json 发送到 web api / postman

通过 Web API 发送的字符串用引号括起来

未发送从 Angular 到 .Net 5 webapi 的发布参数

TypeScript 自动导入中的 WebStorm/PhpStorm 双引号

Oracle中插入带有带引号的字段数据(解决办法)