Angular2 HTTP Post ASP.NET MVC Web API [英] Angular2 HTTP Post ASP.NET MVC Web API

查看:105
本文介绍了Angular2 HTTP Post ASP.NET MVC Web API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How do you properly create a Web API POST of complex object or multiple parameters using Angular2?

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

I have a service component in Angular2 as seen below:

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

目标Web API如下所示:

The targeted web api is seen below:

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

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

This does not work because I need to convert the parameters of the web api into a single POCO class entity with Email and Password properties and put the [FromBody] attribute: Signin([FromBody] Credential credential)

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

Without using [FromURI] (POST requests with query strings?), how can I make POSTs of multiple parameters or complex objects without converting these parameters into a single POCO class?

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

Because what if I have numerous Web API POST actions with parameters like (string sensitiveInfo1, string name, int sensitiveInfo2) or (ClassifiedInfo info, string sensitiveInfo1, string sensitiveInfo2), do I need to convert them all to POCO classes and always use [FromBody]?

PS. 我以前使用过RestangularJS,它可以发布任何内容(多个基本对象和复杂对象),而我的Web API操作没有[FromBody]属性.将要研究RestangularJS的工作方式.

PS. I was using RestangularJS before and it can posts anything (mulitple primitive objects and complex objects) without my Web API actions having [FromBody] attributes. Will about to investigate how RestangularJS do it.

推荐答案

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

Without using [FromURI] (POST requests with query strings?), how can I make POSTs of multiple parameters or complex objects without converting these parameters into a single POCO class?

我知道这不是您想听到的,但开箱即用是不可能的.发出请求的浏览器代码不受限制.这意味着无论您使用的是Angular,JQuery,纯JavaScript还是RestangularJS.这是Web API(任何版本)的局限性(我会宽松地使用该词,因为我确信这是设计使然).这是有关此设计的文档: ASP.NET Web API中的参数绑定,作者是Mike Wasson.

I know its not what you want to hear but out of the box this is not possible. It is not a limitation of the browser code that is making the request. This means it does not matter if you are using Angular, JQuery, straight JavaScript, or even RestangularJS. This is a limitation (I use that word loosely as I am sure this is by design) of Web API (any version). Here is the documentation on this design: Parameter Binding in ASP.NET Web API by Mike Wasson.

最多允许从邮件正文中读取一个参数.所以这行不通:

At most one parameter is allowed to read from the message body. So this will not work:

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

问题就变成了,您有什么选择?

So the question becomes, what are your options?

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

This is the thing you were trying to avoid but I list it first because this is how Web API was intended to behave. I have not yet heard a compelling reason not to do this. This approach allows you to extend your model easily without having to change the method signature. It also allows for model validation on the model itself. Personally I really like this approach.

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

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

我没有重复您现有的JavaScript代码,因为您的工作原理与上述网络api代码一样

再次,您要避免的事情.这确实使您能够实现所需的限制,因为您必须使用URL上的查询字符串来传递这些参数. JavaScript会更改,但您在Web API方法上拥有的签名不会更改.

Again, what you were trying to avoid. This does make what you want possible with the limitation that you have to pass these parameters using the Query string on the URL. The JavaScript would change but the signature you had on the Web API method would not.

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

我没有重复您现有的Web API代码,因为您的工作原理与上述Web JavaScript代码相同(默认情况下,我认为FromUri是假定的)

请参见

See Passing multiple POST parameters to Web API Controller Methods by Rick Strahl. This option allows you to create a custom model binder that could do what you are asking. It is a whole bunch of extra code though for, IMHO, not much benefit. Maybe there are situations where it would be useful although I really cannot think of any off the top of my head.

最后,您还可以传入dynamic对象作为Web API的参数.这本质上与以字符串形式接收JSON并使您的Controller代码负责内容的反序列化相同.同样,我认为这将使您的代码在大多数情况下变得更糟,因为您必须实施自定义验证和类型检查.此答案是先前由Bes Ley在SO上提出的.再说一次,也许在某些情况下它会很有用,尽管我真的想不起任何事情.

Finally you could also pass in a dynamic object as the parameter of your Web API. This is essentially the same as receiving the JSON as a string and making your Controller code responsible for the deserialization of content. Again, I believe that this would make your code worse in most situations as you have to implement custom validation and type checks. This answer was proposed previously on SO by Bes Ley. Again, maybe there are situations where it would be useful although I really cannot think of any off the top of my head.

这篇关于Angular2 HTTP Post ASP.NET MVC Web API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