First off, sorry for the length of this but I wanted to include as much info as possible. I'm writing my first typescript/angular app and attempting to call into our existing IIS WCFservices. The calls are cross domain. Thanks for any input.
Service Contract:
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "LoginUser",
BodyStyle = WebMessageBodyStyle.Wrapped)]
LoginResponse LoginUser(LoginRequest request);
TypeScript Request:
class LoginRequest implements ILoginRequest {
UserName: string;
Password: string;
ReturnListOfQueues: boolean;
}
Angular/Typescript Login Method:
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;
});
}
When I call it as above with headers: { 'Content-Type': undefined }
, the JSON shows up in Fiddler but the Content-Type is `text/plan' and I get a 400 Request Error
If I edit/reissue the request in Fiddler and change the Content-Type to application/json, the service is called succesfully and I get the expected response data.
When i change the request to use application/json the data no longer shows up in Fiddler
var req = {
method: 'POST',
url: base_url,
headers: { 'Content-Type': "application/json" },
data: JSON.stringify({ request: request }),
contentType: "application/json",
dataType: "json",
}
I also get CORS messages in Firefox when setting the Content-Type
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 entried for service
<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>
UPDATE: I followed this post blogs.microsoft.co.il/idof/2011/07/02/cross-origin-resource-sharing-cors-and-wcf/
Now when I send the request in with headers: { 'Content-Type': "application/json" }
, I no longer get the 405 error. It sends the OPTIONS request which returns a 200 OK but the POST request is never made.
I tried the app in chrome and got the following The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed
I removed this section from the web.config and it's working now. Angular makes the follow-up POST following the pre-flight OPTIONS call
<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>