簡體   English   中英

Angular2 HTTP Post ASP.NET MVC Web API

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

如何使用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);
}

目標Web API如下所示:

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

這不起作用,因為我需要將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如何做到這一點。

不使用[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) { ... } 

因此,問題就變成了,您有什么選擇?

建立模型

這是您想要避免的事情,但我首先列出了它,因為這是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)
{
       // ....
}

我沒有重復您現有的JavaScript代碼,因為您使用的代碼與上述網絡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);
}

我沒有重復您現有的Web API代碼,因為您使用的內容與上述Web JavaScript代碼一樣(默認情況下,我認為FromUri是假定的)

定制模型活頁夾

請參閱Rick Strahl的將多個POST參數傳遞給Web API控制器方法 使用此選項,您可以創建可以執行您所要求的自定義模型活頁夾。 盡管這是一大堆額外的代碼,但是恕我直言,並沒有太大的好處。 也許在某些情況下它會很有用,盡管我真的無法想到任何事情。

動態

最后,您還可以傳入dynamic對象作為Web API的參數。 這本質上與以字符串形式接收JSON並使控制器代碼負責反序列化內容相同。 同樣,我認為這將使您的代碼在大多數情況下變得更糟,因為您必須實施自定義驗證和類型檢查。 此答案先前由Bes Ley在SO上提出。 再說一次,也許在某些情況下它會很有用,盡管我真的想不起任何事情。

如果您從Angular 2類型腳本調用Web API 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());

也許您應該張貼選項:

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

並像這樣編碼數據

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

WebAPI不提供此功能。 如果您嘗試了解Web API綁定,則可以找出原因。

我認為這篇文章可能會有所幫助。

通用規則是:

–默認情況下,簡單的,可字符串轉換的參數(值類型,字符串,Guid,DateTimes等)是從URI中讀取的

–默認情況下,從主體讀取復雜類型

–默認情況下,也從主體讀取簡單參數的集合

–您不能基於URI和請求正文的輸入來組合一個模型,它必須是一個模型或另一個模型

我已經解決了Angular2 HTTP Post ASP.NET MVC Web API的問題

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();

如果JSON對象具有相同的字段名,WebApi將能夠反序列化您的Credential對象(我不確定大小寫,因此您可能就在這里)。 您似乎在Angular2組件的post調用中缺少標題。

您可以使用Chrome調試器或Fiddler檢查Content-Type嗎? 它應該是application / json。

嘗試將復雜的類對象傳遞到單個數據參數中。

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接收它,並根據您的類對其進行反序列化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM