与 Janrain“auth_info”通信时出现问题WCF 中的服务

发布于 2024-11-18 02:39:24 字数 3439 浏览 2 评论 0原文

所以我现在陷入困境。我正在尝试与 JanRain 的“auth_info”服务进行通信。事实上,首先,我只是想获取当您直接在浏览器中冲浪时得到的“错误”消息/对象/'.jsthingy':

https://rpxnow.com/api/v2/auth_info

但我想通过 WCF 调用取回该信息。

根据 Fiddler 的说法,该 url 处信息的内容类型是 text/javascript。然而,据我所知,WCF 在通过 WCF 调用它时并没有给我这个选项。我有两个选项:WebMessageFormat.JsonWebMessageFormat.Xml

我在 Visual Studio 中收到以下错误:

InvalidOperationException 未由用户代码处理 - 传入消息具有意外的消息格式“原始”。该操作的预期消息格式为“Xml”、“Json”。这可能是因为尚未在绑定上配置 WebContentTypeMapper。有关更多详细信息,请参阅 WebContentTypeMapper 的文档。

WTF?那么 WCF 是否可以做到这一点? (我怀疑前面有更多手动解决方案)

JanRain 的在线代码示例在 C# 示例中有点缺乏。

他们关于 auth_info 的文档链接在这里 https://rpxnow.com/docs#auth_info

他们的 auth_info 的地址服务在这里:

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;
    }
}

我想也许我应该将内容类型保留为 json 并调整行为或绑定。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧城烟雨 2024-11-25 02:39:24

好的..看起来我需要

在声明绑定后在绑定上添加自定义 contentTypeMapper 我添加了以下内容:

    WebContentTypeMapper customMapper = new JsonContentTypeMapper();
    binding.ContentTypeMapper = customMapper;

这是自定义映射器:

  public class JsonContentTypeMapper : WebContentTypeMapper
    {
        public override WebContentFormat
                   GetMessageFormatForContentType(string contentType)
        {
            if (contentType == "text/javascript")
            {
                return WebContentFormat.Raw;
            }
            else
            {
                return WebContentFormat.Json;
            }
        }
    }

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;
            }
        }
    }
迎风吟唱 2024-11-25 02:39:24

Kevin,

这是一个有关如何处理 auth_info 响应的 C# 示例,您可能会发现它很有帮助:

