Surface controller - accessing node content and properties
I am creating a surface controller that needs to retrieve nodes from a nested content property, but I'm not sure of the correct way to access the property.
I am trying to do something like this:
var block = CurrentPage.Value<IEnumerable<IPublishedElement>>("blocks").Where("Visible").Skip(currentCount).Take(1);
I have tried lots of variations but can't find any examples that work - any help would be greatly appreciated. Instead of using 'CurrentPage' I could load the current page node using an ID if that helps, but I'm not sure how to do that in a surface controller either. I have tried this:
Hi Alex, I'm using version 8.0.1, here is the surface controller code. I've got lots of 'using' statements as I can't seem to use the 'IPublishedContent' type, and was trying a few things.
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Net;
using Umbraco;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.Mvc;
using Umbraco.Web.Models;
namespace MyNamespace.Controllers
{
public class MoreBlocksController : Umbraco.Web.Mvc.SurfaceController
{
public ActionResult LoadMoreBlocks(int currentCount, int moreCount)
{
//get nested content property node from current page
var block = CurrentPage.Value<IEnumerable<IPublishedContent>>("blocks").Where("Visible").Skip(currentCount).Take(1);
//or try to get it from content?? doesn't work either
IPublishedContent content = Umbraco.Content(1234);
block = content.Value<IEnumerable<IPublishedContent>>("blocks").Where("Visible").Skip(currentCount).Take(1);
return PartialView("Blocks/Image List Block", block, new ViewDataDictionary(this.ViewData) {
{ "blockCount", moreCount }
});
}
}
}
Hi jonok, I saw you question and I made an example. I manage to get the property values from textstring in a nested content. I don't know how this will work with media/member/content pickers. Hope you can make a start from that.
If someone has a better solution would be nice to share.
using System.Web.Mvc;
using Umbraco.Web.Mvc;
namespace Umbraco_8_tests.Controllers
{
public class TestingController : SurfaceController
{
public const string PARTIAL_VIEW_FOLDER = "~/Views/Partials/";
public ActionResult TestSurfaceController()
{
return PartialView(PARTIAL_VIEW_FOLDER + "_TestSurfaceController.cshtml");
}
[HttpPost]
public ActionResult testingSC()
{
dynamic nestedContent = Umbraco.Content(CurrentPage.Id).GetProperty("nc").GetValue();
foreach (var item in nestedContent)
{
System.Reflection.PropertyInfo pi = item.GetType().GetProperty("TextNC");
string itemValue = (string)(pi.GetValue(item, null));
}
return View();
}
}
}
Hi Thomas,
Thanks for that, it's definitely helping me understand surface controllers - however I am trying to get an Umbraco node to pass to the PartialView as the model. I'm hoping there is some way to access Umbraco nodes (eg. IPublishedContent) in a surface controller?
If I understand right, you need a form to post to the controller the pageId so you can access any node no matter the page you are.
Anyway generally speaking you can access the nodes as IPublishedContent on a Surface controller
All those are working
var homePage = Umbraco.Content(CurrentPage.Id);
var textString = homePage.Value("text");
var rte = homePage.Value("rte");
var image = homePage.Value<IPublishedContent>("image").Url;
I couldn't get this one to work
var nestedContent= homePage.Value<IEnumerable<IPublishedContent>>("nestedContent");
How many items are created in the nested content property? Are there many or just one?
If your Nested Content property editor is configured in single item mode, then the value converter will automatically know this and return a single IPublishedElement entity rather than an IEnumerable
Hi Thomas,
I can't get anything with IPublishedContent to work. I get the following error:
"The type or namespace name 'IPublishedContent' could not be found".
Do I need to declare anything at the top of the controller file to allow me to use IPublishedContent?
Hi Thomas,
I can't believe it was this simple but I was missing the 'using System.Linq;' declaration at the top of my surface controller. So to fix my original issue, it turns out all I needed was these 2 lines:
using Umbraco.Core.Models.PublishedContent;
using System.Linq;
2) I'm not sure whether you are posting the page to the SurfaceController or whether it's on pageload, if posting add the following to a hidden field.
var id = Model.NestedTest.ToList();
3) SufaceController
public ActionResult NestedContent(IEnumerable<IPublishedElement> id)
{
var publishedElements = id.ToList();
var components = publishedElements.ToList();
foreach (var data in components)
{
var testOuter = data.Value<HtmlString>("bodyText");
if (data.ContentType.Alias == "nestedThreeDoctype")
{
foreach (var item in data.Value<IEnumerable<IPublishedElement>>("nCThree"))
{
var testInner = item.Value<IHtmlString>("bodyText");
}
}
}
return null;
}
I have attached an image to show my backoffice layout, this is just me messing around with V8 but it should give you an idea of how to do what you want
Surface controller - accessing node content and properties
I am creating a surface controller that needs to retrieve nodes from a nested content property, but I'm not sure of the correct way to access the property.
I am trying to do something like this:
I have tried lots of variations but can't find any examples that work - any help would be greatly appreciated. Instead of using 'CurrentPage' I could load the current page node using an ID if that helps, but I'm not sure how to do that in a surface controller either. I have tried this:
but then I get the error "The type or namespace name 'IPublishedContent' could not be found".
Hi Jonok
What Umbraco version are you using? Can you show all the code you have?
Thanks,
Alex
Hi Alex, I'm using version 8.0.1, here is the surface controller code. I've got lots of 'using' statements as I can't seem to use the 'IPublishedContent' type, and was trying a few things.
Hi jonok, I saw you question and I made an example. I manage to get the property values from textstring in a nested content. I don't know how this will work with media/member/content pickers. Hope you can make a start from that.
If someone has a better solution would be nice to share.
Hi Thomas, Thanks for that, it's definitely helping me understand surface controllers - however I am trying to get an Umbraco node to pass to the PartialView as the model. I'm hoping there is some way to access Umbraco nodes (eg. IPublishedContent) in a surface controller?
Hi Thomas,
First of all - do not use "dynamic" type. Everything is strongly typed now.
This line not needed also -
You can always know which type to expect from the property.
Thanks,
Alex
Hi Alex, I used dynamic because I had an issue with this
it was always null, any thoughts why?
Cheers
Use this :
Didn't work..
this one works for me:
Didn't work either
Its not that I will have an error from this:
or this:
the issue is that returns always null
and those (wrong ways),return the 2 items I want to get. but as an object, no as IPublishedContent
If I understand right, you need a form to post to the controller the pageId so you can access any node no matter the page you are.
Anyway generally speaking you can access the nodes as IPublishedContent on a Surface controller
All those are working
I couldn't get this one to work
Hi Thomas
How many items are created in the nested content property? Are there many or just one?
If your Nested Content property editor is configured in single item mode, then the value converter will automatically know this and return a single IPublishedElement entity rather than an IEnumerable
Thanks,
Alex
Hi Thomas, I can't get anything with IPublishedContent to work. I get the following error: "The type or namespace name 'IPublishedContent' could not be found".
Do I need to declare anything at the top of the controller file to allow me to use IPublishedContent?
Hi Jonok, I had those, give it a try
Thanks Thomas - the Umbraco.Core.Models.PublishedContent was the one I was missing. So now when I try the following code:
...I get this error " 'IEnumerable
I can use this code inline within a view and it works fine, but I'm not sure why the Take(1) isn't possible in the surface controller?
Well probably its U8 issue.
Your problem should be the same with mine, IEnumerable IPublishedElement doesn't work (take(1) shouldn't be a problem )
I have use surface controllers in U7 many times and I had no issue.
You can try George Phillipson solution for now.
Hi Alex, there are two items
In this comment I made earlier you can see clearly the issue I described to you
https://our.umbraco.com/forum/umbraco-8/96911-surface-controller-accessing-node-content-and-properties#comment-306308
Cheers, Thomas
Hi Thomas, I can't believe it was this simple but I was missing the 'using System.Linq;' declaration at the top of my surface controller. So to fix my original issue, it turns out all I needed was these 2 lines:
Thanks for your help.
We are glad that it's solved.
I have been testing out V8 and here is an example of how I get the nested content to work.
1) I'm using modelbuilder so in my view I have:
2) I'm not sure whether you are posting the page to the SurfaceController or whether it's on pageload, if posting add the following to a hidden field.
3) SufaceController
I have attached an image to show my backoffice layout, this is just me messing around with V8 but it should give you an idea of how to do what you want
is working on a reply...