来自逻辑层的主页中的C#访问元素

时间:2014-07-17 07:43:54

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

我有一个连接到母版页的内容页面。我可以访问母版页上的元素,并通过调用站点主页上的方法直接从内容页面.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”。

有谁知道如何解决这个问题?我所做的每一次搜索都是关于那些想要访问已经适合我的内容页面中元素的人。

2 个答案:

答案 0 :(得分:2)

我相信你在这里有误会。如果我理解正确,你有一个包含MasterPage的页面。在那个aspx页面上,你正在做一个ajax调用(也许是一个WebService),它做了类似的事情:

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

这里有一些问题。

当您使用此方法时,您将更新该页面的主页。例如:

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

您在此处所做的是在母版页发送到您的浏览器之前更新母版页上的范围。另一个巧妙的是,您没有创建新的SiteMaster,您正在使用Page的现有Master并将其投射到SiteMaster。

有几个原因你不能用ajax做到这一点:

  • 网络服务没有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生成的,只有<p>Page Content</p>是你的aspx页面(还会添加大量的ASP.NET垃圾,我们暂时会忽略它。) / p>

您要做的是更新mySpan中的文字而不回发到服务器。你可以通过javascript做到这一点 - 根本不涉及ajax!

我将假设您正在使用jQuery(主要是因为我更熟悉普通的旧JS)。你有你的跨度ID(“mySpan”)所以其余的很容易:

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

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

答案 1 :(得分:2)

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

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

所以你在课堂上定义它:

protected HtmlGenericControl mySpan;

但ASP.NET引擎将编译此标记

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

到此代码:

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

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

因此,如果您想从Business层使用Master页面的属性,那么您有很多选择。实现最快的是在Logic范围内创建Session类单例,将要在主页内使用的值存储到该单例对象中,然后从主节点读取该值页。这是你应该做的一个例子,当然它很粗糙。

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;