//C# Helper Class for Janrain Engage
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.XPath;
public class Rpx
{
    private string apiKey;
    private string baseUrl;
    public Rpx(string apiKey, string baseUrl) {
        while (baseUrl.EndsWith("/"))
            baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
        this.apiKey = apiKey;
        this.baseUrl = baseUrl;
    }
    public string getApiKey() { return apiKey; }
    public string getBaseUrl() { return baseUrl; }
    public XmlElement AuthInfo(string token) {
        Dictionary<string,string> query = new Dictionary<string,string>();
        query.Add("token", token);
        return ApiCall("auth_info", query);
    }
    public List<string> Mappings(string primaryKey) {
        Dictionary<string,string> query = new Dictionary<string,string>();
        query.Add("primaryKey", primaryKey);
        XmlElement rsp = ApiCall("mappings", query);
        XmlElement oids = (XmlElement)rsp.FirstChild;
        List<string> result = new List<string>();
        for (int i = 0; i < oids.ChildNodes.Count; i++) {
            result.Add(oids.ChildNodes[i].InnerText);
        }
        return result;
    }
    public Dictionary<string,ArrayList> AllMappings() {
        Dictionary<string,string> query = new Dictionary<string,string>();
        XmlElement rsp = ApiCall("all_mappings", query);
        Dictionary<string,ArrayList> result = new Dictionary<string,ArrayList>();
        XPathNavigator nav = rsp.CreateNavigator();
        XPathNodeIterator mappings = (XPathNodeIterator) nav.Evaluate("/rsp/mappings/mapping");
        foreach (XPathNavigator m in mappings) {
            string remote_key = GetContents("./primaryKey/text()", m);
            XPathNodeIterator ident_nodes = (XPathNodeIterator) m.Evaluate("./identifiers/identifier");
            ArrayList identifiers = new ArrayList();
            foreach (XPathNavigator i in ident_nodes) {
                identifiers.Add(i.ToString());
            }
            result.Add(remote_key, identifiers);
        }
        return result;
    }
    private string GetContents(string xpath_expr, XPathNavigator nav) {
        XPathNodeIterator rk_nodes = (XPathNodeIterator) nav.Evaluate(xpath_expr);
        while (rk_nodes.MoveNext()) {
            return rk_nodes.Current.ToString();
        }
        return null;
    }
    public void Map(string identifier, string primaryKey) {
        Dictionary<string,string> query = new Dictionary<string,string>();
        query.Add("identifier", identifier);
        query.Add("primaryKey", primaryKey);
        ApiCall("map", query);
    }
    public void Unmap(string identifier, string primaryKey) {
        Dictionary<string,string> query = new Dictionary<string,string>();
        query.Add("identifier", identifier);
        query.Add("primaryKey", primaryKey);
        ApiCall("unmap", query);
    }
    private XmlElement ApiCall(string methodName, Dictionary<string,string> partialQuery) {
        Dictionary<string,string> query = new Dictionary<string,string>(partialQuery);
        query.Add("format", "xml");
        query.Add("apiKey", apiKey);
        StringBuilder sb = new StringBuilder();
        foreach (KeyValuePair<string, string> e in query) {
            if (sb.Length > 0) {
                sb.Append('&');
            }
            sb.Append(System.Web.HttpUtility.UrlEncode(e.Key, Encoding.UTF8));
            sb.Append('=');
            sb.Append(HttpUtility.UrlEncode(e.Value, Encoding.UTF8));
        }
        string data = sb.ToString();
        Uri url = new Uri(baseUrl + "/api/v2/" + methodName);
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = data.Length;
        // Write the request
        StreamWriter stOut = new StreamWriter(request.GetRequestStream(),
                                              Encoding.ASCII);
        stOut.Write(data);
        stOut.Close();
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream dataStream = response.GetResponseStream ();
        XmlDocument doc = new XmlDocument();
        doc.PreserveWhitespace = false;
        doc.Load(dataStream);
        XmlElement resp = doc.DocumentElement;
        if (resp == null || !resp.GetAttribute("stat").Equals("ok")) {
            throw new Exception("Unexpected API error");
        }
        return resp;
    }
    public static void Main(string[] args) {
        Rpx r = new Rpx(args[0], args[1]);
        if (args[2].Equals("mappings")) {
            Console.WriteLine("Mappings for " + args[3] + ":");
            foreach(string s in r.Mappings(args[3])) {
                Console.WriteLine(s);
            }
        }
        if (args[2].Equals("all_mappings")) {
            Console.WriteLine("All mappings:");
            foreach (KeyValuePair<string, ArrayList> pair in r.AllMappings()) {
                Console.WriteLine(pair.Key + ":");
                foreach (string identifier in pair.Value) {
                    Console.WriteLine("  " + identifier);
                }
            }
        }
        if (args[2].Equals("map")) {
            Console.WriteLine(args[3] + " mapped to " + args[4]);
            r.Map(args[3], args[4]);
        }
        if (args[2].Equals("unmap")) {
            Console.WriteLine(args[3] + " unmapped from " + args[4]);
            r.Unmap(args[3], args[4]);
        }
    }
}

代码源:https://github.com/janrain/Janrain-Sample-Code/blob/master/c-sharp/csharp-helper-class.cs

Kevin,

Here is a C# example on how to process the auth_info response that you might find helpful:

