2017-06-29 57 views
2

我已經創建了一個簡單的測試類,用於將我的http請求發送到OData API(均在本地計算機上運行,​​啓用CORs)。我的OData服務看起來像這樣:angular 4 odata刪除/發佈不工作

import { Injectable } from '@angular/core'; 

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

import { Observable } from 'rxjs'; 
import 'rxjs/add/operator/map'; 

import { IUrlOptions } from './odata.model'; 
import { RequestTypes } from './odata.model'; 

@Injectable() 
export class ODataService { 

    constructor(
     private host: string, 
     private http: Http 
    ) { } 


    private constructUrl(urlOptions: IUrlOptions): string { 
     return this.host + urlOptions.restOfUrl; 
    } 



    //T specifies a generic output of function 
    public Request<T>(requestType: RequestTypes, urlOptions: IUrlOptions, body?: any, options?: RequestOptionsArgs) : Observable<T> { 
     let response: Observable<Response>; 

     if(requestType == RequestTypes.delete){ 
      response = this.http.delete(this.constructUrl(urlOptions), options); 
     } else if(requestType == RequestTypes.get){ 

      response = this.http.get(this.constructUrl(urlOptions), options); 
     } else if (requestType == RequestTypes.post){ 
      response = this.http.post(this.constructUrl(urlOptions), body, options) 
     } 

     return response.map((res) => <T>res.json()); 
    } 
} 

現在我有一個組件來測試這一服務:

import { Component, OnInit } from '@angular/core'; 

import { ODataService } from './odata.service'; 
import { RequestTypes } from './odata.model'; 
import { IUrlOptions } from './odata.model'; 

import { Template } from '../../models/template.model' 

@Component({ 
    selector: 'odata', 
    templateUrl: 'odata.component.html' 
}) 
export class ODataComponent implements OnInit { 


    public requestResult: any; 

    constructor(
     private odata: ODataService 
    ) { } 

    ngOnInit() { } 

    testGet() { 
     let urlOptions: IUrlOptions = <IUrlOptions>{}; 
     urlOptions.restOfUrl = "Template"; 
     this.odata.Request(RequestTypes.get, urlOptions).subscribe(
      data => this.requestResult = data, 
      error => alert(error) 
     ); 
    } 

    testPost() { 
     let urlOptions: IUrlOptions = <IUrlOptions>{}; 
     urlOptions.restOfUrl = "Template"; 
     let body = new Template(); 
     body.Name = "Test3"; 
     body.Private = false; 
     body.User = "chp"; 

     let jsonBody = JSON.stringify(body); 

     this.odata.Request(RequestTypes.post, urlOptions, jsonBody).subscribe(
      data => this.requestResult = data, 
      error => alert(error) 
     ); 
    } 

    testPut() { 
     let urlOptions: IUrlOptions = <IUrlOptions>{}; 
     this.odata.Request(RequestTypes.put, urlOptions).subscribe(
      data => this.requestResult = data, 
      error => alert(error) 
     ); 
    } 

    testPatch() { 
     let urlOptions: IUrlOptions = <IUrlOptions>{}; 
     this.odata.Request(RequestTypes.patch, urlOptions).subscribe(
      data => this.requestResult = data, 
      error => alert(error) 
     ); 
    } 

    testDelete() { 
     let urlOptions: IUrlOptions = <IUrlOptions>{}; 
     urlOptions.restOfUrl = "Template(6)" 
     this.requestResult = this.odata.Request(RequestTypes.delete, urlOptions); 
    } 

} 

忽略認沽和修補程序,因爲他們都沒有得到執行,似乎工作是唯一的服務得到。 POST和DELETE似乎根本不起作用;調用DELETE http://localhost:53219/Template(6)應刪除ID爲6的模板,該模板在使用SOAP UI完成時工作,但不使用第一個代碼段中定義的this.http.delete(...)函數。

此外,在chrome上查看網絡記錄時,它看起來不像是一個刪除請求,我是否錯過了調用該函數的東西?

我的SOAP請求的用戶界面如下:

DELETE http://localhost:53219/Template(6) HTTP/1.1 
Accept-Encoding: gzip,deflate 
Content-Type: application/json 
Content-Length: 83 
Host: localhost:53219 
Connection: Keep-Alive 
User-Agent: Apache-HttpClient/4.1.1 (java 1.5) 

任何幫助,將不勝感激

回答

0

這最終是一個頁眉/ CORS問題。 我做了以下措施來解決這個問題:

  1. 添加以下標題到我的請求:
let headers = new Headers(); 
headers.append("OData-Version","4.0"); 
headers.append("Content-Type","application/json;odata.metadata=minimal"); 
headers.append("Accept","application/json"); 
return headers; 
  • 那我也只好在我的OData API服務器上公開標題,因爲Chrome和其他較新的瀏覽器會執行一些發佈OPTIONS請求的「預發佈」內容(瞭解更多信息here)。要做到這一點,我添加在我WebApiConfi.cs如下:
  • var cors = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*", exposedHeaders: "*"); 
          config.EnableCors(cors); 
    

    這使CORS上的所有控制器,你可以在單獨的控制器或方法將其指定爲在上面的鏈接中提到。