替代.NET的Uri实现?

时间:2009-02-10 11:22:40

标签: c# .net ftp uri

我的.NET Uri实现有问题。似乎如果方案是“ftp”,则查询部分不会被解析为Query,而是作为路径的一部分进行解析。

以下面的代码为例:

Uri testuri = new Uri("ftp://user:pass@localhost/?passive=true");
Console.WriteLine(testuri.Query); // Outputs an empty string
Console.WriteLine(testuri.AbsolutePath); // Outputs "/%3Fpassive=true"

在我看来,Uri类错误地将查询部分解析为路径的一部分。无论如何将方案更改为http,结果都符合预期:

Uri testuri = new Uri("http://user:pass@localhost/?passive=true");
Console.WriteLine(testuri.Query); // Outputs "?passive=true"
Console.WriteLine(testuri.AbsolutePath); // Outputs "/"

有没有人有这方面的解决方案,或者知道一个按预期工作的替代Uri类?

4 个答案:

答案 0 :(得分:4)

嗯,问题不在于我无法创建FTP连接,但是根据RFC 2396不会解析该URI。

我实际打算做的是创建一个Factory,它根据给定的连接URI提供通用文件传输接口(包含get和put方法)的实现。 URI定义了协议,用户信息,主机和路径,并且需要传递的任何属性都应该通过URI的Query部分传递(例如FTP连接的被动模式选项)。

然而,使用.NET Uri实现证明这很困难,因为它似乎根据模式以不同方式解析URI的Query部分。

所以我希望有人知道这个的解决方法,或者替代看似破坏的.NET Uri实现。在花费数小时实现我自己之前会很高兴知道。

答案 1 :(得分:2)

除非您有特殊原因,否则应使用FtpWebRequestFtpWebResponse课程。

FtpWebRequest.fwr = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://uri"));
fwr.ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
fwr.ftpRequest.Credentials = new NetworkCredential("user", "pass");


FileInfo ff = new FileInfo("localpath");
byte[] fileContents = new byte[ff.Length];

using (FileStream fr = ff.OpenRead())
{
   fr.Read(fileContents, 0, Convert.ToInt32(ff.Length));
}

using (Stream writer = fwr.GetRequestStream())
{
   writer.Write(fileContents, 0, fileContents.Length);
}

FtpWebResponse frp = (FtpWebResponse)fwr.GetResponse();
Response.Write(frp.ftpResponse.StatusDescription); 

Ref1 Ref2

答案 2 :(得分:2)

我一直在努力解决同样的问题。尝试使用UriParser.Register替换“ftp”方案的现有UriParser会抛出InvalidOperationException,因为该方案已经注册。

我提出的解决方案涉及使用反射来修改现有的ftp解析器,以便它允许查询字符串。这是基于another UriParser bug的解决方法。

MethodInfo getSyntax = typeof(UriParser).GetMethod("GetSyntax", System.Reflection.BindingFlags.Static
                                                              | System.Reflection.BindingFlags.NonPublic);
FieldInfo flagsField = typeof(UriParser).GetField("m_Flags", System.Reflection.BindingFlags.Instance
                                                           | System.Reflection.BindingFlags.NonPublic);
if (getSyntax != null && flagsField != null)
{
    UriParser parser = (UriParser)getSyntax.Invoke(null, new object[] { "ftp"});
    if (parser != null)
    {
        int flagsValue = (int)flagsField.GetValue(parser);

        // Set the MayHaveQuery attribute
        int MayHaveQuery = 0x20;
        if ((flagsValue & MayHaveQuery) == 0) flagsField.SetValue(parser, flagsValue | MayHaveQuery);
    }
}

在初始化的某个地方运行它,你的ftp Uris会让查询字符串进入Query参数,正如你所期望的那样,而不是Path

答案 3 :(得分:1)

您必须使用特定的FTP协议类,如FtpWebRequest,它具有像RequestUri这样的Uri属性。

你应该在thoses类中搜索我认为的Uri解析器。

相关问题