So I'm stuck at this point. I am trying to communicate with JanRain's "auth_info" service. In fact, to start, I'm just trying to get the "error" message/object/'.jsthingy' that you get when you surf to it directly in the browser:
https://rpxnow.com/api/v2/auth_info
but I want to get that back with a WCF call.
According to Fiddler, the content type of the information at that url is text/javascript. However, from what I can tell, WCF doesn't give me that option when calling it through WCF. I get two options: WebMessageFormat.Json
, or WebMessageFormat.Xml
.
I get the following error in Visual Studio:
InvalidOperationException was unhandled by User Code - The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml', 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.
WTF? So can WCF even do this? (I suspect a more manual solution ahead)
JanRain's online code examples are a little bit lacking in the C# examples.
Their documentation link on auth_info is here https://rpxnow.com/docs#auth_info
The address of their auth_info service is here:
https://rpxnow.com/api/v2/auth_info
[TestMethod]
public void CallJanRain()
{
var x = new JanRainProxy("https://rpxnow.com/api/v2");
x.GetAuthInfo("", ""); //the params are apiKey, and token. not passing either at the moment as I want to be able to know how to at least handle the error first. After all, the *browser* at least got it..
}
[ServiceContract]
public interface IJanRainContract
{
[OperationContract(Name="auth_info")]
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Xml)]
JanRainAuthInfo GetAuthInfo(string apiKey, string token);
}
[DataContract]
public class JanRainAuthInfo
{
[DataMember(Name="identifier")]
public string Identifier { get; set; }
}
public class JanRainProxy: ClientBase<IJanRainContract>
{
public JanRainProxy(string url, WebHttpSecurityMode securityMode = WebHttpSecurityMode.Transport)
: base(ConstructEndpoint(url, securityMode))
{
}
//JanRainContract
public JanRainAuthInfo GetAuthInfo(string apiKey, string token)
{
return base.Channel.GetAuthInfo(apiKey, token);
}
// This method constructs a WebHttpBinding endpoint with all the appropriate
// settings for talking to our services.
private static ServiceEndpoint ConstructEndpoint(string serviceUri, WebHttpSecurityMode securityMode)
{
var contract = ContractDescription.GetContract(typeof(IJanRainContract));
var binding = new WebHttpBinding(securityMode);
//{
// MaxBufferPoolSize = 524288000,
// MaxReceivedMessageSize = 65536000
//};
var address = new EndpointAddress(serviceUri);
var endpoint = new ServiceEndpoint(
contract,
binding,
address);
var webHttpBehavior = new WebHttpBehavior()
{
DefaultBodyStyle = WebMessageBodyStyle.Wrapped,
DefaultOutgoingRequestFormat = WebMessageFormat.Json,
DefaultOutgoingResponseFormat = WebMessageFormat.Json,
AutomaticFormatSelectionEnabled = true,
FaultExceptionEnabled = true
};
endpoint.Behaviors.Add(webHttpBehavior);
return endpoint;
}
}
I'm figuring that perhaps I should leave the contenttype at json and tweak the behavior, or binding.
ok.. it looks like I needed to add a custom contentTypeMapper on my binding
after declaring my binding I added the following:
WebContentTypeMapper customMapper = new JsonContentTypeMapper();
binding.ContentTypeMapper = customMapper;
here's the custom Mapper:
public class JsonContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat
GetMessageFormatForContentType(string contentType)
{
if (contentType == "text/javascript")
{
return WebContentFormat.Raw;
}
else
{
return WebContentFormat.Json;
}
}
}