如何从不带引号的 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的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有字节数组的 json 发送到 web api / postman
未发送从 Angular 到 .Net 5 webapi 的发布参数