从 AngularJS 内容类型问题发布到 WCF 服务
Posting to WCF service from AngularJS Content-type issue
首先,对于这篇文章的篇幅,我深表歉意,但我想包含尽可能多的信息。我正在编写我的第一个 typescript/angular 应用程序并尝试调用我们现有的 IIS WCF 服务。这些调用是跨域的。感谢您的任何输入。
服务合同:
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "LoginUser",
BodyStyle = WebMessageBodyStyle.Wrapped)]
LoginResponse LoginUser(LoginRequest request);
TypeScript 请求:
class LoginRequest implements ILoginRequest {
UserName: string;
Password: string;
ReturnListOfQueues: boolean;
}
Angular/Typescript登录方式:
loginUser(UserName: string,
Password: string,
DomainName: string,
ReturnListOfQueues: boolean): ng.IPromise<ILoginResponse> {
var base_url = 'http://[IP]/AuthenticationService.svc/rest/LoginUser';
var request = new LoginRequest();
request.UserName = UserName;
request.Password = Password;
request.ReturnListOfQueues = ReturnListOfQueues;
var req = {
method: 'POST',
url: base_url,
headers: { 'Content-Type': undefined },
data: JSON.stringify({ request: request }),
contentType: "application/json",
dataType: "json",
}
return this.$http(req)
.then((response: ng.IHttpPromiseCallbackArg<ILoginResponse>): ILoginResponse=> {
return <ILoginResponse>response.data;
});
}
当我用 headers: { 'Content-Type': undefined }
调用它时,JSON 出现在 Fiddler 中,但 Content-Type 是“text/plan”,我得到一个 400 请求错误
我还不能 post 图片所以这里是一个 link to fiddler screencap
https://goo.gl/photos/m75uzHi3E9KdkZhw5
如果我在 Fiddler 中 edit/reissue 请求并将 Content-Type 更改为 application/json,则服务调用成功并且我得到预期的响应数据。
当我将请求更改为使用 application/json 时,数据不再显示在 Fiddler 中
var req = {
method: 'POST',
url: base_url,
headers: { 'Content-Type': "application/json" },
data: JSON.stringify({ request: request }),
contentType: "application/json",
dataType: "json",
}
Fiddler 屏幕截图2:
https://goo.gl/photos/VeJd9HSX46svA1HZ6
设置内容类型时,我还在 Firefox 中收到 CORS 消息
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at [removed]. (Reason: CORS preflight channel did not succeed).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at [removed]. (Reason: CORS request failed).
web.config 进入服务
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
<add name="Access-Control-Max-Age" value="1728000" />
</customHeaders>
</httpProtocol>
<behavior name="restBehavior">
<webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="false" />
</behavior>
更新:
我跟着这个 post blogs.microsoft.co.il/idof/2011/07/02/cross-origin-resource-sharing-cors-and-wcf/
现在,当我使用 headers: { 'Content-Type': "application/json" }
发送请求时,我不再收到 405 错误。它发送 returns 200 OK 的 OPTIONS 请求,但从未发出 POST 请求。
会不会是 JSON.stringify
产生了一些无效的 JSON,因此您发布了无效的 JSON 数据?
如果我尝试反序列化您的第一张图片中包含的请求正文,我会收到以下错误:
Error parsing boolean value. Path 'request.ReturnListOfQueues', line 1, position 80.
我使用了以下代码:
JsonConvert.DeserializeObject("{\"request\": {\"UserName\": \"admin\", \"Password\": \"admin\",\"ReturnListOfQueues\":false\"}}");
如果我将其更改为:
JsonConvert.DeserializeObject("{\"request\": {\"UserName\": \"admin\", \"Password\": \"admin\",\"ReturnListOfQueues\":\"false\"}}");
它工作正常。 (在 false 之前添加了一个额外的双引号。)
我在 chrome 中试用了该应用程序并获得了以下 The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed
我从 web.config 中删除了这一部分,现在可以使用了。 Angular 在飞行前的 OPTIONS 调用
之后进行后续操作 POST
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
<add name="Access-Control-Max-Age" value="1728000" />
</customHeaders>
</httpProtocol>
首先,对于这篇文章的篇幅,我深表歉意,但我想包含尽可能多的信息。我正在编写我的第一个 typescript/angular 应用程序并尝试调用我们现有的 IIS WCF 服务。这些调用是跨域的。感谢您的任何输入。
服务合同:
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "LoginUser",
BodyStyle = WebMessageBodyStyle.Wrapped)]
LoginResponse LoginUser(LoginRequest request);
TypeScript 请求:
class LoginRequest implements ILoginRequest {
UserName: string;
Password: string;
ReturnListOfQueues: boolean;
}
Angular/Typescript登录方式:
loginUser(UserName: string,
Password: string,
DomainName: string,
ReturnListOfQueues: boolean): ng.IPromise<ILoginResponse> {
var base_url = 'http://[IP]/AuthenticationService.svc/rest/LoginUser';
var request = new LoginRequest();
request.UserName = UserName;
request.Password = Password;
request.ReturnListOfQueues = ReturnListOfQueues;
var req = {
method: 'POST',
url: base_url,
headers: { 'Content-Type': undefined },
data: JSON.stringify({ request: request }),
contentType: "application/json",
dataType: "json",
}
return this.$http(req)
.then((response: ng.IHttpPromiseCallbackArg<ILoginResponse>): ILoginResponse=> {
return <ILoginResponse>response.data;
});
}
当我用 headers: { 'Content-Type': undefined }
调用它时,JSON 出现在 Fiddler 中,但 Content-Type 是“text/plan”,我得到一个 400 请求错误
我还不能 post 图片所以这里是一个 link to fiddler screencap https://goo.gl/photos/m75uzHi3E9KdkZhw5
如果我在 Fiddler 中 edit/reissue 请求并将 Content-Type 更改为 application/json,则服务调用成功并且我得到预期的响应数据。
当我将请求更改为使用 application/json 时,数据不再显示在 Fiddler 中
var req = {
method: 'POST',
url: base_url,
headers: { 'Content-Type': "application/json" },
data: JSON.stringify({ request: request }),
contentType: "application/json",
dataType: "json",
}
Fiddler 屏幕截图2: https://goo.gl/photos/VeJd9HSX46svA1HZ6
设置内容类型时,我还在 Firefox 中收到 CORS 消息
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at [removed]. (Reason: CORS preflight channel did not succeed).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at [removed]. (Reason: CORS request failed).
web.config 进入服务
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
<add name="Access-Control-Max-Age" value="1728000" />
</customHeaders>
</httpProtocol>
<behavior name="restBehavior">
<webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="false" />
</behavior>
更新: 我跟着这个 post blogs.microsoft.co.il/idof/2011/07/02/cross-origin-resource-sharing-cors-and-wcf/
现在,当我使用 headers: { 'Content-Type': "application/json" }
发送请求时,我不再收到 405 错误。它发送 returns 200 OK 的 OPTIONS 请求,但从未发出 POST 请求。
会不会是 JSON.stringify
产生了一些无效的 JSON,因此您发布了无效的 JSON 数据?
如果我尝试反序列化您的第一张图片中包含的请求正文,我会收到以下错误:
Error parsing boolean value. Path 'request.ReturnListOfQueues', line 1, position 80.
我使用了以下代码:
JsonConvert.DeserializeObject("{\"request\": {\"UserName\": \"admin\", \"Password\": \"admin\",\"ReturnListOfQueues\":false\"}}");
如果我将其更改为:
JsonConvert.DeserializeObject("{\"request\": {\"UserName\": \"admin\", \"Password\": \"admin\",\"ReturnListOfQueues\":\"false\"}}");
它工作正常。 (在 false 之前添加了一个额外的双引号。)
我在 chrome 中试用了该应用程序并获得了以下 The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed
我从 web.config 中删除了这一部分,现在可以使用了。 Angular 在飞行前的 OPTIONS 调用
之后进行后续操作 POST<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
<add name="Access-Control-Max-Age" value="1728000" />
</customHeaders>
</httpProtocol>