Относительный путь от пользовательского элемента управления ASP.NET NavigateUrl

У меня есть пользовательский элемент управления, содержащий GridView. GridView имеет столбец HyperLinkField и столбец шаблона, который содержит элемент управления HyperLink.

Проект ASP.NET структурирован следующим образом, со страницей Default.aspx в каждом случае с использованием пользовательского элемента управления.

  • Application Root
    • Controls
      • UserControl with GridView
    • SystemAdminFolder
      • Default.aspx
      • Edit.aspx
    • OrganisationAdminFolder
      • Default.aspx
      • Edit.aspx
    • StandardUserFolder
      • Default.aspx
      • Edit.aspx

Примечание. Папки используются для обеспечения правильной роли пользователя.

Мне нужно установить DataNavigateUrlFormatString для HyperLinkField и NavigateUrl для HyperLink, чтобы разрешить страницу Edit.aspx в соответствующей папке.

Если я установил для URL перехода значение «Edit.aspx», URL-адрес в браузере отобразится как «http://Application Root / Controls /Edit.aspx 'независимо от исходного каталога.

Я не могу использовать корневой оператор веб-приложения (~ /), поскольку путь должен быть относительно текущей страницы, а не корня приложения.

Как я могу использовать один и тот же пользовательский элемент управления в нескольких папках и разрешить URL-адрес другой страницы в той же папке?

Примечание. Этот вопрос во многом основан на аналогичном вопросе azhar2000s на форумах asp.net, что соответствует моей проблеме.


person Daniel Ballinger    schedule 09.04.2010    source источник


Ответы (2)


При вводе этого вопроса я натолкнулся на одно возможное решение и дополнительно изменил его, используя отзывы от @Thomas.

Изменение Control.AppRelativeTemplateSourceDirectory изменяет относительные пути, создаваемые элементом управления. Я установил для него корневой относительный виртуальный путь для текущего папка запросов. Теперь любые относительные пути в UserControl с относительными к запрошенной странице, а не к пути пользовательских элементов управления.

//Page Load Event for the User Control
protected void Page_Load(object sender, EventArgs e)
{
    string rootPath = HttpContext.Current.Request.ApplicationPath;
    if (!rootPath.EndsWith("/"))
    {
        rootPath += "/";
    }

    Uri requestUri = HttpContext.Current.Request.Url;
    string folderPath = requestUri.AbsolutePath.Remove(0, rootPath.Length);
    string lastSegment = requestUri.Segments[requestUri.Segments.Length - 1];
    folderPath = folderPath.Remove(folderPath.LastIndexOf(lastSegment));

    AppRelativeTemplateSourceDirectory = "~/" + folderPath;
}
person Daniel Ballinger    schedule 09.04.2010

Я бы установил его в событии Load сетки или страницы следующим образом:

var hyperlinkColumn = this.GridView1.Columns[0] as HyperLinkColumn;
hyperlinkColumn.DataNavigateUrlFormatString = "~/SystemAdminFolder/{0}";

Эта структура предполагает, что URL-адрес должен отличаться для каждой строки в зависимости от DataNavigateUrlField. Если это должен быть один и тот же URL-адрес для всех строк, вы можете просто установить свойство NavigateUrl в Load. Очевидно, вы должны установить другую папку в зависимости от роли пользователя.

ДОПОЛНЕНИЕ Учитывая то, что вы упомянули в своей проблеме в комментариях, я предлагаю где-нибудь сохранить отношения "роль-папка". У вас есть несколько вариантов:

  1. Просто сохраните ключи с волшебными именами в appSettings (Role_SystemAdministrators, Role_OrganizationAdministrators и т. Д.) С именем папки, в которую они должны быть направлены. Преимущество такого подхода в том, что он прост. Недостатком является то, что данные должны быть введены правильно, ничто не мешает кому-либо случайно сопоставить роль с двумя папками, а при добавлении роли ее необходимо обновить еще в одном месте.

  2. Создайте настраиваемый ConfigSection для хранения отношения. Преимущество состоит в том, что вы можете гарантировать, что каждая роль будет указана только один раз. Недостатком является то, что вам нужно написать дополнительный код, и при добавлении роли вам все равно придется добавить что-то в другом месте.

  3. Прочтите теги location из файла конфигурации. Преимущество состоит в том, что вам не нужно писать значение более чем в одном месте. Недостаток в том, что это будет утомительно. Вам нужно будет найти первый тег, связанный с данной папкой, на которую текущий пользователь получил разрешение.

  4. Считайте значения из базы данных. Преимущество состоит в том, что вы можете легко написать экран управления для обновления значений. Недостаток в том, что при добавлении роли вам нужно что-то добавить в совершенно другое место приложения.

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

person Thomas    schedule 09.04.2010
comment
Спасибо, это один из вариантов изменения пути в зависимости от папки. В идеальном мире пользовательский элемент управления не нуждался бы в коде, специфичном для папки, в которой он используется (что мое решение также не полностью решает). То есть я хотел бы иметь возможность отбросить элемент управления на любой произвольной странице и всегда иметь ссылку на страницу Edit.aspx в той же папке, что и содержащая страница. - person Daniel Ballinger; 09.04.2010
comment
@ Дэниел Баллинджер - Существенно ли различаются страницы для каждой роли? То есть, не могли бы вы просто разветвить функциональность на основе ролей на одной странице? - person Thomas; 09.04.2010
comment
Конечно, я мог бы переделать отдельные страницы в одну. Я бы потерял преимущество использования отдельных папок, которые устанавливают ограничения доступа. Я предполагаю, что я действительно ищу в этом вопросе, как сделать относительные пути URL-адресов в пользовательском элементе управления по отношению к страницам, а не к пути пользовательских элементов управления. Пути от пользовательского элемента управления не должны зависеть от страницы, на которой используется элемент управления. - person Daniel Ballinger; 12.04.2010
comment
@ Дэниел Баллинджер - Хорошо. Я не понимал, что это основная проблема. Я обновил свой пост, чтобы дать возможный ответ на эту часть проблемы. - person Thomas; 12.04.2010