Accessing a settings field on CurrentSite

Topics: General
Apr 12, 2013 at 1:37 AM
I added a field to the 'Site' content type called 'Address'. I want to access that field from a view.

I've tried so many things and I just can't get it to work.

E.g.
dynamic contentItem = WorkContext.CurrentSite.ContentItem;
var field = contentItem.ContentPart.Address;
I've googled and googled and I just can't find a solution to this that works. I really don't want to mess around adding code for my own Settings part when there is already fields functionality there.

Thanks
Coordinator
Apr 12, 2013 at 1:38 AM
Try contentItem.Site.Address.
Apr 12, 2013 at 1:51 AM
Ahh to my rescue again, thanks Bertrand!

So the thing to try is always the name of the content type after the content item eh?
Apr 12, 2013 at 1:52 AM
Also is there any way to do this in a "safe" way so that if someone deletes the 'Address' field from the Site type, it doesn't crash? Thanks
Coordinator
Apr 12, 2013 at 1:52 AM
Technically, it's the name of the part on which the field is, but for fields added through the admin, that part is a dynamic part that has the same name as the content type.
Coordinator
Apr 12, 2013 at 2:00 AM
You can test for null, but dynamic is implemented in Orchard with a neat concept of Nil similar to what you can find in Ruby: Nil is an object that compares to null as true, but it's not exactly null as you can evaluate properties on it: Nil.something.foo.bar will work, even though each object along the way is equivalent to null.
Apr 12, 2013 at 2:40 AM
I tried calling contentItem.Site.AddressBlah and it raised an exception. But what you're saying is, it should just return Nil, right?
Coordinator
Apr 12, 2013 at 4:50 AM
There have been some big changes in the dynamic implementation so I'm not 100% sure.
Developer
Apr 12, 2013 at 1:26 PM
Edited Apr 12, 2013 at 1:26 PM
I noticed that exception as well. Before ClaySharp was removed, it would return Nil. After ClaySharp was removed, it throws an exception. For strongly typed parts, this is no issue since we can use the Has<TPart> extension method. For dynamic parts (not having a class), it's trickier: you would have to resort to LINQ to find out if the part or field exists, before accessing it.

@woodvorg: Would you mind filing a bug with simple repro steps?
Apr 13, 2013 at 1:03 AM
I'll just use LINQ for the time being then, thanks.

For anyone reading this thread who wants to know how to do it that way, here's an example
var phoneField = WorkContext.CurrentSite.ContentItem.Parts.SelectMany(p => p.Fields).SingleOrDefault(f => f.Name == "Phone");
var phone = phoneField != null ? phoneField.Storage.Get<string>(null) : string.Empty;
Here's the bug:
https://orchard.codeplex.com/workitem/19604