打包uri验证

时间:2010-06-10 20:21:03

标签: c# uri

验证可以找到包uri的最简单方法是什么?

例如,给定

pack://application:,,,Rhino.Mocks;3.5.0.1337;0b3305902db7183f;component/SomeImage.png

如何检查图像是否确实存在?

干杯,
Berryl

3 个答案:

答案 0 :(得分:5)

我找不到一个简单的答案,所以我结束了自己的代码来完成关于图像资源的三件事:
(1)具有包uri(数据绑定)的字符串表示 (2)验证图像位于我认为它所在的位置(单元测试)
(3)验证包uri是否可用于设置图像(单元测试)

部分原因并不简单,因为打包uri一开始有点令人困惑,而且有几种风格。此代码用于包uri,表示包含在VS程序集中的图像(本地或带有'resource'构建操作的引用程序集。此msdn articles阐明了在此上下文中的含义。您还可以需要了解更多有关装配和构建的信息,而不是最初看起来像是一个好时机。

希望这会让其他人更容易。干杯,
Berryl

    /// <summary> (1) Creates a 'Resource' pack URI .</summary>
    public static Uri CreatePackUri(Assembly assembly, string path, PackType packType)
    {
        Check.RequireNotNull(assembly);
        Check.RequireStringValue(path, "path");

        const string startString = "pack://application:,,,/{0};component/{1}";
        string packString;
        switch (packType)
        {
            case PackType.ReferencedAssemblySimpleName:
                packString = string.Format(startString, assembly.GetName().Name, path);
                break;
            case PackType.ReferencedAssemblyAllAvailableParts:
                // exercise for the reader
                break;
            default:
                throw new ArgumentOutOfRangeException("packType");
        }
        return new Uri(packString);
    }

    /// <summary>(2) Verify the resource is located where I think it is.</summary>
    public static bool ResourceExists(Assembly assembly, string resourcePath)
    {
        return GetResourcePaths(assembly).Contains(resourcePath.ToLowerInvariant());
    }

    public static IEnumerable<object> GetResourcePaths(Assembly assembly, CultureInfo culture)
    {
        var resourceName = assembly.GetName().Name + ".g";
        var resourceManager = new ResourceManager(resourceName, assembly);

        try
        {
            var resourceSet = resourceManager.GetResourceSet(culture, true, true);

            foreach (DictionaryEntry resource in resourceSet)
            {
                yield return resource.Key;
            }
        }
        finally
        {
            resourceManager.ReleaseAllResources();
        }
    }

    /// <summary>(3) Verify the uri can construct an image.</summary>
    public static bool CanCreateImageFrom(Uri uri)
    {
        try
        {
            var bm = new BitmapImage(uri);
            return bm.UriSource == uri;
        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
            return false;
        }
    }

答案 1 :(得分:1)

Public Class Res

    Private Shared __keys As New List(Of String)

    Shared Function Exist(partName As String) As Boolean
        Dim r As Boolean = False

        If __keys.Count < 1 Then
            Dim a = Assembly.GetExecutingAssembly()
            Dim resourceName = a.GetName().Name + ".g"
            Dim resourceManager = New ResourceManager(resourceName, a)
            Dim resourceSet = resourceManager.GetResourceSet(Globalization.CultureInfo.CurrentCulture, True, True)
            For Each res As System.Collections.DictionaryEntry In resourceSet
                __keys.Add(res.Key)
            Next
        End If

        __keys.ForEach(Sub(e)
                           If e.Contains(partName.ToLower) Then
                               r = True
                               Exit Sub
                           End If
                       End Sub)

        Return r
    End Function
End Class

答案 2 :(得分:1)

我知道,这个问题很老,但也许有人有同样的问题。 我也有问题,我想在单元测试中测试我的资源字符串。

最简单的解决方案是初始化ResourceDictionary。您还可以使用dictionary.Keys [“myKey”]访问特定密钥并检查内容。

[SetUp]
public void OnTestInitialize()
{
    if (!UriParser.IsKnownScheme("pack"))
    {
       new Application();
    }
}

[TestCase]
public void TestIfResourcesExist()
{
    var resources = new [] {
        "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonColors.xaml",
        "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonStyles.xaml",
        "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/GridSplitterStyle.xaml"
    };

    foreach (var mergedResource in resources)
    {
        // init
        ResourceDictionary dictionary =
            new ResourceDictionary {Source = new Uri(mergedResource, UriKind.RelativeOrAbsolute)};

        // verify
        dictionary.Keys.Count.Should().BeGreaterThan(0);
    }
}

顺便说一下,这是我在App.xaml.cs中注册资源的方式(所以我可以在单元测试中测试它们):

public static class ResourceManager
{
    public static readonly string[] MergedResources = {
        "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonColors.xaml",
        "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonStyles.xaml",
        "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/GridSplitterStyle.xaml"
    };

    public static void AddResources()
    {
        Application.Current.Resources.BeginInit();
        foreach (var resource in MergedResources)
        {
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
            {
                Source = new Uri(resource, UriKind.Absolute)
            });
        }
        Application.Current.Resources.EndInit();
    }
}

在OnStartup中:

// add xaml resources (styles, colors, ...)
ResourceManager.AddResources();