我创建了一个简单的测试类,用于向OData API发出我的http请求(两者都在我的本地机器上运行,并启用了COR)。我的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);
}
}
忽略Put和Patch,因为它们尚未实现,唯一可行的服务是GET。 POST和DELETE似乎根本不起作用;调用DELETE http://localhost:53219/Template(6)应删除ID为6的模板,该模板在使用SOAP UI完成时有效,但不使用第一个代码片段中定义的this.http.delete(...)函数。
此外,查看Chrome上的网络录音,看起来不像删除请求,我错过了调用该功能的内容吗?
我的SOAP UI请求如下:
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 :(得分:0)
这最终成为了一个Header / CORs问题。 我做了以下步骤来修复它:
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;
var cors = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*", exposedHeaders: "*"); config.EnableCors(cors);
这会在所有控制器上启用CORS,您可以在上面的链接中提到的各个控制器或方法上指定它。