Angular2 HTTP Post ASP.NET MVC Web API

rab*_*ana 11 asp.net asp.net-web-api restangular asp.net-web-api2 angular

如何使用Angular2正确创建复杂对象或多个参数的Web API POST?

我在Angular2中有一个服务组件,如下所示:

public signin(inputEmail: string, inputPassword: string): Observable<Response> {
    return this.http.post('/api/account/signin', JSON.stringify({ Email: inputEmail, Password: inputPassword}), this.options);
}
Run Code Online (Sandbox Code Playgroud)

目标web api如下所示:

[HttpPost]
[Route("signin")]
public async Task<IActionResult> Signin(string email, string password)
{
       ....
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为我需要将web api的参数转换为具有Email和Password属性的单个POCO类实体,并放置[FromBody]属性: Signin([FromBody] Credential credential)

如果不使用[FromURI](带有查询字符串的POST请求?),如何在不将这些参数转换为单个POCO类的情况下对多个参数或复杂对象进行POST?

因为如果我有许多带有参数的Web API POST操作,(string sensitiveInfo1, string name, int sensitiveInfo2)或者(ClassifiedInfo info, string sensitiveInfo1, string sensitiveInfo2),我是否需要将它们全部转换为POCO类并始终使用[FromBody]?

PS.我以前使用RestangularJS它,它可以发布任何东西(多个原始对象和复杂对象),而我的Web API操作没有[FromBody]属性.将研究RestangularJS如何做到这一点.

Igo*_*gor 11

如果不使用[FromURI](带有查询字符串的POST请求?),如何在不将这些参数转换为单个POCO类的情况下进行多个参数或复杂对象的POST?

我知道它不是你想听到的,但开箱即用这是不可能的.它不是发出请求的浏览器代码的限制.这意味着你使用Angular,JQuery,直接JavaScript,甚至是RestangularJS并不重要.这是Web API(任何版本)的一个限制(我使用这个词,因为我确信这是设计).以下是有关此设计的文档:Mike Wasson 在ASP.NET Web API中参数绑定.

最多允许一个参数从消息正文中读取.所以这不起作用:

// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Run Code Online (Sandbox Code Playgroud)

所以问题就变成了,你有什么选择?

创建一个模型

这是你试图避免的事情,但我首先列出它,因为这是Web API的行为方式.我还没有听到一个令人信服的理由不这样做.此方法允许您轻松扩展模型,而无需更改方法签名.它还允许对模型本身进行模型验证.我个人非常喜欢这种方法.

public class SignInModel{
    public string Email {get;set;}
    public string Password {get;set;}
}

[HttpPost]
[Route("signin")]
public async Task<IActionResult> Signin(SignInModel signInModel)
{
       // ....
}
Run Code Online (Sandbox Code Playgroud)

我没有重复你现有的JavaScript代码,因为你的工作原理与上面的web api代码一样

网址

再一次,你试图避免的.这确实可以实现您想要的限制,您必须使用URL上的查询字符串传递这些参数.JavaScript会改变,但您在Web API方法上的签名不会.

public signin(inputEmail: string, inputPassword: string): Observable<Response> {
    return this.http.post('/api/account/signin/?email=inputEmail&password=inputPassword', null, this.options);
}
Run Code Online (Sandbox Code Playgroud)

我没有重复您现有的Web API代码,因为您使用的是上述Web JavaScript代码(默认情况下,我相信FromUri)

自定义模型粘合剂

请参阅Rick Strahl 将多个POST参数传递给Web API控制器方法.此选项允许您创建可以执行您要求的自定义模型绑定器.这是一大堆额外的代码虽然,恕我直言,没有太大的好处.也许在某些情况下它会有用,虽然我真的想不出任何偏离我的头脑.

动态

最后,您还可以传入一个dynamic对象作为Web API的参数.这与将JSON作为字符串接收并使Controller代码负责内容的反序列化基本相同.同样,我认为这会使您的代码在大多数情况下变得更糟,因为您必须实现自定义验证和类型检查.这个答案之前是由Bes Ley提出的.同样,也许有些情况会有用,虽然我真的想不到任何偏离我的头脑.


Kno*_*per 0

如果 JSON 对象具有相同的字段名称,WebApi 将能够反序列化您的 Credential 对象(我不确定大小写,所以您可能就在这里)。您似乎缺少 Angular2 组件中 post 调用的标头。

您可以使用 Chrome 调试器或 Fiddler 检查 Content-Type 吗?它应该是 application/json。