//C# Helper Class for Janrain Engage
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.XPath;
public class Rpx
{
    private string apiKey;
    private string baseUrl;
    public Rpx(string apiKey, string baseUrl) {
        while (baseUrl.EndsWith("/"))
            baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
        this.apiKey = apiKey;
        this.baseUrl = baseUrl;
    }
    public string getApiKey() { return apiKey; }
    public string getBaseUrl() { return baseUrl; }
    public XmlElement AuthInfo(string token) {
        Dictionary<string,string> query = new Dictionary<string,string>();
        query.Add("token", token);
        return ApiCall("auth_info", query);
    }
    public List<string> Mappings(string primaryKey) {
        Dictionary<string,string> query = new Dictionary<string,string>();
        query.Add("primaryKey", primaryKey);
        XmlElement rsp = ApiCall("mappings", query);
        XmlElement oids = (XmlElement)rsp.FirstChild;
        List<string> result = new List<string>();
        for (int i = 0; i < oids.ChildNodes.Count; i++) {
            result.Add(oids.ChildNodes[i].InnerText);
        }
        return result;
    }
    public Dictionary<string,ArrayList> AllMappings() {
        Dictionary<string,string> query = new Dictionary<string,string>();
        XmlElement rsp = ApiCall("all_mappings", query);
        Dictionary<string,ArrayList> result = new Dictionary<string,ArrayList>();
        XPathNavigator nav = rsp.CreateNavigator();
        XPathNodeIterator mappings = (XPathNodeIterator) nav.Evaluate("/rsp/mappings/mapping");
        foreach (XPathNavigator m in mappings) {
            string remote_key = GetContents("./primaryKey/text()", m);
            XPathNodeIterator ident_nodes = (XPathNodeIterator) m.Evaluate("./identifiers/identifier");
            ArrayList identifiers = new ArrayList();
            foreach (XPathNavigator i in ident_nodes) {
                identifiers.Add(i.ToString());
            }
            result.Add(remote_key, identifiers);
        }
        return result;
    }
    private string GetContents(string xpath_expr, XPathNavigator nav) {
        XPathNodeIterator rk_nodes = (XPathNodeIterator) nav.Evaluate(xpath_expr);
        while (rk_nodes.MoveNext()) {
            return rk_nodes.Current.ToString();
        }
        return null;
    }
    public void Map(string identifier, string primaryKey) {
        Dictionary<string,string> query = new Dictionary<string,string>();
        query.Add("identifier", identifier);
        query.Add("primaryKey", primaryKey);
        ApiCall("map", query);
    }
    public void Unmap(string identifier, string primaryKey) {
        Dictionary<string,string> query = new Dictionary<string,string>();
        query.Add("identifier", identifier);
        query.Add("primaryKey", primaryKey);
        ApiCall("unmap", query);
    }
    private XmlElement ApiCall(string methodName, Dictionary<string,string> partialQuery) {
        Dictionary<string,string> query = new Dictionary<string,string>(partialQuery);
        query.Add("format", "xml");
        query.Add("apiKey", apiKey);
        StringBuilder sb = new StringBuilder();
        foreach (KeyValuePair<string, string> e in query) {
            if (sb.Length > 0) {
                sb.Append('&');
            }
            sb.Append(System.Web.HttpUtility.UrlEncode(e.Key, Encoding.UTF8));
            sb.Append('=');
            sb.Append(HttpUtility.UrlEncode(e.Value, Encoding.UTF8));
        }
        string data = sb.ToString();
        Uri url = new Uri(baseUrl + "/api/v2/" + methodName);
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = data.Length;
        // Write the request
        StreamWriter stOut = new StreamWriter(request.GetRequestStream(),
                                              Encoding.ASCII);
        stOut.Write(data);
        stOut.Close();
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream dataStream = response.GetResponseStream ();
        XmlDocument doc = new XmlDocument();
        doc.PreserveWhitespace = false;
        doc.Load(dataStream);
        XmlElement resp = doc.DocumentElement;
        if (resp == null || !resp.GetAttribute("stat").Equals("ok")) {
            throw new Exception("Unexpected API error");
        }
        return resp;
    }
    public static void Main(string[] args) {
        Rpx r = new Rpx(args[0], args[1]);
        if (args[2].Equals("mappings")) {
            Console.WriteLine("Mappings for " + args[3] + ":");
            foreach(string s in r.Mappings(args[3])) {
                Console.WriteLine(s);
            }
        }
        if (args[2].Equals("all_mappings")) {
            Console.WriteLine("All mappings:");
            foreach (KeyValuePair<string, ArrayList> pair in r.AllMappings()) {
                Console.WriteLine(pair.Key + ":");
                foreach (string identifier in pair.Value) {
                    Console.WriteLine("  " + identifier);
                }
            }
        }
        if (args[2].Equals("map")) {
            Console.WriteLine(args[3] + " mapped to " + args[4]);
            r.Map(args[3], args[4]);
        }
        if (args[2].Equals("unmap")) {
            Console.WriteLine(args[3] + " unmapped from " + args[4]);
            r.Unmap(args[3], args[4]);
        }
    }
}

Code source: https://github.com/janrain/Janrain-Sample-Code/blob/master/c-sharp/csharp-helper-class.cs

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文