web-dev-qa-db-ja.com

Angular2 HTTP Post ASP.NET MVC Web API

Angular2を使用して複雑なオブジェクトまたは複数のパラメーターのWebAPI 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);
}
_

ターゲットとするWebAPIを以下に示します。

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

Web APIのパラメーターをEメールとパスワードのプロパティを持つ単一のPOCOクラスエンティティに変換し、[FromBody]属性を配置する必要があるため、これは機能しません:Signin([FromBody] Credential credential)

_[FromURI]_(クエリ文字列を含むPOSTリクエスト?)を使用せずに、これらのパラメーターを単一のPOCOクラスに変換せずに、複数のパラメーターまたは複雑なオブジェクトのPOSTを作成するにはどうすればよいですか?

_(string sensitiveInfo1, string name, int sensitiveInfo2)_や_(ClassifiedInfo info, string sensitiveInfo1, string sensitiveInfo2)_などのパラメーターを持つ多数のWeb API POSTアクションがある場合、それらすべてをPOCOクラスに変換し、常に[FromBody]を使用する必要があるためです。 ?

PS。以前はRestangularJSを使用していましたが、_[FromBody]_属性を持つWeb APIアクションがなくても、何でも(複数のプリミティブオブジェクトと複雑なオブジェクト)投稿できます。 RestangularJSがそれをどのように行うかを調査しようとしています。

11
raberana

[FromURI](クエリ文字列を含むPOSTリクエスト?)を使用せずに、複数のパラメーターまたは複雑なオブジェクトを単一のPOCOクラスに変換せずにPOSTを作成するにはどうすればよいですか?

私はあなたが聞きたいことではないことを知っていますが、箱から出してこれは不可能です。リクエストを行っているのはブラウザコードの制限ではありません。つまり、Angular、JQuery、ストレートJavaScript、さらにはRestangularJSを使用しているかどうかは関係ありません。これは、Web API(任意のバージョン)の制限(これは設計によるものであると確信しているため)、そのWordを大まかに使用します。この設計に関するドキュメントは次のとおりです。 ASP.NET Web APIでのパラメーターバインディング by MikeWasson。

メッセージ本文からの読み取りは、最大で1つのパラメーターに許可されます。したがって、これは機能しません。

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

だから問題は、あなたの選択肢は何ですか?

モデルを作成する

これはあなたが避けようとしていたことですが、これが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)
{
       // ....
}

上記のWeb APIコードと同じように機能するため、既存のJavaScriptコードを繰り返しませんでした

URL

繰り返しますが、あなたが避けようとしていたこと。これにより、URLのクエリ文字列を使用してこれらのパラメータを渡す必要があるという制限がありますが、必要なことが可能になります。 JavaScriptは変更されますが、WebAPIメソッドにある署名は変更されません。

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

上記のWeb JavaScriptコードでそのまま機能するため、既存のWeb APIコードを繰り返しませんでした(デフォルトでは、FromUriが想定されています)

カスタムモデルバインダー

複数のPOSTパラメーターをWebAPIコントローラーメソッドに渡す by Rick Strahlを参照してください。このオプションを使用すると、要求していることを実行できるカスタムモデルバインダーを作成できます。 IMHOにとっては、余分なコードがたくさんありますが、あまりメリットはありません。頭から離れて考えることはできませんが、役立つ場合もあるかもしれません。

動的

最後に、WebAPIのパラメーターとしてdynamicオブジェクトを渡すこともできます。これは基本的に、JSONを文字列として受け取り、コントローラーコードにコンテンツの逆シリアル化を担当させることと同じです。繰り返しますが、カスタム検証と型チェックを実装する必要があるため、ほとんどの状況でコードが悪化すると思います。この答えは提案されました 以前はSO by Bes Ley 。繰り返しになりますが、私は本当に何も考えられませんが、それが役立つ状況があるかもしれません。頭。

11
Igor

Angular 2タイプのスクリプトからWebAPI 2.2 postメソッドを呼び出す場合は、次のヘッダーコンテンツとパラメーターオブジェクトを追加することを忘れないでください。

let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' }); 
 var params = new URLSearchParams();
        params.set('userid', '102');
        params.set('username', 'foo');

 return this._http.post('http://localhost:6579/api/PostUser', params.toString(), { headers: headers }).map(res => res.json());
4

おそらくあなたはオプションで投稿する必要があります:

{ 
   headers: new Headers({
   'Content-Type': 'application/x-www-form-urlencoded'
   })
}

次のようなデータをエンコードします

jQuery.param({user:'bla', password: 'bla'});
2
kemsky

WebAPIはこれをそのままでは提供しません。 Web APIバインディングを理解しようとすると、その理由を理解できる可能性があります。

この記事 が役立つかもしれないと思います。

一般的なルールは次のとおりです。

–単純な文字列変換可能なパラメーター(値タイプ、文字列、GUID、DateTimesなど)は、デフォルトでURIから読み取られます

–複合型は、デフォルトで本体から読み取られます

–単純なパラメーターのコレクションは、デフォルトで本体からも読み取られます

–URIとリクエスト本文の両方からの入力に基づいて単一のモデルを作成することはできません。どちらか一方である必要があります

2
Guanxi

Angular2 HTTP Post ASP.NET MVC WebAPIの問題を修正しました

let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
let params: URLSearchParams = new URLSearchParams();
params.set('value', '2');

let options = new RequestOptions({
    headers: headers//,
    //search: params
});
let content = new URLSearchParams();
content.set('StudentName', 'Inderjit Singh';
content.set('Mobile', '+919041165398');            
content.set('Nationality', 'Indian');
content.set('AdmissionNo', '6');
content.set('SectionCode', '1');
content.set('Gender', 'Male');
content.set('RegNo', '18585');
content.set('ClassCode', '1');
this.http.post('YOUR_URL', content.toString(), { headers: headers }).map((res: Response) => { console.log("data is==>" + res.text()); }).subscribe();
1
InderMoga

複雑なクラスオブジェクトを単一のデータパラメータに渡して、これを試してください。

var SearchQuery = function () {
    this.Alphabet = null;
    this.Search = false;
    this.Keyword = null;
    this.RegionList = null;
};
var para = new SearchQuery();
{ data: JSON.stringify(para) } - Post Data

aPIコントローラーのJObjectを使用して受信し、クラスに従って逆シリアル化できます。

0
Vivek Singh

JSONオブジェクトのフィールド名が同じであれば、WebApiはCredentialオブジェクトを逆シリアル化できます(大文字と小文字はわかりませんので、ここにいる可能性があります)。 Angular2コンポーネントのポストコールからヘッダーが欠落しているようです。

Chrome DebuggerまたはFiddlerを使用してContent-Typeを確認できますか?application/jsonである必要があります。

0
KnowHoper