Our Forum has Moved

This site is our old forum and is only here for achive until we get proper 301 redirects setup to make Google happy.

Please use our new community site - Our Umbraco - which contains an improved forum, documentation wiki, package repository and a member locator.

Go to Our Umbraco now

Learn everything about Umbraco
Basic Question: Accessing Umbraco content from a UserControl using the API Options
dconlisk
Posted: Friday, March 21, 2008 11:14:29 AM

Rank: Aficionado

Joined: 10/19/2007
Posts: 161
Location: Glasgow, Scotland
Hello all,

I'm attempting to access an email address stored in Umbraco from a .NET User Control. I've added references to the dlls, etc. I have a content type called Resources, which stores an email address and a telephone number. I've created a content item where I store some sample values, and its id is 1235. I can access the name of the node like this no problem at all:

Code:

umbraco.cms.businesslogic.Content c = new umbraco.cms.businesslogic.Content(1235);
Response.Write(c.Text); // Output the node name to the page


but I can't access any of the properties of the node (ie the telephone number or the email address). I've tried using the ContentItem, Content and Document objects and I can access the Text for each but none of the content. I've tried using getProperty, and I've tried looping over getProperties, but the properties array is always of length zero.

Any ideas?

Thanks in advance,

David

Certified Umbraco developer
mortenbock
Posted: Friday, March 21, 2008 12:30:58 PM

Rank: Addict

Joined: 7/19/2006
Posts: 882
Location: Århus, Denmark
You should use the umbraco.presentation.nodeFactory namespace. This uses the content that is already stored in memory on the server, instead of looking in the database.

So you should be able to do something like:

Code:

umbraco.presentation.nodeFactory.Node n = new umbraco.presentation.nodeFactory.Node(1235);
Response.Write(n.GetProperty("emailadress").Value);


Morten Bock - Level 2 certified - MVP 2008/2009 - My danish blog with a few english posts

dconlisk
Posted: Friday, March 21, 2008 1:11:59 PM

Rank: Aficionado

Joined: 10/19/2007
Posts: 161
Location: Glasgow, Scotland
Thanks for the quick reply Morten! My issue now is this: even though I've added references to umbraco.dll and businesslogic.dll in my project, when I run this:

Code:
umbraco.presentation.nodeFactory.Node n = new umbraco.presentation.nodeFactory.Node(1235);


I get this exception being thrown:

Quote:
The type initializer for 'Nested' threw an exception.


Any ideas? I'm running the latest version of Umbraco (v3.0.3), everything is as up-to-date as I can get it.

Thanks,

David

Certified Umbraco developer
thomwhaites
Posted: Friday, March 28, 2008 5:38:49 PM
Rank: Fanatic

Joined: 7/20/2006
Posts: 258
Location: Boston, Massachusetts
You may also need references to cms.dll and interfaces.dll - i usually include these in my controls
hoehler
Posted: Sunday, March 30, 2008 8:12:29 PM

Rank: Addict

Joined: 7/19/2006
Posts: 634
Location: Bad Homburg, Germany
thomwhaites wrote:
You may also need references to cms.dll and interfaces.dll - i usually include these in my controls

For the umbraco.presentation namespace you only need the umbraco.dll

Skip all references you don't need and uncomment all code which is unnessecary to go step by step.

hth, Thomas

• 2007/2008 MVP • www.thoehler.comblog.thoehler.com • Bad Homburg, Germany
imayat12
Posted: Thursday, April 03, 2008 8:43:41 AM

Rank: Umbracoholic

Joined: 7/19/2006
Posts: 1,043
Location: Preston, UK
David,

Are you running this locally on your pc / laptop through visual studio? I had this error before where i had separate web project and was trying to run it in debug via visual studio. The way i got round this was to have project dir in umbraco website dir so that website had already fired up and everything had been initialised.

Regards

Ismail

Level 2 certified. If it aint broke dont fix.
dconlisk
Posted: Wednesday, April 09, 2008 10:33:47 AM

