FacebookApplication.VerifyAuthentication(_httpContext,GenerateLocalCallbackUri())在Facebook上返回null

我使用nopcommerce开发了一个mvc 5应用程序,我使用外部回调它使用facebook登录它正在工作,但现在它不工作,我无法找到实际问题。 并使用下面的代码

this.FacebookApplication.VerifyAuthentication(_httpContext, GenerateLocalCallbackUri());

并且它返回我总是null并且身份validation状态失败我在网上搜索并做了所有事情并按照这些步骤但仍然无法登录facebook。

我的代码在FacebookProviderAuthorizer.cs中是这样的

 private AuthorizeState VerifyAuthentication(string returnUrl) { var authResult = DotNetOpenAuth.AspNet.Clients.FacebookApplication.VerifyAuthentication(_httpContext, GenerateLocalCallbackUri()); if (authResult.IsSuccessful) { } } 

然后编写回调方法

 private Uri GenerateLocalCallbackUri() { string url = string.Format("{0}plugins/externalauthFacebook/logincallback/", _webHelper.GetStoreLocation()); return new Uri(url); } 

然后生成服务登录URL

 private Uri GenerateServiceLoginUrl() { //code copied from DotNetOpenAuth.AspNet.Clients.FacebookClient file var builder = new UriBuilder("https://www.facebook.com/dialog/oauth"); var args = new Dictionary(); args.Add("client_id", _facebookExternalAuthSettings.ClientKeyIdentifier); args.Add("redirect_uri", GenerateLocalCallbackUri().AbsoluteUri); args.Add("response_type", "token"); args.Add("scope", "email"); AppendQueryArgs(builder, args); return builder.Uri; } 

2017年3月27日星期一,当Facebook停止支持他们的Graph API v2.2时,我们遇到了同样的问题。

我们也使用DotNetOpenAuth,它最初是通过Nuget安装的。 源代码可从以下链接获得:

https://github.com/DotNetOpenAuth/DotNetOpenAuth

具体来说,我们发现我们的代码使用的是4.3分支,其中包含DotNetOpenAuth.AspNet.DLL的源代码。 在检查源代码时,我们发现问题出在DotNetOpenAuth.AspNet \ Clients \ OAuth2 \ FacebookClient.cs的代码片段中,位于QueryAccessToken方法中:

 using (WebClient client = new WebClient()) { string data = client.DownloadString(builder.Uri); if (string.IsNullOrEmpty(data)) { return null; } var parsedQueryString = HttpUtility.ParseQueryString(data); return parsedQueryString["access_token"]; } 

具体来说,问题是ParseQueryString调用。 从API的v2.3开始,数据不再作为HTML查询字符串返回,而是以标准JSON格式返回。

为了解决这个问题,我们创建了自己的自定义类,inheritance了OAuth2Client并从FacebookClient.cs导入了大部分相同的代码。 然后,我们用解析JSON响应的代码替换上面的代码片段以提取access_token,然后返回它。 您可以在GetUserData方法中的同一个FacebookClient类中看到如何执行此操作的示例:

 FacebookGraphData graphData; var request = WebRequest.Create( "https://graph.facebook.com/me?access_token=" + MessagingUtilities.EscapeUriDataStringRfc3986(accessToken)); using (var response = request.GetResponse()) { using (var responseStream = response.GetResponseStream()) { graphData = JsonHelper.Deserialize(responseStream); } } 

唯一的另一个变化是注册我们的自定义类来代替FacebookClient类,因此OAuth回调使用它来处理来自Facebook API的post。 一旦我们这样做,一切都顺利进行。

我使用了@Vishal共享的代码并得到了相同的工作。

我们必须关注的主要事情是覆盖QueryAccessToken方法以使用json响应。

 protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { var uri = BuildUri(TokenEndpoint, new NameValueCollection { { "code", authorizationCode }, { "client_id", _appId }, { "client_secret", _appSecret }, { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, }); var webRequest = (HttpWebRequest)WebRequest.Create(uri); string accessToken = null; HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); // handle response from FB // this will not be a url with params like the first request to get the 'code' Encoding rEncoding = Encoding.GetEncoding(response.CharacterSet); using (StreamReader sr = new StreamReader(response.GetResponseStream(), rEncoding)) { var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); var jsonObject = serializer.DeserializeObject(sr.ReadToEnd()); var jConvert = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(jsonObject)); Dictionary desirializedJsonObject = JsonConvert.DeserializeObject>(jConvert.ToString()); accessToken = desirializedJsonObject["access_token"].ToString(); } return accessToken; } 

实现此目的的步骤:步骤1.您需要做的是添加一个名为FacebookClientOverride.cs的文件(除了FacebookClient.cs)

这是整个文件的代码片段。

  using System; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; using DotNetOpenAuth.AspNet.Clients; using Newtonsoft.Json; public class FacebookClient : OAuth2Client { #region Constants and Fields ///  /// The authorization endpoint. ///  private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; ///  /// The token endpoint. ///  private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; ///  /// The user info endpoint. ///  private const string UserInfoEndpoint = "https://graph.facebook.com/me"; ///  /// The app id. ///  private readonly string _appId; ///  /// The app secret. ///  private readonly string _appSecret; ///  /// The requested scopes. ///  private readonly string[] _requestedScopes; #endregion ///  /// Creates a new Facebook OAuth2 client, requesting the default "email" scope. ///  /// The Facebook App Id /// The Facebook App Secret public FacebookClient(string appId, string appSecret) : this(appId, appSecret, new[] { "email" }) { } ///  /// Creates a new Facebook OAuth2 client. ///  /// The Facebook App Id /// The Facebook App Secret /// One or more requested scopes, passed without the base URI. public FacebookClient(string appId, string appSecret, params string[] requestedScopes) : base("facebook") { if (string.IsNullOrWhiteSpace(appId)) throw new ArgumentNullException("appId"); if (string.IsNullOrWhiteSpace(appSecret)) throw new ArgumentNullException("appSecret"); if (requestedScopes == null) throw new ArgumentNullException("requestedScopes"); if (requestedScopes.Length == 0) throw new ArgumentException("One or more scopes must be requested.", "requestedScopes"); _appId = appId; _appSecret = appSecret; _requestedScopes = requestedScopes; } protected override Uri GetServiceLoginUrl(Uri returnUrl) { var state = string.IsNullOrEmpty(returnUrl.Query) ? string.Empty : returnUrl.Query.Substring(1); return BuildUri(AuthorizationEndpoint, new NameValueCollection { { "client_id", _appId }, { "scope", string.Join(" ", _requestedScopes) }, { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, { "state", state }, }); } protected override IDictionary GetUserData(string accessToken) { var uri = BuildUri(UserInfoEndpoint, new NameValueCollection { { "access_token", accessToken } }); var webRequest = (HttpWebRequest)WebRequest.Create(uri); using (var webResponse = webRequest.GetResponse()) using (var stream = webResponse.GetResponseStream()) { if (stream == null) return null; using (var textReader = new StreamReader(stream)) { var json = textReader.ReadToEnd(); var extraData = JsonConvert.DeserializeObject>(json); var data = extraData.ToDictionary(x => x.Key, x => x.Value.ToString()); data.Add("picture", string.Format("https://graph.facebook.com/{0}/picture", data["id"])); return data; } } } protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { var uri = BuildUri(TokenEndpoint, new NameValueCollection { { "code", authorizationCode }, { "client_id", _appId }, { "client_secret", _appSecret }, { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, }); var webRequest = (HttpWebRequest)WebRequest.Create(uri); string accessToken = null; HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); // handle response from FB // this will not be a url with params like the first request to get the 'code' Encoding rEncoding = Encoding.GetEncoding(response.CharacterSet); using (StreamReader sr = new StreamReader(response.GetResponseStream(), rEncoding)) { var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); var jsonObject = serializer.DeserializeObject(sr.ReadToEnd()); var jConvert = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(jsonObject)); Dictionary desirializedJsonObject = JsonConvert.DeserializeObject>(jConvert.ToString()); accessToken = desirializedJsonObject["access_token"].ToString(); } return accessToken; } private static Uri BuildUri(string baseUri, NameValueCollection queryParameters) { var keyValuePairs = queryParameters.AllKeys.Select(k => HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(queryParameters[k])); var qs = String.Join("&", keyValuePairs); var builder = new UriBuilder(baseUri) { Query = qs }; return builder.Uri; } ///  /// Facebook works best when return data be packed into a "state" parameter. /// This should be called before verifying the request, so that the url is rewritten to support this. ///  public static void RewriteRequest() { var ctx = HttpContext.Current; var stateString = HttpUtility.UrlDecode(ctx.Request.QueryString["state"]); if (stateString == null || !stateString.Contains("__provider__=facebook")) return; var q = HttpUtility.ParseQueryString(stateString); q.Add(ctx.Request.QueryString); q.Remove("state"); ctx.RewritePath(ctx.Request.Path + "?" + q); } } 

步骤2.添加一个对System.Web.Extensions的引用

步骤3.在FacebookProviderAuthorizer.cs(Nopcommerce项目)中查找FacebookClient Property私有FacebookClient _facebookApplication;

这应该引用刚刚添加的新文件。

步骤4.现在在文件FacebookProviderAuthorizer.cs中的名为VerifyAuthentication的方法中放置一个断点。

authResult.IsSuccessful现在必须为true才能成功解析令牌。

谢谢大家。 请问,如果解决方案适合您。

在Steve的post上,我创建了一个“FriendlyFacebookClient”来代替FacebookClient,复制了一些内部方法,并用以下内容替换了QueryAccessToken:

  protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { UriBuilder builder = new UriBuilder("https://graph.facebook.com/oauth/access_token"); AppendQueryArgs(builder, (IEnumerable>)new Dictionary() { { "client_id", this.appId}, { "redirect_uri", FriendlyFacebookClient.NormalizeHexEncoding(returnUrl.AbsoluteUri)}, { "client_secret", this.appSecret }, { "code", authorizationCode }, { "scope", "email" } }); using (WebClient webClient = new WebClient()) { var response = webClient.DownloadString(builder.Uri); var data = JsonConvert.DeserializeObject>(response); return data["access_token"]; } } 

根据之前的答案我得到了我的解决方案。 在MVC4每个人都写下他们的AppIDSecurityCode 。 由于facebook GRAPH API的更改,以前的链接被破坏了。 因此,每个人都需要更改RegisterFacebookClient类。 但是这个类是.Net库中的密封类,所以任何人都无法扩展或覆盖它。 因此,我们需要使用wrapper类。 我正在写这个答案,因为所有以前的答案供应商都错过了一件事,我遭受了很多苦难。 因为他们没有在AuthConfig类中提到过类整经系统。 因此解决这个问题需要太多。 因此,我将按照以下步骤进行。 让我们考虑我的Wrapper类是FacebookClientV2Dot3因此我的课程将是

 using System; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; using DotNetOpenAuth.AspNet.Clients; using Newtonsoft.Json; public class FacebookClientV2Dot3 : OAuth2Client { #region Constants and Fields ///  /// The authorization endpoint. ///  private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; ///  /// The token endpoint. ///  private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; ///  /// The user info endpoint. ///  private const string UserInfoEndpoint = "https://graph.facebook.com/me"; ///  /// The app id. ///  private readonly string _appId; ///  /// The app secret. ///  private readonly string _appSecret; ///  /// The requested scopes. ///  private readonly string[] _requestedScopes; #endregion ///  /// Creates a new Facebook OAuth2 client, requesting the default "email" scope. ///  /// The Facebook App Id /// The Facebook App Secret public FacebookClient(string appId, string appSecret) : this(appId, appSecret, new[] { "email" }) { } ///  /// Creates a new Facebook OAuth2 client. ///  /// The Facebook App Id /// The Facebook App Secret /// One or more requested scopes, passed without the base URI. public FacebookClient(string appId, string appSecret, params string[] requestedScopes) : base("facebook") { if (string.IsNullOrWhiteSpace(appId)) throw new ArgumentNullException("appId"); if (string.IsNullOrWhiteSpace(appSecret)) throw new ArgumentNullException("appSecret"); if (requestedScopes == null) throw new ArgumentNullException("requestedScopes"); if (requestedScopes.Length == 0) throw new ArgumentException("One or more scopes must be requested.", "requestedScopes"); _appId = appId; _appSecret = appSecret; _requestedScopes = requestedScopes; } protected override Uri GetServiceLoginUrl(Uri returnUrl) { var state = string.IsNullOrEmpty(returnUrl.Query) ? string.Empty : returnUrl.Query.Substring(1); return BuildUri(AuthorizationEndpoint, new NameValueCollection { { "client_id", _appId }, { "scope", string.Join(" ", _requestedScopes) }, { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, { "state", state }, }); } protected override IDictionary GetUserData(string accessToken) { var uri = BuildUri(UserInfoEndpoint, new NameValueCollection { { "access_token", accessToken } }); var webRequest = (HttpWebRequest)WebRequest.Create(uri); using (var webResponse = webRequest.GetResponse()) using (var stream = webResponse.GetResponseStream()) { if (stream == null) return null; using (var textReader = new StreamReader(stream)) { var json = textReader.ReadToEnd(); var extraData = JsonConvert.DeserializeObject>(json); var data = extraData.ToDictionary(x => x.Key, x => x.Value.ToString()); data.Add("picture", string.Format("https://graph.facebook.com/{0}/picture", data["id"])); return data; } } } protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { var uri = BuildUri(TokenEndpoint, new NameValueCollection { { "code", authorizationCode }, { "client_id", _appId }, { "client_secret", _appSecret }, { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, }); var webRequest = (HttpWebRequest)WebRequest.Create(uri); string accessToken = null; HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); // handle response from FB // this will not be a url with params like the first request to get the 'code' Encoding rEncoding = Encoding.GetEncoding(response.CharacterSet); using (StreamReader sr = new StreamReader(response.GetResponseStream(), rEncoding)) { var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); var jsonObject = serializer.DeserializeObject(sr.ReadToEnd()); var jConvert = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(jsonObject)); Dictionary desirializedJsonObject = JsonConvert.DeserializeObject>(jConvert.ToString()); accessToken = desirializedJsonObject["access_token"].ToString(); } return accessToken; } private static Uri BuildUri(string baseUri, NameValueCollection queryParameters) { var keyValuePairs = queryParameters.AllKeys.Select(k => HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(queryParameters[k])); var qs = String.Join("&", keyValuePairs); var builder = new UriBuilder(baseUri) { Query = qs }; return builder.Uri; } ///  /// Facebook works best when return data be packed into a "state" parameter. /// This should be called before verifying the request, so that the url is rewritten to support this. ///  public static void RewriteRequest() { var ctx = HttpContext.Current; var stateString = HttpUtility.UrlDecode(ctx.Request.QueryString["state"]); if (stateString == null || !stateString.Contains("__provider__=facebook")) return; var q = HttpUtility.ParseQueryString(stateString); q.Add(ctx.Request.QueryString); q.Remove("state"); ctx.RewritePath(ctx.Request.Path + "?" + q); } } 

在这里,我已经用更新的版本链接替换了所有API链接。

现在你需要修改你的

AuthConfig

只需使用包装类而不是RegisterFacebookClient 。 完全阻止这部分代码。 并添加这个……

 OAuthWebSecurity.RegisterClient(new FacebookClientV2Dot3("AppID", "HassedPassword")); 

然后一切顺利。 你的Facebook登录将恢复到以前的状态。

但是,您可以面对这个新API而不是以前的API的新问题,问题是IP Whitelisting 。 喜欢这张图片 。 希望你除此之外什么都不需要。 快乐的编码。

正如@SteveTerry所建议我们需要在FacebookClient类中更新QueryAccessToken函数。 不幸的是“FacebookClient”是密封类,所以我们不能inheritance和覆盖。 无论你选择哪种方式取决于你。 这是最终结果应该是什么样的:

这个函数的旧代码是:

 protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { // Note: Facebook doesn't like us to url-encode the redirect_uri value var builder = new UriBuilder(TokenEndpoint); builder.AppendQueryArgs( new Dictionary { { "client_id", this.appId }, { "redirect_uri", NormalizeHexEncoding(returnUrl.AbsoluteUri) }, { "client_secret", this.appSecret }, { "code", authorizationCode }, { "scope", "email" }, }); using (webclient client = new webclient()) { string data = client.downloadstring(builder.uri); if (string.isnullorempty(data)) { return null; } var parsedquerystring = httputility.parsequerystring(data); return parsedquerystring["access_token"]; } 

}

并且为了支持新版本的fb api,应该是这样的:

 ///  /// Contains access_token of a Facebook user. ///  [DataContract] [EditorBrowsable(EditorBrowsableState.Never)] [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Facebook", Justification = "Brand name")] public class FacebookAccessTokenData { #region Public Properties ///  /// ///  [DataMember(Name = "access_token")] public string AccessToken { get; set; } ///  /// ///  [DataMember(Name = "token_type")] public string TokenType { get; set; } ///  /// ///  [DataMember(Name = "expires_in")] public string ExpiresIn { get; set; } #endregion } ///  /// Obtains an access token given an authorization code and callback URL. ///  ///  /// The return url. ///  ///  /// The authorization code. ///  ///  /// The access token. ///  protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { // Note: Facebook doesn't like us to url-encode the redirect_uri value var builder = new UriBuilder(TokenEndpoint); builder.AppendQueryArgs( new Dictionary { { "client_id", this.appId }, { "redirect_uri", NormalizeHexEncoding(returnUrl.AbsoluteUri) }, { "client_secret", this.appSecret }, { "code", authorizationCode }, { "scope", "email" }, }); FacebookAccessTokenData graphData; var request = WebRequest.Create(builder.Uri); using (var response = request.GetResponse()) { using (var responseStream = response.GetResponseStream()) { graphData = JsonHelper.Deserialize(responseStream); } } return graphData.AccessToken; } 

我解决了我的问题,我会做同样的事情,就像@Adam在他的回答中所描述的那样,根据@Adam,@ SteveTerry和@ Adeem的回答我改变了我的代码并创建了具有不同名称的自定义FacebookClient类。 并在nopCommerce中替换FacebookClient的原始参考。

 public class FacebookOAuth2Client : OAuth2Client { #region Constants and Fields ///  /// The authorization endpoint. ///  private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; ///  /// The token endpoint. ///  private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; ///  /// The user info endpoint. ///  private const string UserInfoEndpoint = "https://graph.facebook.com/me"; ///  /// The app id. ///  private readonly string _appId; ///  /// The app secret. ///  private readonly string _appSecret; ///  /// The requested scopes. ///  private readonly string[] _requestedScopes; #endregion ///  /// Creates a new Facebook OAuth2 client, requesting the default "email" scope. ///  /// The Facebook App Id /// The Facebook App Secret public FacebookClient(string appId, string appSecret) : this(appId, appSecret, new[] { "email" }) { } ///  /// Creates a new Facebook OAuth2 client. ///  /// The Facebook App Id /// The Facebook App Secret /// One or more requested scopes, passed without the base URI. public FacebookClient(string appId, string appSecret, params string[] requestedScopes) : base("facebook") { if (string.IsNullOrWhiteSpace(appId)) throw new ArgumentNullException("appId"); if (string.IsNullOrWhiteSpace(appSecret)) throw new ArgumentNullException("appSecret"); if (requestedScopes == null) throw new ArgumentNullException("requestedScopes"); if (requestedScopes.Length == 0) throw new ArgumentException("One or more scopes must be requested.", "requestedScopes"); _appId = appId; _appSecret = appSecret; _requestedScopes = requestedScopes; } protected override Uri GetServiceLoginUrl(Uri returnUrl) { var state = string.IsNullOrEmpty(returnUrl.Query) ? string.Empty : returnUrl.Query.Substring(1); return BuildUri(AuthorizationEndpoint, new NameValueCollection { { "client_id", _appId }, { "scope", string.Join(" ", _requestedScopes) }, { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, { "state", state }, }); } protected override IDictionary GetUserData(string accessToken) { var uri = BuildUri(UserInfoEndpoint, new NameValueCollection { { "access_token", accessToken } }); var webRequest = (HttpWebRequest)WebRequest.Create(uri); using (var webResponse = webRequest.GetResponse()) using (var stream = webResponse.GetResponseStream()) { if (stream == null) return null; using (var textReader = new StreamReader(stream)) { var json = textReader.ReadToEnd(); var extraData = JsonConvert.DeserializeObject>(json); var data = extraData.ToDictionary(x => x.Key, x => x.Value.ToString()); data.Add("picture", string.Format("https://graph.facebook.com/{0}/picture", data["id"])); return data; } } } protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { var uri = BuildUri(TokenEndpoint, new NameValueCollection { { "code", authorizationCode }, { "client_id", _appId }, { "client_secret", _appSecret }, { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, }); var webRequest = (HttpWebRequest)WebRequest.Create(uri); string accessToken = null; HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); // handle response from FB // this will not be a url with params like the first request to get the 'code' Encoding rEncoding = Encoding.GetEncoding(response.CharacterSet); using (StreamReader sr = new StreamReader(response.GetResponseStream(), rEncoding)) { var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); var jsonObject = serializer.DeserializeObject(sr.ReadToEnd()); var jConvert = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(jsonObject)); Dictionary desirializedJsonObject = JsonConvert.DeserializeObject>(jConvert.ToString()); accessToken = desirializedJsonObject["access_token"].ToString(); } return accessToken; } private static Uri BuildUri(string baseUri, NameValueCollection queryParameters) { var keyValuePairs = queryParameters.AllKeys.Select(k => HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(queryParameters[k])); var qs = String.Join("&", keyValuePairs); var builder = new UriBuilder(baseUri) { Query = qs }; return builder.Uri; } ///  /// Facebook works best when return data be packed into a "state" parameter. /// This should be called before verifying the request, so that the url is rewritten to support this. ///  public static void RewriteRequest() { var ctx = HttpContext.Current; var stateString = HttpUtility.UrlDecode(ctx.Request.QueryString["state"]); if (stateString == null || !stateString.Contains("__provider__=facebook")) return; var q = HttpUtility.ParseQueryString(stateString); q.Add(ctx.Request.QueryString); q.Remove("state"); ctx.RewritePath(ctx.Request.Path + "?" + q); } } 

在这段代码中,我没有JsonHelper的参考,所以我使用简单的jsonConvert。 Thanx再次@Adam,@ SteveTerry和@ Adeem寻求帮助。