【问题标题】:C# access element in master page from logic layerC# 从逻辑层访问母版页中的元素
【发布时间】:2014-09-07 23:27:03
【问题描述】:

我有一个连接到母版页的内容页。我可以访问母版页上的元素,并通过调用站点母版上的方法直接从内容页 .cs 文件修改它。 (这可能是人们在这类领域中最常见的错误)

我的问题是我想扩展此功能以从 AJAX 请求更新站点母版页。 ajax 文件调用一个不同的页面,该页面依次启动一个逻辑层的实例,我将其用于所有计算和连接。我想要做的是直接从逻辑层访问站点管理员(只有一个 .cs 文件)。

我当前的代码是这样的:

SiteMaster sm = new SiteMaster();
sm.MyMethod("param1", "param2");

这成功访问了站点主控中名为“MyMethod”的方法,但在此方法中我有以下代码:

mySpan.InnerText = "this is a test";

这不起作用,因为我收到“对象引用未设置为对象的实例......”错误。这是因为 mySpan 为 NULL。如果我使用 this.mySpan.InnerText 调用它,如果我将鼠标悬停在“this”上,那么我可以看到 ID“mySpan”。

有谁知道我该如何解决这个问题?我所做的每一次搜索都是针对那些想要从内容页面访问元素的人,这些内容已经对我有用。

【问题讨论】:

  • @Liath 是的,mySpan 为空,感谢您指出这一点,我将其添加到原始问题中。
  • 我个人使用this.Page.Master作为SiteMaster;
  • 您能否补充一下您是如何获得 mySpan 的?大概是 sm.mySpan?
  • @Liath 你到底是什么意思?在方法“MyMethod”中,我只是有我在问题中发布的行(在我的 Site.Master.cs 文件中)。 mySpan 根据 VS2012 可用,但运行代码时它始终为 null。

标签: c# asp.net master-pages business-logic-layer


【解决方案1】:

我相信你在这里有一个误解。如果我理解正确,您有一个带有 MasterPage 的页面。在那个 aspx 页面上,您正在执行 ajax 调用(可能是 WebService),它执行以下操作:

[WebMethod]
public void UpdateText(string message)
{
  var master = new SiteMaster();
  master.mySpan.Text = message;
}

这里有几个问题。

当您使用这种方法是一个 aspx 页面时,您正在更新该页面的母版。例如:

public void OnSomeRandomButtonClick(object sender, EventArgs e)
{
  ((SiteMaster)this.Page.Master).mySpan.Text = "Some Text";
}

您在此处所做的是更新母版页上的跨度在发送到您的浏览器之前。另一个微妙之处是,您不是在创建新的 SiteMaster,而是在使用页面的现有 Master 并将其转换为 SiteMaster。

您不能使用 ajax 执行此操作有几个原因:

  • Web 服务没有 MasterPage
  • 在您发送 ajax 请求时,您的母版页已经创建并发送到浏览器。

所以你的问题变成了我们如何在不发回服务器的情况下更新 Master 中的 span?

让我们看看实际在您的盒子上的 html,它看起来像这样:

<html>
  <head>
    <title>My Awesome Page</title>
  </head>
  <body>
    <h1>This is my Awesome Website</h1>
    <span id="mySpan">I'm sure you'll like it</span>
    <div>
      <p>Page Content</p>
    <div>
  </body>
</html>

假设这里的所有内容都是由 master 生成的,并且只有 &lt;p&gt;Page Content&lt;/p&gt; 是您的 aspx 页面(还会添加大量 ASP.NET 垃圾,我们暂时忽略它)。

您要做的是更新mySpan 中的文本,而不发回服务器。您可以通过 javascript 执行此操作 - 根本不涉及 ajax!

我假设您使用的是 jQuery(主要是因为我对它比普通的旧 JS 更熟悉)。您已经获得了跨度的 ID(“mySpan”),剩下的就很简单了:

