angular 4 odata Delete/Post 不工作
angular 4 odata Delete/Post not working
我创建了一个简单的测试 class 用于向 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 上的网络记录,似乎从未发出过删除请求,我是否缺少调用该函数的内容?
我的SOAPUI请求如下:
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)
任何帮助将不胜感激
这最终成为了一个 Header/CORs 问题。
我执行了以下步骤来修复它:
- 在我的请求中添加了以下 Headers:
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 服务器上公开 headers 作为 Chrome 和其他较新的浏览器做一些 "pre-flight" 发送选项请求的东西(了解更多 here)。为此,我在 WebApiConfi.cs 中添加了以下内容:
var cors = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*", exposedHeaders: "*");
config.EnableCors(cors);
这会在所有控制器上启用 CORS,您可以在上面 link 中提到的单个控制器或方法上指定它。
我创建了一个简单的测试 class 用于向 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 上的网络记录,似乎从未发出过删除请求,我是否缺少调用该函数的内容?
我的SOAPUI请求如下:
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)
任何帮助将不胜感激
这最终成为了一个 Header/CORs 问题。 我执行了以下步骤来修复它:
- 在我的请求中添加了以下 Headers:
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 服务器上公开 headers 作为 Chrome 和其他较新的浏览器做一些 "pre-flight" 发送选项请求的东西(了解更多 here)。为此,我在 WebApiConfi.cs 中添加了以下内容:
var cors = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*", exposedHeaders: "*"); config.EnableCors(cors);
这会在所有控制器上启用 CORS,您可以在上面 link 中提到的单个控制器或方法上指定它。