Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • crono 58 posts 129 karma points
    Apr 19, 2016 @ 07:31
    crono
    0

    Dude, where's my ContentService?

    Just upgraded our project to the latest 7.4.3 from 7.2.4.

    As expected, a lot of things changed - including how you are able to call the ContentService.

    We used to be able to create an instance by simply using:

    new ContentService();
    

    Not so much anymore. I've tried various solutions posted on the net, but none of them give me the HttpContext that is needed for the CS to SaveAndPublishWithStatus fx.

    It works fine in SurfaceControllers, but anywhere outside of that - it fails, as the httpContext is null.

    Anyone here able to shed some light on the proper use of the CS when not accessed from within a SurfaceController?

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Apr 19, 2016 @ 07:46
    Jeavon Leopold
    0

    Should find it at ApplicationContext.Current.Services.ContentService (should always have been accessing it like this)

    https://our.umbraco.org/Documentation/Reference/Management/Services/ContentService

  • crono 58 posts 129 karma points
    Apr 19, 2016 @ 07:57
    crono
    0

    Yes, that's how I'd do it normally too.

    But when using ApplicationContext.Current.Services.ContentService to save/publish - the HttpContext is null.

    There is no issue with getting ids from the service though. Only the saving and publishing fails, due to lack of context.

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Apr 19, 2016 @ 07:59
    Jeavon Leopold
    0

    Services doesn't require HttpContext?

  • crono 58 posts 129 karma points
    Apr 19, 2016 @ 08:09
    crono
    0

    Well, that's what it is complaining about when trying to SaveAndPublishWithStatus. :S

    A value cannot be null. Parameter name: httpContext
    

    It's able to grab nodes by ids, but not save any changes made to them.

    Edit: Stack trace

       ved System.Web.HttpContextWrapper..ctor(HttpContext httpContext)
       ved Umbraco.Web.SingletonHttpContextAccessor.get_Value()
       ved Umbraco.Web.RequestLifespanMessagesFactory.Get()
       ved Umbraco.Core.Services.ContentService.SaveAndPublishDo(IContent content, Int32 userId, Boolean raiseEvents)
       ved Umbraco.Core.Services.ContentService.Umbraco.Core.Services.IContentServiceOperations.SaveAndPublish(IContent content, Int32 userId, Boolean raiseEvents)
       ved Umbraco.Core.Services.ContentService.SaveAndPublishWithStatus(IContent content, Int32 userId, Boolean raiseEvents)
    
  • Lee 1130 posts 3088 karma points
    Apr 19, 2016 @ 10:51
  • crono 58 posts 129 karma points
    Apr 19, 2016 @ 11:37
    crono
    0

    Thanks for chiming in.

    It doesn't really help, unfortunately, as I need to save/publish the node(s) after I retrieved and modified them (unless there is a way to make the helper do that?).

    As stated; I can get all the IContent, no problem, but as soon as I try to SaveAndPublishWithStatus, it gives me the exception.

    I'm trying to do this inside an UmbracoApplication, in case that'll give any clues.

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 7x c-trib
    Apr 19, 2016 @ 12:14
    Lars-Erik Aabech
    100

    If you're in a place without any http context, you can just fake it using HttpContext.Current = new HttpContext(fake objects).

    Previous to the SingletonHttpContextAccessor we had an ever tighter dependency on HttpContext, so it's moving in the right direction. :)

    However, you should not create services yourself. You should let Umbraco give them to you. The content service (should) always work when accessed via ApplicationContext.Current.Services.ContentService.

    [edit]: We do SaveAndPublishWithStatus using this branch of @sitereactor's samples. However, we have to add some silly sitemap provider while using it.

  • crono 58 posts 129 karma points
    Apr 20, 2016 @ 10:12
    crono
    0

    Sorry for the late reply and thank you for the hint.

    While this does indeed seem to work - I'm curious to know if there is any validity to this statement, posted in Lee's link :

    NEVER do that, you don't need to set the HttpContext.Current to something, there's a reason it is null, it is not in a web context. If you want an UmbracoContext outside of a request, you can create your own http context (standalone) and just pass it in. Never set the HttpContext.Current, bad things will happen because many threads rely on the check to see if it exists to determine if it is a web request and that is how it manages request lifespans for certain objects.

    What are your thoughts on that?

  • Nastassia 2 posts 72 karma points
    Nov 14, 2019 @ 11:46
    Nastassia
    0

    @crono,

    Topic that you quoted can be true. But in case when you try update content in asynchronous task from api controller or in process of HttpTaskAsyncHandler before save or save and publish (with status) you need ensure HttpContext.Current (not UmbracoContext.Curent) if not exist. When you process synchronous task HttpContenxt.Curent presented.

    We had this issue in project and solved by this way:

    public static class ContextHelper
    {
        private static readonly object SynchObject = new object();
    
        public static void EnsureFakeHttpContextIfNone()
        {
            if (HttpContext.Current == null)
            {
                lock (SynchObject)
                {
                    if (HttpContext.Current == null)
                    {
                        HttpContext.Current = new HttpContext(new SimpleWorkerRequest("dummy.aspx", "", new StringWriter()));
                    }
                }
            }
        }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft