4
votes

I'm using Umbraco CMS. I have the following model:

 public class LoyaltyPromo : RenderModel
    {
        public LoyaltyPromo(IPublishedContent content)
            : base(content)
        {
        }
        //properties removed for brevity
    }

I want to use this model inside UmbracoApiController. So i do this:

    public class PromoServiceController : UmbracoApiController
        {
            public async Task<object> GetAll()
            {

                var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
                IPublishedContent content = umbracoHelper.TypedContent(1050);
                var list = new List<LoyaltyPromo>();
                list.Add(new LoyaltyPromo(content));
                return list;

            }
        }

Unfortunately it doesn't work, i get the NullReferenceException:

Screenshot where the exception occurs

An error has occurred. Object reference not set to an instance of an object. System.NullReferenceException at Umbraco.Web.Models.RenderModel..ctor(IPublishedContent content) at LoyaltyOps.Models.LoyaltyPromo..ctor(IPublishedContent content) in C:\Users\mkallingal\documents\visual studio 2015\Projects\LoyaltyOps\LoyaltyOps.Models\LoyaltyPromo.cs:line 13 at LoyaltyOps.Controllers.PromoServiceController.d__0.MoveNext() in C:\Users\mkallingal\documents\visual studio 2015\Projects\LoyaltyOps\LoyaltyOps\Controllers\PromoServiceController.cs:line 32 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.TaskHelpersExtensions.d__3`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()

How can i resolve this?

1
I think you're going to need to extend your code example so we can see LoyaltyPromo.cs:line 13 where it says the null reference is occurring?ProNotion
Hi @ProNotion, 13th line is public LoyaltyPromo(IPublishedContent content) : base(content) { }Irshu
You are taking the publishedcontent node using a hardcoded id, eg. 1050. Are you sure this id exists?Mivaweb
Hi @Mivaweb, yes it exists. I copied it from Umbraco ->Content->Promos-List (content name) -> Id (from the Properties tab) . IPublishedContent content = umbracoHelper.TypedContent(1050); returns all the info of the content; it's not null.Irshu
I see you are using async task, check this solution on stackoverflow: stackoverflow.com/questions/23006976/…Mivaweb

1 Answers

4
votes

Your problem is that RenderModel is not intended to be used within WebAPI, which has no context regarding a front end page at all. Internally RenderModel is relying on the PublishedContentRequest property of UmbracoContext being set properly, which doesn't happen with WebAPI.

If you really do need to base your model on RenderModel, then use the alternative constructor:

RenderModel(IPublishedContent content, CultureInfo culture)

And pass in the culture as well as the content - this will get around the need for PublishedContentRequest being set, but you may run into other problems further on.

The better approach would be to create a view model that doesn't rely on RenderModel at all. Since WebAPI typically serialises your model to JSON anyway, the lighter you can make it the better.

One other thing - your listing for GetAll() doesn't return at all - I assume there's no extra processing going on in your actual method that requires your model to be based on RenderModel, and you're just returning the list?