【问题标题】:Calling web api2 from angular 2 with CORS post request使用 CORS 发布请求从角度 2 调用 web api2
【发布时间】:2017-12-05 11:02:06
【问题描述】:

我正在尝试将下面的 api 响应绑定到 html,

   {
  "ScreenData": {
    "ScreeNo": 101,
    "MovieName": "Movie101",
    "SeatRows": [
      {
        "SeatRowNumber": 1,
        "Seats": [
          {
            "SeatRowNo": 1,
            "SeatColumnNo": 1,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 1,
        "Seats": [
          {
            "SeatRowNo": 1,
            "SeatColumnNo": 2,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 1,
        "Seats": [
          {
            "SeatRowNo": 1,
            "SeatColumnNo": 3,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 1,
        "Seats": [
          {
            "SeatRowNo": 1,
            "SeatColumnNo": 4,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 1,
        "Seats": [
          {
            "SeatRowNo": 1,
            "SeatColumnNo": 5,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 2,
        "Seats": [
          {
            "SeatRowNo": 2,
            "SeatColumnNo": 1,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 2,
        "Seats": [
          {
            "SeatRowNo": 2,
            "SeatColumnNo": 2,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 2,
        "Seats": [
          {
            "SeatRowNo": 2,
            "SeatColumnNo": 3,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 2,
        "Seats": [
          {
            "SeatRowNo": 2,
            "SeatColumnNo": 4,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 2,
        "Seats": [
          {
            "SeatRowNo": 2,
            "SeatColumnNo": 5,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 3,
        "Seats": [
          {
            "SeatRowNo": 3,
            "SeatColumnNo": 1,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 3,
        "Seats": [
          {
            "SeatRowNo": 3,
            "SeatColumnNo": 2,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 3,
        "Seats": [
          {
            "SeatRowNo": 3,
            "SeatColumnNo": 3,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 3,
        "Seats": [
          {
            "SeatRowNo": 3,
            "SeatColumnNo": 4,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 3,
        "Seats": [
          {
            "SeatRowNo": 3,
            "SeatColumnNo": 5,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 4,
        "Seats": [
          {
            "SeatRowNo": 4,
            "SeatColumnNo": 1,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 4,
        "Seats": [
          {
            "SeatRowNo": 4,
            "SeatColumnNo": 2,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 4,
        "Seats": [
          {
            "SeatRowNo": 4,
            "SeatColumnNo": 3,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 4,
        "Seats": [
          {
            "SeatRowNo": 4,
            "SeatColumnNo": 4,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      },
      {
        "SeatRowNumber": 4,
        "Seats": [
          {
            "SeatRowNo": 4,
            "SeatColumnNo": 5,
            "Price": 100.0,
            "IsAvailable": true
          }
        ]
      }
    ]
  }
}

HTML代码如下

     <div *ngFor="let seatRow of seatsData?.SeatRows"style="display: block; height: 50px;">
    <span  style="float: left;margin-right: 40px;margin-left: 20px;">{{seatRow?.SeatRowNumber}}o</span>
    <div *ngFor="let seat of seatRow?.Seats" style="width: 10%; float: left">
      <span> <input type="checkbox"  (change)="AddData(Seat,$event)" [disabled]="!seat?.IsAvailable" [checked]="!seat?.IsAvailable"> {{seat?.SeatRowNo}}{{seat?.SeatColumnNo}}  {{seat?.IsAvailable}} </span>
    </div>
</div>

角度组件代码如下

import { Component, OnInit } from '@angular/core'
import { ISeat } from './ISeat';
import { TheatorService } from './theator.service';

@Component({
    selector: 'theator',
    templateUrl: './theator.component.html'
})
export class TheatorComponent implements OnInit {
    seatAggregateData: any[];
    seatsData: any ;

    errorMessage: string;
    constructor(private theatorService: TheatorService) {

    }
    ngOnInit() {

            this.GetScreenDeatails();
    }
    public GetScreenDeatails()
    {
        this.theatorService.getScreenDetailsService(101).subscribe(s => this.seatsData = s.ScreenData, e => this.errorMessage = <any>e);

    }
    public AddData(seatData: ISeat, event: any) {
        if (event.target.checked) {
            this.seatAggregateData.push(seatData)
        }
        else {
            var index = this.seatAggregateData.indexOf(seatData);
            this.seatAggregateData.splice(index, 1);
        }
    }

}

Angular 服务代码如下

import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class TheatorService {
    getScreenDetailsUrl: string = 'http://localhost:17046/api/Theator/GetScreenDetailsInfo'
    constructor(private http: Http) {

    }
    getScreenDetailsService(screenNumber: number): Observable<any>  {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json; charset=utf-8');
        let bodyString = JSON.stringify(screenNumber); // Stringify payload
        return this.http.post(this.getScreenDetailsUrl,bodyString,  { headers: headers })
            .map((res: Response) => res.json())  // ...and calling .json() on the response to return data
            .catch((error: any) => Observable.throw(error.json().error || 'Server error')); //...errors if any;

    }
}

当我调用 web api post 方法时,有两个方法被调用,一个是 OPTIONS,另一个是 post 方法。 在调试时,我知道在调用响应为空的 OPTION 方法时发生了与组件属性 this.seatsData 的数据绑定。默认情况下会调用 OPTION,我们启用 CORS。 因此,我无法绑定数据并出现以下错误,

theator.component.html:2 错误类型错误:无法读取属性 未定义的“SeatRows” 在 Object.eval [as updateDirectives] (theator.component.html:2) 在 Object.debugUpdateDirectives [as updateDirectives] (services.ts:273) 在 checkAndUpdateView (view.ts:345) 在 callViewAction (view.ts:700) 在 execComponentViewsAction (view.ts:644) 在 checkAndUpdateView (view.ts:392) 在 callViewAction (view.ts:700) 在 execComponentViewsAction (view.ts:644) 在 checkAndUpdateView (view.ts:392) 在 callWithDebugContext (services.ts:645)

【问题讨论】:

  • Angular 永远不会从 OPTIONS 请求中获得响应,而 Angular 只会从 POST 请求中获得响应。 OPTIONS 请求由浏览器透明地发出。您的问题的原因在其他地方。
  • 我猜你只需要*ngFor="let seatRow of seatsData?.SeatRows"(添加?
  • 您是否使用 Fiddler/swagger 检查了来自 Web API 的请求和响应?

标签: html angular asp.net-web-api asp.net-web-api2


【解决方案1】:

这应该可以解决您的问题。

*ngFor="let seatRow of seatsData?.SeatRows"

尝试使用safe navigation operator

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2019-07-17
    • 2014-11-09
    相关资源
    最近更新 更多