从AngularJS向WCF服务发布内容类型的问题

本文关键字:布内容 类型 问题 服务 AngularJS WCF | 更新日期: 2023-09-27 17:54:53

首先,抱歉这篇文章的长度,但我想包括尽可能多的信息。我正在编写我的第一个typescript/angular应用程序,并试图调用我们现有的IIS WCFservices。这些调用是跨域的。谢谢你的建议。

服务合同:

[OperationContract]
[WebInvoke(Method = "POST",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    UriTemplate = "LoginUser", 
    BodyStyle = WebMessageBodyStyle.Wrapped)]
LoginResponse LoginUser(LoginRequest request);

打印稿的要求:

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显示在提琴手中,但内容类型是"文本/计划",我得到一个400请求错误

我还不能发布图片,所以这里有一个提琴截图的链接https://goo.gl/photos/m75uzHi3E9KdkZhw5

如果我在Fiddler中编辑/重新发出请求并将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",
}

screencap2提琴手:https://goo.gl/photos/VeJd9HSX46svA1HZ6

当设置Content-Type

时,我也会在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).

网络。

服务配置项
<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>

更新:我关注了这篇文章:http://www.microsoft.co..cn/2011/07/02/cross-origin-resource-sharing-cors-and-wcf/

现在当我用headers: { 'Content-Type': "application/json" }发送请求时,我不再得到405错误。它发送OPTIONS请求,返回200 OK,但从未发出POST请求。

从AngularJS向WCF服务发布内容类型的问题

可能是JSON.stringify正在产生一些无效的JSON,因此您正在发布无效的JSON数据?

如果我试图反序列化包含在您的第一张图片中的请求正文,我会得到以下错误:

解析布尔值错误。路径的请求。ReturnListOfQueues',第1行,位置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

我从网上删除了这个部分。配置,它现在正在工作。Angular在pre-flight 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>