2011-07-07 64 views
4

我试图用WebRequest.RegisterPrefix注册一个装饰IWebRequestCreate实现的意图是要加上“调试”的场景(如模拟不同的连接方案)。WebRequest.RegisterPrefix对于http://返回true,不工作

我在使用Mango beta 2 SDK和RegisterPrefix方法时总是以“http://”作为前缀(或“http”)作为前缀返回true,但注册的IWebRequestCreate实例不在用过的。

我可以从文档中看到,它应该为重复项返回false,但它似乎不像记录中那样起作用。

是否有任何其他方式实现我对消费者透明的方式?

回答

2

我使用WebRequest.RegisterPrefix单元测试,注册一个IWebRequestCreate实施的test://的前缀,这确实工作。

我发现,登记为http://IWebRequestCreate后,调用WebRequest.Createhttp:// URI将返回从注册IWebRequestCreate产生的一个请求,但调用WebRequest.CreateHttp仍然会返回一个HttpWebRequest

下面的代码应该验证这一点,我使用的是芒果Beta 2的SDK(11年6月29日):

public partial class MainPage : PhoneApplicationPage 
{ 
    public class FakeRequest : WebRequest 
    { 
     private Uri _uri; 

     public FakeRequest(Uri uri) 
     { 
      _uri = uri; 
     } 

     public override Uri RequestUri { get { return _uri; } } 
    } 

    public class FakeRequestFactory : IWebRequestCreate 
    { 
     public WebRequest Create(Uri uri) 
     { 
      return new FakeRequest(uri); 
     } 
    } 

    // Constructor 
    public MainPage() 
    { 
     InitializeComponent(); 

     // returns System.Net.Browser.ClientHttpWebRequest 
     var request1 = WebRequest.Create("http://www.foo.com"); 

     // returns System.Net.Browser.ClientHttpWebRequest 
     var request2 = WebRequest.CreateHttp("http://www.foo.com"); 

     // returns true 
     bool result1 = WebRequest.RegisterPrefix("http://", new FakeRequestFactory()); 

     // returns FakeRequest 
     var request3 = WebRequest.Create("http://www.foo.com"); 

     // returns System.Net.Browser.ClientHttpWebRequest 
     var request4 = WebRequest.CreateHttp("http://www.foo.com"); 

     // returns false 
     bool result2 = WebRequest.RegisterPrefix("http://", new FakeRequestFactory()); 

     // returns false, as per the note in the documention 
     bool result3 = HttpWebRequest.RegisterPrefix("http://", new FakeRequestFactory()); 
    } 
} 
-1

电话只有有一个客户端堆栈,所以RegisterPrefix对电话没有影响。

+0

如何注册自定义协议?如果它没有实现,他们不应该删除API或抛出NotSupportedException? –

+0

API不是关于不同的协议,它只改变现有的协议(https/http)。由于只有一个堆栈,它可以完成预期的任务。它不会抛出NotSupported的原因是它做它所做的事情(以便桌面和手机之间的共享代码不会中断)。 –

+0

如果只是在客户端/浏览器实现之间进行交换,为什么不使用枚举而不是接口呢?为什么要给出可扩展性的错误认识? –

0

嘿,我知道这个问题是2岁,但我穿过来了同样的问题。我想你会发现WebRequest.RegisterPrefix()确实如果您尝试注册http:(注意单个冒号,没有正斜杠),则返回false。如果我找到解决方法,我会尽量记住更新这篇文章。

编辑

在我的具体情况,我想扔出去System.Net.FtpWebRequest,并推出自己的FTP客户端实现(因为该框架的实施sucks)。

为了做到这一点,我使用反射(和一堆后期绑定技巧)来获取注册前缀的数组列表,并删除链接到内部类System.Net.FtpWebRequestCreator的数组。

我不知道如果所有这些API可用于Windows手机,但这里是我所做的:

Type webRequest = typeof(System.Net.WebRequest); 
Assembly system = Assembly.GetAssembly(webRequest); 
Type ftpWebRequestCreator = system.GetType("System.Net.FtpWebRequestCreator"); 
ArrayList prefixList = (ArrayList)webRequest.GetProperty("PrefixList", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null); 

IEnumerator enumerator = prefixList.GetEnumerator(); 
while (enumerator != null && enumerator.MoveNext()) { 
    if (object.ReferenceEquals(enumerator.Current.Creator.GetType(), ftpWebRequestCreator)) { 
     prefixList.Remove(enumerator.Current); 
     if (System.Net.WebRequest.RegisterPrefix(enumerator.Current.Prefix, new CustomWebRequestCreator())) { 
      enumerator = null; 
     } else { 
      enumerator = prefixList.GetEnumerator(); 
     } 
    } 
} 

// Now I can use Create() on the base class 
System.Net.WebRequest myCustomWebRequest = System.Net.WebRequest.Create("ftp://example.com/public"); 

这是通过查找与FtpWebRequestCreator注册的所有前缀,并用自己的替换它们创造者。为了适应http(s),这应该相当简单。