我在尝试访问 WCF REST 服务时遇到了 iPhone 模拟器的一些问题。 我在 Xamarin 论坛上问过这个问题,但没有任何乐趣。
一些上下文:
- 我有一个 Xamarin 跨平台项目的 PCL,在 VS 2012 中。
- 我使用 Portable Microsoft HttpClient package和 Json.NET包。
- 我在后台有一个非常简单的 WCF REST 服务。
测试时
- 我可以通过开发机器上的浏览器正常访问该服务。
- 我可以使用通过 PCL 的控制台应用程序访问它。
- 我可以通过应用程序访问它,从 WiFi 网络上的真实安卓设备 同一公司网络。
- 我可以在 build Mac 上通过 Safari 访问它。
- 我可以在构建 Mac 上的 iPhone 模拟器上通过 Safari 正常访问它。
问题是,当我尝试通过 iPhone 模拟器上的应用程序访问该服务时,我收到 407,代理访问被拒绝错误。
这是我用来设置连接的代码:
private static HttpRequestMessage PrepareRequestMessage(HttpMethod method, string baseUri,
string queryParameters, out HttpClient httpClient, string bodyContent)
{
var finalUri = new Uri(baseUri + queryParameters);
var handler = new HttpClientHandler();
httpClient = new HttpClient(handler);
var requestMessage = new HttpRequestMessage(method, finalUri);
if (handler.SupportsTransferEncodingChunked())
{
requestMessage.Headers.TransferEncodingChunked = true;
}
if (method == HttpMethod.Post || method == HttpMethod.Put)
{
requestMessage.Content =
new StringContent(bodyContent, Encoding.UTF8, "application/json");
}
return requestMessage;
}
该代码给我 407 错误。
我尝试使用 SupportsProxy 和 SupportsUseProxy 的各种组合来设置代理。 (两者都从模拟器返回 false。) 无论如何,我都尝试过强制代理设置。我试过在处理程序本身上设置凭据。我试过使用 UseDefaultCredentials 和 UseProxy 标志。我还尝试在邮件 header 中设置 IfModifiedSince 值。我也尝试过使用 PortableRest 包。
所有这些似乎只会让事情变得更糟。在我最初遇到 407 错误的地方,对 httpClient.GetAsync 的调用将立即返回 null。
我在这里有点不知所措,所以非常感谢任何帮助。
附言。为了完整起见,进行调用的其余周围代码:(请原谅蹩脚的异常处理,我仍在处理错误)
public static async Task<T> SendRESTMessage<T>(HttpMethod method, string baseUri,
string queryParameters, T contentObject)
{
HttpClient httpClient;
var payload = string.Empty;
if (contentObject != null)
{
payload = JsonConvert.SerializeObject(contentObject);
}
var requestMessage =
PrepareRequestMessage(method, baseUri, queryParameters, out httpClient, payload);
HttpResponseMessage responseMessage = null;
try
{
if (method == HttpMethod.Get)
{
responseMessage = await httpClient.GetAsync(requestMessage.RequestUri);
}
else
{
responseMessage = await httpClient.SendAsync(requestMessage);
}
}
catch (HttpRequestException exc)
{
var innerException = exc.InnerException as WebException;
if (innerException != null)
{
throw new Exception("Unable to connect to remote server.");
}
}
return await HandleResponse<T>(responseMessage);
}
private static async Task<T> HandleResponse<T>(HttpResponseMessage responseMessage)
{
if (responseMessage != null)
{
if (!responseMessage.IsSuccessStatusCode)
{
throw new Exception("Request was unsuccessful");
}
var jsonString = await responseMessage.Content.ReadAsStringAsync();
var responseObject = JsonConvert.DeserializeObject<T>(jsonString);
return responseObject;
}
return default(T);
}
这是我快速而肮脏地实现 IWebProxy 的尝试,我认为这可能会使事情变得更糟:
public class MyProxy : IWebProxy
{
private System.Net.ICredentials creds;
public ICredentials Credentials
{
get
{
return creds;
}
set
{
creds = value;
}
}
public Uri GetProxy(Uri destination)
{
return new Uri("proxy addy here");
}
public bool IsBypassed(Uri host)
{
return true;
}
}
再次感谢您花时间阅读我的问题。
最佳答案
所以我终于让它工作了。
事实证明这真的很愚蠢,但作为 iOS 移动开发的新手以及该服务在模拟器上通过 Safari 运行的事实让我陷入了困境。
我读到模拟器使用 Mac 上定义的代理设置。所以我转到网络设置并将服务地址添加到代理绕过列表中。
现在就像一个魅力。
如果有人觉得有更好的方法来做到这一点,请提出您的意见。
关于cross-platform - Xamarin 可移植类库在 iPhone 模拟器上被拒绝代理访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21523388/