用户控件中的asp:Literal控件为空。

5

我有一个用户控件,其中包含 asp:Literal。

<div>
     <asp:Literal id="MenuContainer" runat="server" />
</div>

在代码后台页面中有一个方法,用于初始化控件:
internal void Setup(MyBusinessObject obj)
{
    MenuObject menu = MenuHelper.GetMenu(obj.State);

    if(obj == null)
        MenuContainer.Visible = false;

    //other code
}

在使用该控件的页面中,我在 LoadComplete 事件处理程序中调用控件的 Setup 方法(我最初是在 Load 事件中调用它)。无论 MyBusinessObject 是否为null,当我访问用户控件上的 Literal 时都会出现错误。
Object reference not set to an instance of an object.

这是什么原因,有什么解决方法?

它对我来说运行得很好。可能有其他问题。尝试编译整个网站。顺便问一下,您能够正确访问该用户控件中的其他控件吗? - Kirtan
实际上,这是用户控件中唯一的控件。 - TheVillageIdiot
7个回答

11

这很简单。我正在向web.config的controls部分添加东西,正如Rick Sthral在他的一篇文章中建议的那样(:( 忘记了这篇文章,你将不得不在他的页面上搜索)。

这使我能够很好地添加控件而不需要放置@ Register标记,但缺点是我的控件上的子控件被显示为null!因此,我只需在我的页面中放置@ Register指令即可解决问题。


+1,谢谢!但是有人能解释一下这个毫无意义的解决方案吗?难道web.config快捷方式不应该消除在页面标记中添加Register指令的需要吗?如果我们必须把它放在那里以防止出现奇怪的错误,那还有什么意义呢?好了,</rant>。 - Sean Hanley
@Yadyn,这就是我无法理解的地方。我在Rick的博客上留言了,但没有得到任何回复。 - TheVillageIdiot

5

这取决于您在web.config中包含控件的方式。如果您尝试在命名空间中包含所有控件,它将无法工作(尽管设计器会正确显示您的控件列表):

<add tagPrefix="prefix" namespace="example.ui.controls" assembly="example.ui" />

但是,如果您逐个添加控件并指向它们的实际位置,则可以按预期工作,而无需包含无尽的@Register指令。

<add tagPrefix="prefix" tagName="Message" src="~/Controls/Message.ascx" />

1

感谢TheVillageIdiot发布了解决方案 - 我遇到了完全相同的误解。

通过添加控件

<add tagPrefix="user" namespace="Frontend.Web.UserControlsAccount" assembly="Frontend.Web" />

在web.config中并不足以实际使用它!我尝试在页面上这样使用:

<user:ucLoginMessages runat="server" ID="Msgs" />

...但这将导致这种现象,即UserControl内的控件都没有被初始化。只有添加

<%@ Register Src="~/UserControlsAccount/LoginMessages.ascx" TagPrefix="user" TagName="Messages" %>

回到页面顶部解决了问题 :-)

再次感谢!


0

正如JerSchneid的回答中所提到的,如果obj为空,则会出现该错误。 因此,请尝试像这样做 -

internal void Setup(MyBusinessObject obj)
{
    if(obj == null)
        MenuContainer.Visible = false;
    else
        MenuObject menu = MenuHelper.GetMenu(obj.State);
}

编辑:我知道你在那一行代码上遇到了错误,但是试着按照这种方式来做。否则,删除整个代码,只保留MenuContainer.Visible = false;这一行。


亲爱的,obj 不是 null,只有 MenuContainer 是 null。这就是我感到困惑的原因。 - TheVillageIdiot

0
你发布的代码如下:
internal void Setup(MyBusinessObject obj)
{    
    MenuObject menu = MenuHelper.GetMenu(obj.State);    

    if(obj == null)        
        MenuContainer.Visible = false;    //other code
}
  • 如果 obj 为 null,则在第一行对 obj.State 的解引用将抛出 NullReferenceException

  • 如果 obj 不为 null,则该行 MenuContainer.Visible = false 不会被执行。

所以我认为您没有发布所有相关的代码。

当您在调试此类问题时,请尝试使用调试器逐步执行代码或向您的代码添加一些断言,这将帮助您准确地了解发生了什么:

internal void Setup(MyBusinessObject obj)
{    
    Debug.Assert(obj != null);
    MenuObject menu = MenuHelper.GetMenu(obj.State);    

    Debug.Assert(MenuContainer != null);
    if(obj == null)        
        MenuContainer.Visible = false;    //other code
}

0

如果MenuContainer为null,则可能与页面的生命周期时间线有关。您在链接MenuContainer之前调用该函数。您可以尝试在Page_Load函数中调用Setup吗?


0
你确定 MenuContainer 是问题所在吗?因为在 Setup 函数的第一行中,你引用了 obj.State。如果那个 obj 是 null,你就会得到那个错误。

是的,这就是问题所在。如果(obj == null)通过了,而MenuContainer.Visible会抛出异常。 - TheVillageIdiot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接