Rank: Aficionado

Joined: 10/19/2007
Posts: 161
Location: Glasgow, Scotland
Hi guys,

Thanks for the responses. Ismail, can you expand on that a little?
Are you saying that you have a fully fledged VS project which sits in a subdirectory of the Umbraco installation?
I take it the Umbraco site is the compiled site, not the source code?
Do you then compile your VS project, or just browse to the subdir?

I'm not getting the errors any more, but I just can't seem to access the properties of a content node.

Help!

David

Certified Umbraco developer
dconlisk
Posted: Wednesday, April 09, 2008 11:18:49 AM

Rank: Aficionado

Joined: 10/19/2007
Posts: 161
Location: Glasgow, Scotland
Okay, sorted. Here's how (lots of trial and error omitted for clarity!):

Include a copy of the umbraco.dll from the Umbraco installation /bin directory as a reference in the project.

Do this in the code of the page:

Code:

using umbraco.presentation.nodeFactory;

...

Node n = new Node(1235);
Response.Write("Node name: " + n.Name + "<br/>");
Response.Write("Property One: " + n.Properties[1].Value.ToString() + "<br/>");
Response.Write("Email: " + n.GetProperty("emailaddress").Value.ToString() + "<br/>");


This is no doubt blindingly obvious to those of you who've done this before, but I did a lot of this before getting it to work: Brick wall Using the document object didn't work for properties, so thanks Morten for putting me on the right track there!

Thanks,

David

Certified Umbraco developer
roual
Posted: Wednesday, April 23, 2008 4:46:17 PM
Rank: Enthusiast

Joined: 2/5/2008
Posts: 43
mortenbock wrote:
You should use the umbraco.presentation.nodeFactory namespace. This uses the content that is already stored in memory on the server, instead of looking in the database.



Sorry to drag up a solved post with a stupid question, but what are the benefits of using the nodeFactory namespace method over the database method? I'm guessing it's a security thing, or is there a speed element as well?

www.punkyduck.com
The iron heals, mends, fortifies, toughens, vitalizes, enables, engages, entertains, fulfills, instructs, humbles and makes a good door stop...
Dave Draper
drobar
Posted: Wednesday, April 23, 2008 5:02:04 PM

Rank: Umbracoholic

Joined: 9/8/2006
Posts: 2,020
Location: MA, USA; Cambridge, UK
Any time you can work with the content already in memory you're going to have extremely high performance and a solution that scales better as well.

cheers,
doug.

MVP 2007-2009 - Percipient Studios - Percipient Blog
roual
Posted: Wednesday, April 23, 2008 5:50:47 PM
Rank: Enthusiast

Joined: 2/5/2008
Posts: 43
Makes sense, thanks doug.

