web-dev-qa-db-ja.com

UriオブジェクトC#からファイル拡張子または「HasExtension」タイプのブール値を取得します

簡単な質問:

正規表現や一般的なテキスト検索よりも優れた方法を考えて、Uriオブジェクト(URL文字列ではない)にファイル拡張子があるかどうかを判断できますか?

どんな考えでも歓迎します。すでにこれを行っている.NETフレームワーク/ Uriクラスで何かを見逃してしまった場合はお詫びします。


少し複雑になります。


私はcraigtpの答えを受け入れました。しかし、私が必要としているのは、このように解決策です。

var hasExtension = Path.HasExtension(requestUri.AbsolutePath);

これに挑戦したすべての人に。完全で包括的な答えを得るには、さらにチェックを行うためにmimeタイプ辞書が必要になることは明らかです。例http://example/this.is.sort.of.valid.but.not.a.mime.type「true」を返しますhas Path.HasExtensionしかし、私が必要としているもののために、私はこのタイプのパスが入ってくることは決してありません。

25

System.IO.Path クラスの HasExtension メソッドを使用して、URIの文字列に拡張子があるかどうかを判別できます。

AbsoluteUri オブジェクトの Uri プロパティを使用すると、URIを表す完全な文字列を取得できます。この文字列をPathクラスのHasExtensionメソッドに渡すと、URIにファイル拡張子が含まれているかどうかを示すブール値が正しく返されます。

次のコードをコピーして単純なコンソールアプリケーションに貼り付け、これをテストします。 myUri3myUrl4のみがTrueを返します。これは、HasExtensionメソッドがファイル名(および拡張子)の後の追加の文字(つまり、クエリ文字列)を正しく処理できることも示しています。

using System;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri myURI1 = new Uri(@"http://www.somesite.com/");
            Uri myURI2 = new Uri(@"http://www.somesite.com/filenoext");
            Uri myURI3 = new Uri(@"http://www.somesite.com/filewithext.jpg");
            Uri myURI4 = new Uri(@"http://www.somesite.com/filewithext.jpg?q=randomquerystring");

            Console.WriteLine("Does myURI1 have an extension: " + Path.HasExtension(myURI1.AbsoluteUri));
            Console.WriteLine("Does myURI2 have an extension: " + Path.HasExtension(myURI2.AbsoluteUri));
            Console.WriteLine("Does myURI3 have an extension: " + Path.HasExtension(myURI3.AbsoluteUri));
            Console.WriteLine("Does myURI4 have an extension: " + Path.HasExtension(myURI4.AbsoluteUri));

            Console.ReadLine();
        }
    }
}

編集:

拡張機能が有効な拡張機能であるかどうかを判断することに関する質問者の編集に基づいて、以下のいくつかの新しいコードを作成しました(コンソールアプリにコピーして貼り付けます)。

using System;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri myUri1 = new Uri("http://www.somesite.com/folder/file.jpg?q=randomquery.string");
            string path1 = String.Format("{0}{1}{2}{3}", myUri1.Scheme, Uri.SchemeDelimiter, myUri1.Authority, myUri1.AbsolutePath);
            string extension1 = Path.GetExtension(path1);
            Console.WriteLine("Extension of myUri1: " + extension1);

            Uri myUri2 = new Uri("http://www.somesite.com/folder/?q=randomquerystring");
            string path2 = String.Format("{0}{1}{2}{3}", myUri2.Scheme, Uri.SchemeDelimiter, myUri2.Authority, myUri2.AbsolutePath);
            string extension2 = Path.GetExtension(path2);
            Console.WriteLine("Extension of myUri1: " + extension2);

            Console.ReadLine();
        }
    }
}

この新しいコードは、Uriオブジェクトのすべてのコンポーネント部分(つまり、Scheme-http部分など)を分解し、具体的には、のクエリ文字列部分を削除します。ウリ。これは、クエリ文字列にドット文字が含まれている可能性があるというこの回答のコメントで Adriano によって指摘されているように、潜在的な問題を回避します(これにより、HasExtensionメソッドが台無しになる可能性があります)。

Uriが分解されると、Uri文字列に拡張子があるかどうかと、whatその拡張子の両方を適切に判別できるようになります。です。

ここからは、この拡張機能を既知の有効な拡張機能のリストと照合する場合にすぎません。この部分は、anyファイル拡張子が潜在的に有効であるため、.NET Frameworkでは決して提供されないものです(必要に応じて、任意のアプリケーションが独自のファイル拡張子を作成できます!)

22
CraigTP

他の人が提案したUri.IsFileプロパティは機能しません。

ドキュメントから

The IsFile property is true when the Scheme property equals UriSchemeFile.

file://server/filename.ext"

http://msdn.Microsoft.com/en-us/library/system.uri.isfile.aspx

できることは、URIのAbsolutePath(たとえば、/ contactまたは/images/logo.pngに対応)を取得してから、FileInfoクラスを使用して拡張子を確認/取得することです。

var uris = new List<Uri>()
{
  new Uri("http://mysite.com/contact"),
  new Uri("http://mysite.com/images/logo.png"),
  new Uri("http://mysite.com/images/logo.png?query=value"),
};

foreach (var u in uris)
{
  var fi = new FileInfo(u.AbsolutePath);
  var ext = fi.Extension;
  if (!string.IsNullOrWhiteSpace(ext))
  {
    Console.WriteLine(ext);
  }
}

より複雑なケース(contact.is.sortof.validおよびcontact.is.sortof.valid.png)を処理するには、サポートされている拡張機能のリストと照合する必要があります。

テスト:

"http://mysite.com/contact"                             //no ext
"http://mysite.com/contact?query=value"                 //no ext
"http://mysite.com/contact?query=value.value"           //no ext
"http://mysite.com/contact/"                            //no ext
"http://mysite.com/images/logo.png"                     //.png
"http://mysite.com/images/logo.png?query=value"         //.png
"http://mysite.com/images/logo.png?query=value.value"   //.png
"http://mysite.com/contact.is.sortof.valid"             //.valid
"http://mysite:123/contact.is.sortof.valid"              //.valid
8
wdavo

UriBuilderクラスを見てください。 URLの特定の部分を取得できるだけでなく、自由に交換することもできます。

public bool HasExtension(Uri myUri)
{
    var validExtensions = new List<string>() { ".png", ".jpg" };
    var builder = UriBuilder(myUri)
    foreach (var extension in validExtensions) {
        if(builder.Path.Equals(extension, StringComparison.InvariantCultureIgnoreCase))
            return true;
    return false;
}
0
TxRegex