将正文中的字符串作为POST REST调用发送(javascript到Asp.Net Core)



我有一个用Asp.Net Core编写的简单后端API,它接收一个字符串:

[HttpPost]
public IResult Post([FromBody] string value)
{
//do something with value...
}

我的前端javascript看起来是这样的:

const request = {
method: 'POST',
mode : "cors",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, currency })
};
const response = await fetch(link, request);
const data = await response.json();

这似乎很容易,但我得到了以下错误:
"分析值时遇到意外字符:{.Path'',第1行,位置1。">
"值字段是必需的。">

问题出在正文中,它作为JSON对象发送:
{"amount":123,"currency":"eur"}

显然,解析会产生问题
如果使用Postman,我在正文内发送以下字符串:
"{\"amount \":123,\"currency \":\"eur\"}">

一切正常!

如果我通过javascript发送,它不会:(

所以,我的问题是:很明显,c#扰乱了主体中的数据类型。它期望一个字符串,但它正在接收一个JSON(尽管JSON.stringfy生成了一个字符串但不知何故,它似乎被解析回了介于两者之间的JSON(。

我能把C#上的类型改成JSON之类的吗?一切都会自动工作吗?有没有一种方法可以通过javascript发送一个看起来像JSON的字符串,而不需要在两者之间进行这种不必要的转换?


附加信息:

@Strike轻柔的方式不起作用。我收到一条错误消息,说只有一个参数可以与[FromBody]属性一起传递。

@joacoleza方式可能有效,但我希望避免它,因为它会在我的代码中填充数十个描述函数输入的小类。

这是有效的。但我的眼睛流血了:

body:"'" + JSON.stringify({amount, currency}) + "'"

这是传递字符串的最优雅的解决方案吗?

它期望value有一个string,但您给了它一个对象。可以更改方法的参数以接受具有amountcurrency属性的对象,也可以更改方法参数以接受两个同名变量。

[HttpPost]
public IResult Post([FromBody] int amount, [FromBody] string currency)
{
//do something
}

尽管@joacoleza的答案确实有效,但在我的一个案例中它是不可行的(我收到的对象很大(约200个字段(,我只需要提取5个。此外,它可能会经常变化,即使我并没有真正被这些变化所打动,我也必须调整我的对象。

我终于自己找到了解决方案:

如前所述,.Net试图将正文的内容解析为请求的对象:

public ActionResult Post([FromBody] string value)

这需要一个字符串对象。如果我们想发送JSON并解析它,我们可以通过以下方式发送:'{"field":"value", "field2":"value2"}'

但是,如果我们不控制请求中主体的内容,并且我们正在接收一个X对象(或者我们可能想在运行时解析的不同对象(,我们只需要将函数参数的类型更改为JObject:

public ActionResult Post([FromBody] JObject value)

解析后的JObject将包含JSON的整个结构,但它仍然会给我们足够的自由,让我们对原始版本为所欲为,而不必为了转换而将其转换为POCO:var amount = value["amount"];

这就是我想要的。

试着这样做。

发送这样的请求:

const request = {
method: 'POST',
mode : "cors",
headers: { 'Content-Type': 'application/json' },
body: { amount: 100, currency: 'USD' })
};
const response = await fetch(link, request);
const data = await response.json();

并定义一个可以绑定到您发送的主体的类:

public class MyClass
{
public int Amount { get; set; }
public string Currency  { get; set; }
}

并使用该类作为POST方法的参数:

[HttpPost]
public IResult Post([FromBody] MyClass data)
{
//do something with value...
}

最新更新