使用HttpClient和RXJS通过凭据将数据发布到Web API:true

时间:2018-07-24 21:58:36

标签: angular http asp.net-web-api rxjs httpclient

我有一个Angular服务已连接到我的.NET Web API,并且我正在尝试POST将一些数据添加到API。目前,我使用的是HTTP而不是HttpClient,并且我没有发送任何数据。但是该服务已成功连接到API。

在将实际数据从我的Angular控制器传递到服务(进而传递给API)以及在服务中实现HttpClient时,我需要帮助。到目前为止,我的控制器仅调用了服务的myFunction()函数,并且未传递任何参数,因此没有数据。我不确定该服务的RXJS部分中要附加我的数据的地方。

注意:但是,由于我的API的配置,我还是实现了它,但仍需要它传递withCredentials: true

Web API控制器:

namespace api.controllers
{
    [Authorize]
    public class ValuesController : ApiController
     {
        static List<string> strings = new List<string>()
        {
            "value0", "value1", "value2"
        };

        // GET api/values
        public IEnumerable<string> Get()
        {
            return strings;
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        public void Post([FromBody]string value)
        {
            strings.Add(value);
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }

    }
}

Web API web.config文件(CORS设置):

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="http://localhost:5200" />
    <add name="Access-Control-Allow-Headers" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
    <add name="Access-Control-Allow-Credentials" value="true" />
  </customHeaders>
</httpProtocol>


myComponent.component.ts:

  myService: MyService;

  constructor(myService: MyService) {
      this.myService = myService;
      this.myService.myFunction();
   }


myService.service.ts:

import { Injectable } from '@angular/core';
import { Http, Response, Request, Headers } from '@angular/http';
// import { HttpClient, HttpResponse, HttpRequest, HttpHeaders, HttpInterceptor, HttpHandler, HttpEvent } from '@angular/common/http';

import { Observable } from 'rxjs';
import { from } from 'rxjs';
import { map, filter, catchError, mergeMap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})

export class MyService {
  http: Http;

  constructor(http: Http) {
    this.http = http;
  };

  public myFunction() {
    let request = new Request({
      method: "POST",
      url: "http://localhost:9090/api/values",
      withCredentials: true
    });

    return this.http.request(request)
      .pipe(map(res => res.json()))
      .subscribe(
        data => console.warn(data),
        err => console.error(err),
        () => console.log("empty")
      );
  }
}


如何从控制器向该服务添加一些实际数据?我如何调整服务以改为使用HttpClient?我尝试将所有http: Http的引用更改为HttpClient,完成所有HttpClient的导入并注释掉.map/json portions,但是在{{1这样做时,请在服务的request行中添加}}参数。

3 个答案:

答案 0 :(得分:4)

我使用这个概念,希望它也能与您一起解决。

为您的数据创建属性类(将其与.net API上的类进行匹配),这也可以轻松处理数据 型号

export class MyData
{
 username:string;
 password:string;
 isAuthenticated:boolean;
}

服务

import { Http, Response, Request, Headers } from '@angular/http';

export class MyService {     

  constructor(private http: Http) {}

public myFunction(body:MyData) {
 let url = 'http://localhost:9090/api/values'
    return this.http.post(url,body)
      .pipe(map(res => res.json()))          
  }
}

TS

returnValue:any;
myData:MyData;
constructor(private service:MyService){
this.myData = new MyData();
}
myFunction()
{
 this.myData.username = 'anything';
 this.myData.password = 'mypw';
 this.myData.isAuthenticated = true;

 this.returnValue = this.service.myFunction(this.myData)
 .subscribe(res=>{console.log(res)})
}

.NET API

[HttpPost]
public void MYAPI([FromBody]MyData model)
{

    string uname = model.username;
    string pw = model.password;
}

答案 1 :(得分:1)

要使用HttpClient,您必须以HttpClientModule的{​​{1}}身份导入app.module.ts并开始以HttpModule的身份注入HttpClient对象

http
  

使用HttpClient时,无需执行@Injectable({ providedIn: 'root' }) export class MyService { constructor(private http: HttpClient) { }; public myFunction(body) { let requestOptions = { withCredentials : true }; return this.http.post("http://localhost:9090/api/values",body,requestOptions); } }

组件

.map(res => res.json())
  

通常您不需要从服务中进行订阅,即可获得   数据到组件

ngOnInit

  

通常,您必须在中执行初始api请求   ngOninit方法

complete guide about httpRequestOptions

最后这是打字稿提示

这是简写语法

 constructor(myService: MyService) {
      this.myService = myService;
      this.myService.myFunction({username:'test',password:'123465'})
      .subscribe(data => console.warn(data), err => console.error(err),() => console.log("empty")
      );
   }

对此

 constructor(private http: HttpClient) {
  };

答案 2 :(得分:1)

除了服务之外,您的代码似乎还不错。 另外,我还看到您的API具有[Authorize]。您需要通过授权

例如:

const httpOptions = {
 headers: new HttpHeaders({
  'Authorization': myToken
 }),
 withCredentials: true
};

在您的Http请求上,这样您就不会收到需要授权的错误。

此参考可能有用:https://angular.io/guide/security

使用HttpClient的服务:

 import { Injectable } from '@angular/core';
 import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { Observable } from 'rxjs';

 // api path
 const API_URL = 'http://10.111.1.23:80/api/my_api/api/yourController';

 // add http headers.
 const httpOptions = {
    headers: new HttpHeaders({
    'Content-Type': 'application/json'
   })
  };

 @Injectable()
 export class MyService {

 // inject the Http Client to the constructor
 constructor(private _http: HttpClient) { };

 myFunction(entity: any): Observable<yourModel> {
    // using http client the return value of you api is
    // directly map to your model
    return this._http.post<yourModel>(API_URL ,
      entity, httpOptions);
 );
}