【问题标题】:Relative path from an ASP.NET user control NavigateUrl来自 ASP.NET 用户控件 NavigateUrl 的相对路径
【发布时间】:2011-02-05 23:20:51
【问题描述】:

我有一个包含 GridView 的用户控件。 GridView 有一个 HyperLinkField 列和一个包含 HyperLink 控件的模板列。

ASP.NET 项目的结构如下,Default.aspx 页面在每种情况下都使用用户控件。

  • 应用程序根
    • 控件
      • 带有 GridView 的用户控件
    • 系统管理员文件夹
      • 默认.aspx
      • Edit.aspx
    • 组织管理文件夹
      • 默认.aspx
      • Edit.aspx
    • 标准用户文件夹
      • 默认.aspx
      • Edit.aspx

注意:这些文件夹用于确保用户具有正确的角色。

我需要能够设置 HyperLinkField 的 DataNavigateUrlFormatString 和 HyperLink 的 NavigateUrl 以解析到相应文件夹中的 Edit.aspx 页面。

如果我将导航 URL 设置为“Edit.aspx”,浏览器中的 URL 将显示为 'http://Application Root/Controls/Edit.aspx' 与原始目录无关。

我不能使用 Web 应用程序根操作符 (~/),因为路径需要相对于当前页面,而不是应用程序根。

如何在多个文件夹中使用相同的用户控件并将 URL 解析到同一文件夹中的另一个页面?

注意:该问题强烈基于azhar2000s on the asp.net forums 提出的与我的问题相匹配的类似问题。

【问题讨论】:

    标签: asp.net user-controls relative-path absolute-path


    【解决方案1】:

    在输入这个问题时,我遇到了一个可能的解决方案,并使用来自@Thomas 的反馈进一步修改了它。

    更改Control.AppRelativeTemplateSourceDirectory 会更改控件生成的相对路径。对于当前的请求文件夹,我已将其设置为 root relative virtual path。现在 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;
    }
    

    【讨论】:

      【解决方案2】:

      我会在网格或页面的 Load 事件中设置它,如下所示:

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

      此结构假定根据DataNavigateUrlField,每行的 URL 应该不同。如果所有行的 url 应该是相同的,那么您可以在 Load 处设置 NavigateUrl 属性。显然,您会根据用户的角色设置不同的文件夹。

      添加鉴于您在 cmets 中的问题中提到的内容,我建议将角色文件夹关系存储在某处。您有多种选择:

      1. 只需将神奇命名的键存储在 appSettings(Role_SystemAdministrators、Role_OrganizationAdministrators 等)中,并附上它们应该指向的文件夹的名称。这种方法的优点是简单。缺点是数据必须正确输入,没有什么可以阻止某人不小心将一个角色映射到两个文件夹,并且当添加一个角色时,它必须在另一个地方更新。

      2. 创建自定义 ConfigSection 来存储关系。优点是您可以确保每个角色只列出一次。缺点是你必须编写额外的代码,当添加一个角色时,你仍然需要在另一个地方添加一些东西。

      3. 从配置文件中读取location 标签。优点是您可以避免在多个位置写入值。缺点是这样做会很麻烦。您必须找到与当前用户被授予权限的给定文件夹关联的第一个标签。

      4. 从数据库中读取值。优点是您可以轻松编写管理屏幕来更新值。缺点是添加角色时,您需要将某些内容添加到应用程序的完全不同的位置。

      您仍然可以像现在一样设置文件夹权限。但是,一旦您存储了这种关系,您就可以将该人重定向到适当的文件夹,而无需编写自定义分叉代码。

      【讨论】:

      • 谢谢,这是根据文件夹更改路径的一种选择。在理想的世界中,用户控件不需要特定于它正在使用的文件夹的代码(我的解决方案也没有完全解决)。也就是说,我希望能够将控件放在任意页面中,并且始终将链接指向与包含页面位于同一文件夹中的 Edit.aspx 页面。
      • @Daniel Ballinger - 每个角色的页面是否显着不同?即,您不能简单地在单个页面中根据角色分叉功能吗?
      • 当然,我可以将单独的页面重新合成为一个。我将失去使用强制访问限制的单独文件夹的优势。我想我在这个问题上真正寻找的是如何在用户控件中创建相对于页面而不是用户控件路径的相对 URL 路径。来自用户控件的路径应该与使用该控件的页面无关。
      • @Daniel Ballinger - 好的。我没有意识到这是根本问题。我已经更新了我的帖子,以便为这部分问题提供可能的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 2012-02-03
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 1970-01-01
      相关资源
      最近更新 更多