【问题标题】:How to call non-static method from static method in an aspx.cs code-behind如何从 aspx.cs 代码隐藏中的静态方法调用非静态方法
【发布时间】:2011-11-18 20:41:07
【问题描述】:

在其他地方提出了类似的问题,但答案似乎不适用于我的特定情况。
我在 aspx 页面上有一个隐藏字段:

<asp:HiddenField ID="dataReceiver" runat="server" Value="" />

我正在尝试从代码隐藏中访问此字段。似乎我必须从 VS2010 自动生成的默认类中引用它。由于我无法创建新课程,我尝试了以下方法。

1public partial class _Default : System.Web.UI.Page
2{
3   protected void Page_Load(object sender, EventArgs e)
4   {
5       Data2();
6       MessageBox.Show(dataReceiver.Value);
7   }

8   public void Data1()
9   {
10      dataReceiver.Value = "123456";
11  }

12  public static void Data2()
13  {
14      _Default def = new _Default();
15      def.Data1();
16  }
17}

这会在第 10 行生成错误:“对象引用未设置为对象的实例。”

我也尝试将第 14 行输入为“_Default def = new _Default().Data1();”但这被编译器拒绝并显示错误:“无法将类型'void'隐式转换为'WebApplication6._Default'”

有没有办法让这个工作,或者我需要一个完全不同的方法?

[编辑] 下面达林的回答为我解决了这个问题,但我确实花了一些时间来弄清楚如何应用这些信息。我想我应该澄清解决方案的细节,以防以后有人遇到类似问题。
尽管 WebMethod 不能调用实例方法,而且它似乎无法访问页面元素,而不管它们的“runat”属性如何,但它可以向调用它的 JavaScript 方法返回一个值。该值可以在 JavaScript 中作为名为“result”的局部变量访问,该变量被传递给“success”或“failure”函数。

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager id="scriptManager1" runat="server" EnablePageMethods= "true" />
<asp:HiddenField ID="dataReceiver" runat="server" Value="789" />
</asp:Content>
//Javascript
function callServer() {
    PageMethods.Data2($("#MainContent_dataReceiver").attr("value").toString(), success, failure);

    function success(result, userContext, methodName) { alert(result + " . " + userContext + " . " + methodName); }
    function failure(result, userContext, methodName) { alert(result + " . " + userContext + " . " + methodName); }
}
//C# Code Behind
[WebMethod]
public static string Data2(string value)
{
    value = "101112";
    return value;
}

【问题讨论】:

  • 您拥有此控件的.aspx 页面上的@Page 指令是什么样的?
  • 为什么不直接从Page_Load方法调用Data1呢?
  • @ThomasLevesque - 因为您需要一个类的实例来调用 Data1。
  • @JonH,在 Page_Load 方法中,您已经在 _Default... 的实例中...
  • @ThomasLevesque 确实,我不知道 OP 的意图是什么,就像困惑一样。

标签: c# asp.net code-behind static-methods object-reference


【解决方案1】:

您无法从 ASP.NET 中的 PageMethod 访问实例字段,我怀疑这是您在此处尝试实现的目标。就是这样,您对此无能为力。所以我建议你只是让你的页面方法将隐藏字段的值作为参数:

public static void Data2(string value)
{
    ... do something with the value of the hidden field
}

现在让页面方法的调用者提供所需的值,因为它在页面的上下文中。

【讨论】:

  • 不开玩笑。我以为我说得更清楚了,但我肯定忘了包括一些细节。
【解决方案2】:

目前还不清楚这里发生了什么 - 你想要实现什么。您收到错误消息的原因可能是 _Default 的无参数构造函数未将 dataReceiver 设置为有用的值。

Data2()需要是静态方法有什么原因吗? 逻辑上应该调用Data1() 什么?您不应该仅仅因为需要在 some 实例上调用 Data1() 而决定,只需创建 _Default 的新实例并在其上调用它就可以了。找出调用的逻辑目的,这应该表明您需要在哪个实例上调用Data1() - 或者这实际上是否应该是一个实例方法开始。

【讨论】:

  • 感谢乔恩的回复。 Data2 需要是静态的,因为在我从中提取此代码的原始程序中是一个 WebMethod。我很抱歉没有在我原来的帖子中提到这一点......
  • @BrandonRoss:如果是WebMethod,为什么需要引用页面实例?从逻辑上讲,该页面不存在。听起来这是您设计中的一个基本问题 - 暂时忽略实现,并考虑 逻辑 设计。
  • 我可以理解优秀设计的价值,但这远不是我正在从事的项目中唯一的潜在设计缺陷。我仍在学习,没有一位高级程序员在整个过程中牵着我的手。最终,如果必须,我会在空闲时间返回并重构整个事情。我一定会记住你的建议。谢谢!
【解决方案3】:

您为什么要创建一个新实例:_Default def = new _Default();,要访问它,请使用 dataReceiver.Value。如果控件指定runat=server,则意味着您可以从后面的代码中访问该控件。

为什么Data1 是实例方法?我们需要更多信息。

【讨论】:

  • 感谢乔恩的回复。 dataReceiver 在 Data2() 中不可用——我猜是因为它是静态的。它在 Data1() 中可用,但如果从 Data2 调用 Data1,则会导致运行时错误。我不确定我能回答为什么 Data1 是一个实例方法。我要做的就是在页面加载后更改 dataReceiver 的值,例如,当用户单击某物时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
相关资源
最近更新 更多