Another question (should probably start a new thread for this, but since I'm typing here anyway...), when I try and get the root node using the API with "new Node(-1)" and write out it's child count, it always comes to 0, even though there are multiple child nodes in umbraco.

I'll be the first to admit that XML isn't really my strong point, but this seems a little illogical to me. Can anyone shed any light on this?

www.punkyduck.com
The iron heals, mends, fortifies, toughens, vitalizes, enables, engages, entertains, fulfills, instructs, humbles and makes a good door stop...
Dave Draper
tkahn
Posted: Monday, April 28, 2008 3:58:15 PM

Rank: Fanatic

Joined: 11/24/2006
Posts: 346
Location: Stockholm, Sweden
I've tried the stuff in this thread and I'm really excited about accessing Umbraco data from inside a user control!

In the example above, the ID of the starting node is known. What if I want to select which node to fetch data from based on a property other than ID?



Web Developer at Kärnhuset - http://www.karnhuset.net - Stockholm, Sweden
A jQuery plugin for smooth scrolling Smooth Div Scroll. Free of course!
dconlisk
Posted: Monday, April 28, 2008 4:09:47 PM

Rank: Aficionado

Joined: 10/19/2007
Posts: 161
Location: Glasgow, Scotland
For my example, I've exposed a public property in my user control which is the ID of my resources node, which contains my email address:

Code:

private int resourcesNodeId = -1;

        public int ResourcesNodeId
        {
            get { return resourcesNodeId; }
            set { resourcesNodeId = value; }
        }



Then in my Umbraco template, I do something like:

<?UMBRACO_MACRO macroAlias="MyMacro" ResourcesNodeId="1235"></?UMBRACO_MACRO>

Of course, in your macro in Umbraco you need to add a parameter with the same name (case sensitive, in this case ResourcesNodeId of type contentPicker) to allow the id to pass through. And you should be sorted!

Oh, and you can also use the shorthand [#pageID] if you would prefer to pass through the ID of the current page to your user control like this:

<?UMBRACO_MACRO macroAlias="MyMacro" ResourcesNodeId="[#pageID]"></?UMBRACO_MACRO>


Hope that helps,

David



Certified Umbraco developer
tkahn
Posted: Monday, April 28, 2008 5:03:39 PM

Rank: Fanatic

Joined: 11/24/2006
Posts: 346
Location: Stockholm, Sweden
Thanks for the reply!

This solution still requires a hard-coded ID, eventhough it's moved to a macro parameter. I would like to get the ID of the node based on other node parameters. Some example pseudo code: get the latest created node that with the node type "NNN".



Web Developer at Kärnhuset - http://www.karnhuset.net - Stockholm, Sweden
A jQuery plugin for smooth scrolling Smooth Div Scroll. Free of course!
tkahn
Posted: Monday, April 28, 2008 6:36:00 PM

Rank: Fanatic

Joined: 11/24/2006
Posts: 346
Location: Stockholm, Sweden
Here's an XSLT-script that generates a form based on a question and answers that the administrator can enter using the Umbraco interface:

Code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxml="urn:schemas-microsoft-com:xslt"
    xmlns:umbraco.library="urn:umbraco.library"
    exclude-result-prefixes="msxml umbraco.library">


<xsl:output method="xml" omit-xml-declaration="yes" />

<xsl:param name="currentPage"/>
<!-- PARAMETER USED TO GET TO THE ROOT OF THE SITE -->
<xsl:param name="motherPage" select="$currentPage/ancestor::root"/>

<xsl:template match="/">
<!-- GET ALL NODES THAT HAVE THE DOCTYPE question_doctype -->
<xsl:for-each select="$motherPage/descendant::node[@nodeTypeAlias='question_doctype']">

<!-- SORT BY UPDATE DATE -->
<xsl:sort select="@updateDate" order="descending"/>

    <!-- JUST GET THE LATEST QUESTION -->
    <xsl:if test="position() &lt;= '1'">

    <!-- PRINT THE QUESTION -->
        <h2>
        <xsl:value-of select="data[@alias='question']"/>
        </h2>


        <form>
            <xsl:attribute name="method">POST</xsl:attribute>
            <xsl:attribute name="action">
                <xsl:value-of select="umbraco.library:NiceUrl($currentPage/@id)"/>
            </xsl:attribute>

            <!-- ANSWER 1-->
            <xsl:if test="data[@alias='answer1'] != ''">
                <input type="radio" name="poll">
                    <xsl:attribute name="value">
                        <xsl:value-of select="data[@alias='answer1']"/>
                    </xsl:attribute>
                </input>
                <xsl:value-of select="data[@alias='answer1']"/>
            </xsl:if>
            <br/>
            <!-- ANSWER 2-->
            <xsl:if test="data[@alias='answer2'] != ''">
                <input type="radio" name="poll">
                    <xsl:attribute name="value">
                        <xsl:value-of select="data[@alias='answer2']"/>
                    </xsl:attribute>
                </input>
                <xsl:value-of select="data[@alias='answer2']"/>
            </xsl:if>
            <br/>
            <!-- ANSWER 3-->
            <xsl:if test="data[@alias='answer3'] != ''">
                <input type="radio" name="poll">
                    <xsl:attribute name="value">
                        <xsl:value-of select="data[@alias='answer3']"/>
                    </xsl:attribute>
                </input>
                <xsl:value-of select="data[@alias='answer3']"/>
            </xsl:if>
            <br/>
            <!-- ANSWER 4-->
            <xsl:if test="data[@alias='answer4'] != ''">
                <input type="radio" name="poll">
                    <xsl:attribute name="value">
                        <xsl:value-of select="data[@alias='answer4']"/>
                    </xsl:attribute>
                </input>
                <xsl:value-of select="data[@alias='answer4']"/>
            </xsl:if>
            <br/>
            <input type="submit" value="Send answer" class="submitButton"></input>
        </form>
    </xsl:if>
</xsl:for-each>

</xsl:template>

</xsl:stylesheet>


This generates the form I want. Since I don't want the user to be directed away from the page I have set the current page as the action page for the form.

Now I need some sort of technique to retrieve the data from the form submission and store it somehow and then present the data in a nice diagram. ;-)

I'm working on a mini-poll function and since I can't get the code that Tim used to have on his page I guess I'll have to write a function of my own.

Web Developer at Kärnhuset - http://www.karnhuset.net - Stockholm, Sweden
A jQuery plugin for smooth scrolling Smooth Div Scroll. Free of course!
dconlisk
Posted: Monday, April 28, 2008 6:40:46 PM

Rank: Aficionado

Joined: 10/19/2007
Posts: 161
Location: Glasgow, Scotland
Yeah - sorry - didn't read your post carefully enough! Hopefully will help someone else though...

Certified Umbraco developer
mortenbock
Posted: Wednesday, April 30, 2008 11:05:41 PM

Rank: Addict

Joined: 7/19/2006
Posts: 882
Location: Århus, Denmark
You could use a library method to make an Xpath search through your in memory nodes:

umbraco.library.GetXmlNodeByXPath('yourxpath')

That would get you the XML node you need, and then you can take the properties, or the node ID from there, and use it to get a node object if you want.

Morten Bock - Level 2 certified - MVP 2008/2009 - My danish blog with a few english posts

tkahn
Posted: Friday, May 02, 2008 9:49:25 AM

Rank: Fanatic

Joined: 11/24/2006
Posts: 346
Location: Stockholm, Sweden
mortenbock wrote:
You could use a library method to make an Xpath search through your in memory nodes:

umbraco.library.GetXmlNodeByXPath('yourxpath')

That would get you the XML node you need, and then you can take the properties, or the node ID from there, and use it to get a node object if you want.


Yes! It was something along these lines that I was thinking of!
If I just get access to the XML-structure of the site programatically it should be easy to make selections either by checking values with if-statements or by using XSLT in .NET.

Thanks!

/Thomas

Web Developer at Kärnhuset - http://www.karnhuset.net - Stockholm, Sweden
A jQuery plugin for smooth scrolling Smooth Div Scroll. Free of course!
mortenbock
Posted: Friday, May 02, 2008 9:55:21 AM

Rank: Addict

Joined: 7/19/2006
Posts: 882
Location: Århus, Denmark
tkahn wrote:
If I just get access to the XML-structure of the site programatically (...)


Hi Thomas

If you take a look at the umbraco.presentation.nodefactory namespace, you will se the API for working with the in-memory content. I think that this also has some xpath methods, and you get node objects instead of XML.

Morten Bock - Level 2 certified - MVP 2008/2009 - My danish blog with a few english posts

psterling@homax
Posted: Thursday, June 26, 2008 7:25:31 PM

Rank: Fanatic

Joined: 10/30/2007
Posts: 329
Location: Bellingham
These postings are helpful, even months later. I used the suggestions in this post to create multiple instances of a macro in a single template.

Also created a post here.

Thanks,
-Paul

motusconnect.com :: level-2 certified :: MVP 2008/2009

The forum has moved

This forum is no longer in use, so you can't reply to this message - please go to Our Umbraco

Users browsing this topic
Guest


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.