Why my contentItem is null?

Topics: Developer Forum
Sep 24, 2008 at 2:09 AM
Error message is "Value cannot be null.Parameter name: item "

I make a MyTextItem.ascx and want put it on zone in start page.

mycode:

[Definition("My Text Item", "MyTextItem")]
    [AllowedZones("MainContentSidebar", "RightSidebar")]
    public class MyTextItem : AbstractItem
    {
        [EditableFreeTextArea("Text", 100)]
        public virtual string Text
        {
            get { return (string)(GetDetail("Text") ?? string.Empty); }
            set { SetDetail("Text", value, string.Empty); }
        }

        public override string TemplateUrl
        {
            get { return "~/Views/Shared/MyTextItem.ascx"; }
        }

        public override string IconUrl
        {
            get { return "~/Img/text_align_left.png"; }
        }
    }

When I click new button and type some texts and save, the error was thrown, I wanna traced the error and found N2.Web.UI.WebControls.Display.ContentItem is null, so the error was thrown by "GetDisplayableAttribute(PropertyName, CurrentItem)"

Please help me

Coordinator
Sep 24, 2008 at 7:10 AM
So MyTextItem.ascx has a button which is doing a postback? Where is the actual Display? Can you post a stack trace?
Sep 24, 2008 at 11:09 AM
When I create a MyTextItem I got the error, it was not display in the page, stack trace as below, thanks a lot!
[ArgumentNullException: Value cannot be null.
Parameter name: item]
   N2.Web.UI.WebControls.Display.Throw(Exception ex) in D:\Work\N2CMS\Carebase\N2\Web\UI\WebControls\Display.cs:163
   N2.Web.UI.WebControls.Display.GetDisplayableAttribute(String propertyName, ContentItem item) in D:\Work\N2CMS\Carebase\N2\Web\UI\WebControls\Display.cs:138
   N2.Web.UI.WebControls.Display.get_Displayable() in D:\Work\N2CMS\Carebase\N2\Web\UI\WebControls\Display.cs:31
   N2.Web.UI.WebControls.Display.AddDisplayable() in D:\Work\N2CMS\Carebase\N2\Web\UI\WebControls\Display.cs:108
   N2.Web.UI.WebControls.EditableDisplay.OnInit(EventArgs e) in D:\Work\N2CMS\Carebase\N2\Web\UI\WebControls\EditableDisplay.cs:44
   System.Web.UI.Control.InitRecursive(Control namingContainer) +333
   System.Web.UI.Control.AddedControl(Control control, Int32 index) +198
   System.Web.UI.ControlCollection.Add(Control child) +80
   System.Web.UI.Control.AddParsedSubObject(Object obj) +41
   System.Web.UI.Control.System.Web.UI.IParserAccessor.AddParsedSubObject(Object obj) +10
   ASP.views_shared_mytextitem_ascx.__BuildControlTree(views_shared_mytextitem_ascx __ctrl) in d:\Work\N2CMS\Carebase\wwwroot\Views\Shared\MyTextItem.ascx:1
   ASP.views_shared_mytextitem_ascx.FrameworkInitialize() in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\6ecd4400\3ceb49b5\App_Web_hmlx97cw.1.cs:0
   System.Web.UI.UserControl.InitializeAsUserControlInternal() +35
   System.Web.UI.UserControl.OnInit(EventArgs e) +68
   System.Web.UI.Control.InitRecursive(Control namingContainer) +333
   System.Web.UI.Control.InitRecursive(Control namingContainer) +210
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +378
Coordinator
Sep 24, 2008 at 7:22 PM
Is your user control's code behind class implementing N2.Web.UI.ContentUserControl? If the user control doesn't implement IContentTemplate it won't get it's ContentItem updated and you could get that error.
Sep 25, 2008 at 1:42 AM
Edited Sep 25, 2008 at 4:20 AM
MyTextItem.ascx.cs code as below:
namespace Carebase.Views.Shared
{
    public partial class MyTextItem : N2.Web.UI.ContentUserControl<Carebase.Models.MyTextItem>
 {
 }
}

