Проблема UriMapper с учетом регистра в Silverlight 3

В API навигации Silverlight 3 класс UriMapper чувствителен к регистру. Для следующего сопоставления uri

<nav:Frame Source="/Home">
  <nav:Frame.UriMapper>
    <uriMapper:UriMapper>
      <uriMapper:UriMapping
        Uri=""
        MappedUri="/Views/HomePage.xaml"/>
      <uriMapper:UriMapping
        Uri="/entity/{code}"
        MappedUri="/Views/EntityEditorPage.xaml?code={code}"/>
      <uriMapper:UriMapping
        Uri="/{pageName}"
        MappedUri="/Views/{pageName}Page.xaml"/>
    </uriMapper:UriMapper>
  </nav:Frame.UriMapper>
</nav:Frame>

«/entity/123» правильно отображается на «/Views/EntityEditorPage.xaml?code=123», но «/Entity/123» завершится ошибкой с исключением «/Views/Entity/123Page.xaml not found».

Как я могу сделать UriMapper нечувствительным к регистру?

Спасибо.


person Safor    schedule 01.07.2010    source источник


Ответы (3)


Сафор,

Я сделал именно то, что предложил Энтони для моего собственного приложения.

Вот ваш XAML, модифицированный для использования CustomUriMapper:

<nav:Frame Source="/Home">
    <nav:Frame.UriMapper>
        <app:CustomUriMapper>
            <app:CustomUriMapping Uri="" MappedUri="/Views/HomePage.xaml"/>
            <app:CustomUriMapping Uri="/entity/{code}" MappedUri="/Views/EntityEditorPage.xaml?code={code}"/>
            <app:CustomUriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}Page.xaml"/>
        </app:CustomUriMapper>
    </nav:Frame.UriMapper>
</nav:Frame>

Вот код для классов CustomUriMapping и CustomUriMapper:

using System;
using System.Collections.ObjectModel;
using System.Windows.Markup;
using System.Windows.Navigation;

namespace YourApplication
{
    // In XAML:
    // <app:CustomUriMapper>
    //     <app:CustomUriMapping Uri="/{search}" MappedUri="/Views/searchpage.xaml?searchfor={search}"/>
    // </app:CustomUriMapper>

    public class CustomUriMapping
    {
        public Uri Uri { get; set; }
        public Uri MappedUri { get; set; }

        public Uri MapUri(Uri uri)
        {
            // Do the uri mapping without regard to upper or lower case
            UriMapping _uriMapping = new UriMapping() { Uri = (Uri == null || string.IsNullOrEmpty(Uri.OriginalString) ? null : new Uri(Uri.OriginalString.ToLower(), UriKind.RelativeOrAbsolute)), MappedUri = MappedUri };
            return _uriMapping.MapUri(uri == null || string.IsNullOrEmpty(uri.OriginalString) ? null : new Uri(uri.OriginalString.ToLower(), UriKind.RelativeOrAbsolute));
        }
    }

    [ContentProperty("UriMappings")]
    public class CustomUriMapper : UriMapperBase
    {
        public ObservableCollection<CustomUriMapping> UriMappings { get { return m_UriMappings; } private set { m_UriMappings = value; } }
        private ObservableCollection<CustomUriMapping> m_UriMappings = new ObservableCollection<CustomUriMapping>();

        public override Uri MapUri(Uri uri)
        {
            if (m_UriMappings == null)
                return uri;

            foreach (CustomUriMapping mapping in m_UriMappings)
            {
                Uri mappedUri = mapping.MapUri(uri);
                if (mappedUri != null)
                    return mappedUri;
            }

            return uri;
        }
    }
}

Удачи, Джим МакКарди.

person Jim McCurdy    schedule 26.07.2010
comment
Джим, спасибо за код. Оно работает! Всего одно замечание. Параметры необходимо указывать только в нижнем регистре. -Евгений - person Safor; 15.08.2010
comment
Хм, я в замешательстве. Все дело в том, что этот UriMapper выполняет проверку Uri без учета регистра. Какие параметры вы указываете в нижнем регистре? - person Jim McCurdy; 16.08.2010
comment
Джим, извини, я пропустил твой вопрос. Я имел в виду такие параметры, как {search}. В приведенном выше коде вы не можете использовать {searchArg}, но {searcharg} будет работать. Только то. - person Safor; 19.09.2010

UriMapper использует регулярное выражение, попробуйте изменить сопоставление на «[V|v]iews/EntityEditorPage.xaml?code={code}» для начала, это сделает V в представлении нечувствительным

person Larry Dukek    schedule 29.10.2010
comment
Сопоставление должно быть [Vv]iews/EntityEditorPage.xaml?code={code}. В противном случае URL-адрес |iews/EntityEditorPage.xaml?code={code} также будет совпадать. - person stefan.s; 30.11.2011

Вы не можете сделать это легко. В конечном итоге вам нужно будет создать свой собственный UriMapperBase и выполнить всю логику сопоставления самостоятельно. Это, вероятно, не стоит делать, если вы не можете использовать некоторые упрощенные сопоставления.

person AnthonyWJones    schedule 06.07.2010