$('#mySpan').html('This is the updated message');

您可以将其置于点击或页面加载中。

【讨论】:

  • 我真的很喜欢你的观点,这是一种与我完全不同的方法,它是客户端 :)
  • 我想你可能刚刚从“在它被发送到你的浏览器之前”的角度击中了头。由于 ajax 调用的性质(在页面加载时),我忘记了页面已经加载的事实(在我的情况下,它已加载,而不是相反)所以显然我无法对主页面进行任何更改页。我不会费心详细介绍我实际尝试做的事情,但解决我想要做的事情的唯一方法是从 AJAX 调用返回一个变量并通过 jQuery 更新页面,如您所说。您的 cmets 帮助我朝着正确的方向前进,谢谢!
  • @James 很高兴我们能提供帮助
【解决方案2】:

没有。您不能简单地构建一个 ASP.NET 页面并使用它的state

ASP.NET 页面(以及控件和母版页)正在根据为它们提供的标记从 ASP.NET 引擎内部构建和初始化。例如,在您的母版页的 codeBehind 内没有对 mySpan 的初始化,当基于标记生成的代码根据用户请求被调用时,该初始化将被构造。

所以你在你的类中定义这个:

protected HtmlGenericControl mySpan;

但是 ASP.NET 引擎会编译这个标记

<span id="mySpan" style="color:green"></span>

到此代码:

this.mySpan = new HtmlGenericControl();
this.mySpan.Style.Add("color", "green);

这就是为什么你可以在你的代码中使用这个对象。

因此,如果您想从业务层使用母版页的属性,您有很多选择。最快的实现方法之一是在Session 范围内创建Logic 类单例,将要在母版页内使用的值存储到该单例对象中,然后从母版页读取该值。这是你应该做的一个例子,当然是粗略的。

class Logic
{
   public static Logic Instance
   {
      get
      {
          if (HttpContext.Current.Session["LogicInstance"] == null)
              HttpContext.Current.Session["LogicInstance"] = new Logic();
          return (Logic) HttpContext.Current.Session["LogicInstance"];
      }
   }

   public string TextForSpan {get;}

   // The rest of your implementation
}

代替分配内部文本的代码,写:

Logic.Instance.TextForSpan = "This is my text";

在您的母版页中:

this.mySpan.InnerText = Logic.Instance.TextForSpan;

【讨论】:

  • 很好的答案 - 我仍然不是 100% OP 正在尝试做的事情,但我认为在我们两个之间,我们已经涵盖了大部分选项!
  • 同意!多种选择
  • @Alireza 这是一个非常有趣的选项。我正在考虑一个简单的解决方案,如下所示:当用户登录时,我为“mySpanString”创建会话。每当我调用 mySpan 的当前更新(从内容页面工作)时都可以更新这个值,但我也可以使用 HttpContext.. 在逻辑层强制更新,然后,当返回所有 AJAX 调用时,我只需检查mySpanString 会话的值并将其与所有当前的 AJAX 调用一起返回,然后使用 jQuery 进行更新。不完全是我最初的想象,但可以工作......你觉得呢?
  • 它会起作用的。要记住的重要一点是我的答案的第一段和第二段。其余的是实现细节,取决于您的设计。在这种特殊情况下,@Liath 的答案比我的要好,因为这是您想要对 AJAX 请求执行的操作,并且该方法不需要 Session 变量。但是,您可以混合使用这两种方法:他在请求之后立即更新跨度,而我的在从服务器刷新页面“之后”保持更新。
  • @Alireza 问题是 Liath 的回答没有为我提供解决方案。我有三种不同类型的案例,可能需要我更新跨度。在页面加载(服务器端)、页面加载(ajax 调用)和页面加载之后(n 个 ajax 调用)。这意味着让所有三种情况都起作用的唯一方法是使用 Session。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 2016-06-28
  • 1970-01-01
相关资源
最近更新 更多