I modified the code follow you suggestion and null value exception has gone but another error occured.
The error occured by these defaultView.aspx as below:
<% foreach (N2.ContentItem part in ViewData.Model.GetChildren("MainContentSidebar")){ %>
   <% Html.RenderPartial(part.TemplateUrl, part); %>
<% }%>

Stack Trace:
[InvalidOperationException: The view at '~/Views/Shared/MyTextItem.ascx' must derive from ViewPage, ViewPage<TViewData>, ViewUserControl, or ViewUserControl<TViewData>.]
   System.Web.Mvc.WebFormView.Render(ViewContext viewContext, TextWriter writer) +513
   System.Web.Mvc.ViewResult.ExecuteResult(ControllerContext context) +364
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ActionResult actionResult) +105
   System.Web.Mvc.<>c__DisplayClass12.<InvokeActionResultWithFilters>b__f() +39
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +385
   System.Web.Mvc.<>c__DisplayClass14.<InvokeActionResultWithFilters>b__11() +61
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ActionResult actionResult, IList`1 filters) +386
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +736
   System.Web.Mvc.Controller.ExecuteCore() +180
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +96
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +36
   System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +377
   System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +71
   System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +36
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

Are some problems with my code?

Coordinator
Sep 25, 2008 at 4:34 PM
Didn't realise you were using asp.net mvc. That changes things. Maybe you should reconsider using the display control in the first place.

However to make it work try something along the lines:

public class MyUserControl : ViewUserControl<ContentItem>, N2.Web.UI.IItemContainer
{
  public ContentItem CurrentItem
  {
    get { return Model.Data; }
  }
}

What happens is that the display control looks in the control hierarchy to find a control that implements that interface.
Jun 11, 2009 at 1:28 PM

I'm having similar problems with my N2 in ASP.NET MVC.

Maybe the API changed, but I can't access Model.Data from my UserControl.

 

The problem I'm encountering is that Model in my ASCX represents the model of the page, not the model of the usercontrol. So the question is: how do I access the information that I entered in editmode of the usercontrol from within the ASCX page?

Coordinator
Jun 11, 2009 at 11:19 PM

How are you rendering your user control?

Jun 15, 2009 at 8:54 AM

My CS file:


using N2.Integrity;

namespace Myol.Dal.Models.ContentParts
{
  [AllowedZones("NarrowZone")]
  public class TestControl : N2.ContentItem
  {

    public override string TemplateUrl
    {
      get
      {
        return "~/UserControls/TestControl.ascx";
      }
    }

    public override bool IsPage
    {
      get
      {
        return false;
      }
    }
  }
}

 

My ASCX file:


<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TestControl.ascx.cs" Inherits="Myol.UserControls.TestControl" %>
<div>TestControl!</div>

<div><%= CurrentItem.Title %></div>

 

The error I receive:


Cannot cast the current page gevoel#17 from type 'Myol.Dal.Models.ContentTypes.Theme' to type 'Myol.Dal.Models.ContentParts.TestControl' required by this template.

 

So the CurrentItem variable refers to the Theme (of the page itself) and not to the TestControl (of the usercontrol)

I hope this clarifies!

Jun 15, 2009 at 8:55 AM

Owh, and the ASCX.CS file:

 


namespace Myol.UserControls
{
  public partial class TestControl :
    N2.Web.UI.ContentUserControl<Myol.Dal.Models.ContentParts.TestControl>
  {

  }
}

 

Coordinator
Jun 15, 2009 at 8:36 PM

Are you adding TestControl to a page "Theme" via drag and drop? If so you should use the second generic overload for the user control:

namespace Myol.UserControls
{
  public partial class TestControl :
    N2.Web.UI.ContentUserControl<Myol.Dal.Models.ContentParts.Theme, Myol.Dal.Models.ContentParts.TestControl>
  {
  }
}

TPage is the page type, and TItem is the part type.

Jun 15, 2009 at 8:45 PM

Yesss that's the solution!

That list is going to get quite long if I have to include all the possible usercontrols that could be on those pages. Is this really the way to go?

Coordinator
Jun 15, 2009 at 9:19 PM

You can also use a shared type:

namespace Myol.UserControls
{
  public partial class TestControl :
    N2.Web.UI.ContentUserControl<N2.ContentItem, Myol.Dal.Models.ContentParts.TestControl>
  {
  }
}