How to get info from a programmatically saved page...
# help-with-umbraco
c
V13.2.2 In a WorkFlow I've saved a new page and want to get the URL of one of it's images, to send of to an external API, before the Workflow completes. So far I have this:-
Copy code
var pageRef = _contentService.SaveAndPublish(advertiserPage);

        GuidUdi adPageUdi = pageRef.Content.GetUdi();
        var adPage = _contentService.GetById(adPageUdi.Guid);  // <--- Seems to be ok so far!
        
        var logoImageRef = adPage.GetValue("logoImage") as Udi;  // <--- I get Null here although the image exists in the saved page
        IMedia logoImage = _mediaService.GetById(logoImageRef.AsGuid());
I've been round and round this and can't work it out. Actually I could also do with the URL for the page itself as well. Any pointers would be appreciated. Thanks.
Second go with....
Copy code
var pageRef = _contentService.SaveAndPublish(advertiserPage);
      int adPageId = pageRef.Content.Id;
        AdvertiserPage? pageFromId = null;
        
        if(_queryAccessor.TryGetValue(out var query))
        {
            pageFromId = query.Content(adPageId) as AdvertiserPage; // <--- Null :(
        }

        if (pageFromId is not null) {
            string logoImageUrl = pageFromId.LogoImage.Url();
        }
Head scratching continues........
j
Had a quick look at this, and in your top example you do this:
Copy code
csharp
var logoImageRef = adPage.GetValue("logoImage") as Udi;
Which as far as I can see is never going to work, as the value of a mediaPicker v3 is a json blob which can't immediately be turned into a udi. Fx with a simple imagepicker allowing only one image and with no local crops I had a value like this:
Copy code
json
[{"key":"810d0061-b59e-4017-a2dc-bdba544b038c","mediaKey":"276b48e4-f241-428c-8411-133454977781"}]
Where mediaKey is the one you want to use. The interesting thing is I couldn't get it to get the value of the property even as a string, not really sure why.. Your 2nd example worked for me though, I don't have the modelsbuilder models you have obviously but getting the page as IPublishedContent through the publishedQueryAccessor worked just fine and I could get the image as MediaWithCrops as expected.
Copy code
csharp
var adPage = _contentService.GetById(content.Id);

if (_publishedContentQueryAccessor.TryGetValue(out var query) && adPage is not null)
{
    var page = query.Content(adPage.Id);
    var image = page?.Value<MediaWithCrops>("imagePicker"); // gets an image reference
}

var logoImageRef = adPage?.GetValue("imagePicker");  // always null
NOTE: Getting it through the IPublishedContentQueryAccessor will only get the latest Published version, so may not be the right workaround anyways for your needs
c
In my equivalent adPage has a reference, but pageFromId ends up as null.
Copy code
var adPage = _contentService.GetById(pageRef.Content.Id);

if(_queryAccessor.TryGetValue(out var query) && adPage is not null)
{
   var pageFromId = query.Content(adPage.Id);
   
   var theLogoImage = pageFromId?.Value<MediaWithCrops>("logoImage");
   var logoImageUrl = theLogoImage.Url();
}
j
If the page has never been published before then it will return null as the queryAccessor only gets published content, and that is part of why this is not necessarily a good solution
c
But the page has "just" been published. That's the
var pageRef = _contentService.SaveAndPublish(advertiserPage);
at the top of my second example. And the ContentService returns a page. So is there any other way of getting the URL's of the images on the page that's just been published if not using the QueryAccessor?
And another failed attempt. This time injecting
IUmbracoContextFactory context
😦 :-
Copy code
var pageRef = _contentService.SaveAndPublish(advertiserPage)

var adPage = _contentService.GetById(pageRef.Content.Id);

using (var ctxRef = _umbracoContextFactory.EnsureUmbracoContext())
  {
      var publishedAdPage = ctxRef.UmbracoContext.Content.GetById(adPage.Id);

      if (publishedAdPage != null) <-- Is Null!!
      {
          var content = _contentService.GetById(adPage.Id);

          content = _contentService.GetVersion(content.PublishedVersionId);

          if (publishedAdPage.UpdateDate.Equals(content.PublishDate))
          {
              parameters.Add("advertiserPageUrl", publishedAdPage.Url());
              
              var publishedLogoImage = publishedAdPage.Value<MediaWithCrops>("logoImage");
              
              parameters.Add("advertiserPageUrl", publishedLogoImage.Url());
          }
      }
  }
Following these posts and discussions on FB have decided it's not possible. Probably due to the new page not being cached in time. Have therefore reluctantly re-engineered the solution.
j
I'm sure it's possible, so I'm not sure what's going on here. I thought publishing was synchronous...
c
Just reposting my reply from FB as it sort of covers it...... This is a UF custom workflow where we create a page and also send the data and URLs off to a legacy system. So it all needs doing at once really. Anyway, I've decided it can't be done so I'm just sending the GUID of the page instead, because it's about the onlything I can get hold of, which means when they send their manufactured HTML back (don't ask!, lol) I'll have to regex for the GUIDs and replace URL's and Image srcs. Would have been MUCH more efficient if I could have just sent the URLs in the first place, but Umbraco says NO.
64 Views