Get SPListItem in another format - sharepoint

I want to get different Rows from an SPListItem. I'll show you my problem with an example.
This code
Console.WriteLine(SPItemName["Created By"]);
or
Console.WriteLine(SPItemName["Created By"].ToString);
returns "8;UserName" (8 is the User ID).
If I look up the row in SharePoint Designer, i can choose even a format for this data field.
So i could get the html code of this field.
How to set the format (like html code or text) of a datafield in c#?
thanks

Use Either SPFieldLookupValue
If you need just the username, use SPFieldLookupValue to seperate id from value:
var userValue = new SPFieldLookupValue(SPItemName["Created By"] as string)
Then you can:
userValue.LookupValue to return UserName
userValue.LookupId to return Id
Or SPFieldUserValue
Or better yet, you can create SPFieldUserValue object to access any other user properties like email, login name, etc..
SPFieldUserValue objUserFieldValue = new SPFieldUserValue(web, SPItemName["Created By"].ToString());
Afterwards you can use:
objUserFieldValue.User.LoginName;
objUserFieldValue.User.Name;
objUserFieldValue.User.ID;
objUserFieldValue.User.Groups;
objUserFieldValue.User.Roles;
objUserFieldValue.User.Email;
objUserFieldValue.User.Sid;
objUserFieldValue.User.UserToken;
http://www.sharepointkings.com/2009/04/spfielduservalue-and.html
Note: to create SPFieldUserValue you must pass reference to web, that's because SharePoint has to get additional user information from user information list to construct SPFieldUserValue object.

Related

Kentico Document Get Page Meta Data Custom Page Type

When trying to retrieve DocumentPageTitle and DocumentPageDescription using GetStringValue() on a custom page type TreeNode, the result is always coming back as the default value (in this case an empty string) passed into the method.
I'm able to successfully retrieve other column values as well as standard document properties such as DocumentName, DocumentID and AbsoluteURL, but not the document meta properties.
The respective fields in the Meta tab of document/page do have values and are being successfully rendered in the by default such as <meta name="description" content=".." />
// returns empty string
string documentPageDescription = DocumentContext.CurrentDocument.GetString("DocumentPageDescription", string.Empty);
// returns empty string
TreeNode document = parameters[0] as TreeNode;
string documentPageDescription = document.GetStringValue("DocumentPageDescription", string.Empty);
I've tried setting option Inherits fields from page type to "Page (menu item)", but that did not help.
Does the custom page type need to inherit from something specifically or have a specific setting activated to access these values? Or if what I think is a TreeNode in fact isn't, how could I get the TreeNode from this object that has the properties listed before available?
Thank you for any help you can provide.
ValidationHelper.GetString(CMS.DocumentEngine.DocumentContext.CurrentDocument.GetValue("DocumentPageDescription"), string.Empty)
Two things to check, one, are you sure the meta data is available on the page you are pulling? Two, is your API actually pulling all the data for that page?
I've used these in my test and both returned the metadata.
var page = DocumentHelper.GetDocuments().Path("/Articles/Coffee-Beverages-Explained").FirstObject;
Response.Write(page.GetStringValue("DocumentPageDescription", string.Empty));
TreeProvider tree = new TreeProvider(MembershipContext.AuthenticatedUser);
TreeNode tn = tree.SelectNodes().OnCurrentSite().Path("/Articles/Coffee-Beverages-Explained").FirstObject;
Response.Write(tn.GetStringValue("DocumentPageDescription", string.Empty));
The DocumentPageTitle and DocumentPageDescription were coming back as null when the custom page type document/page was inheriting from parent/global values.
I was able to use the following to get the properties when not inheriting, while falling back to the parent value when inheriting was taking place:
string documentPageTitle = document.GetStringValue("DocumentPageTitle", DocumentContext.CurrentTitle);
This approach came from the following issue on Kentico DevNet.
Thank you for your help and suggestions, it's appreciated.

How to assign a value to an Orchard ContentPickerField from code?

I am working on an Orchard site that needs to be able to use some customized forms to create new content items.
To handle this I'm using a controller to display a form and then trying to create the new content items on post back by populating the dynamic items and then sending them through the ContentManagerService's Create() function.
This is working ok until I got to the content picker field I have as part of my content item.
In my project I have a content type of Question Record that has a SubmittedBy field that is a Content Picker Field.
Here is what I can see in the immediate window while processing the post back:
> dynamic q = _questionService.NewQuestion("Why doesn't this work?");
{Custom.Website.Models.Question}
base {Orchard.ContentManagement.ContentPart}: {Custom.Website.Models.Question}
IsNew: true
OriginalQuestion: "Why doesn't this work?"
Summary: null
> q.QuestionRecord
{Orchard.ContentManagement.ContentPart}
base {System.Dynamic.DynamicObject}: {Orchard.ContentManagement.ContentPart}
ContentItem: {Orchard.ContentManagement.ContentItem}
Fields: Count = 5
Id: 0
PartDefinition: {Orchard.ContentManagement.MetaData.Models.ContentPartDefinition}
Settings: Count = 0
TypeDefinition: {Orchard.ContentManagement.MetaData.Models.ContentTypeDefinition}
TypePartDefinition: {Orchard.ContentManagement.MetaData.Models.ContentTypePartDefinition}
Zones: {Orchard.UI.ZoneCollection}
> q.QuestionRecord.SubmittedBy
{Orchard.ContentPicker.Fields.ContentPickerField}
base {Orchard.ContentManagement.ContentField}: {Orchard.ContentPicker.Fields.ContentPickerField}
ContentItems: null
Ids: {int[0]}
The ContentItems property is read-only and the Ids when assigning a new int[] to the Ids array I get a System.ObjectDisposedException with the message: Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed.
Are there any workarounds to get this value set in code or do I need to create my own property to store the related content item ids? It would be very helpful to have the admin interface of the ContentPickerField also available.
Thanks.
If you have a reference to the ContentPickerField, you can assign it a value using the Ids property.
In example (assuming your content type has a part called Question which has a field called SubmittedBy):
var submittedByField = ((dynamic)q.ContentItem).Question.SubmittedBy;
sbmittedByField.Ids = new[] { submittedById };
As Bertrand mentioned, the format to access a content field is: contentItem.PartName.FieldName.
If you attached a field to a type directly via the admin, the part name has the same name as the type name, hence contentItem.TypeName.FieldName (where TypeName is actually the name of the implicitly created part).

Sharepoint 2010 Metadata fields Key, Value

I'm currently working with Sharepoint 2010 and Sharepoint API on creating a document library with some existing document lists.
I have created a WinForm that loops through a given doc lists and then add them to diffrent document libraries depending on 'Type(A metadata field)' of the document. Type is determined by reading the "Metadata fields" for the specific document. Metadata fields are read by creating Hashtable of SPFields
Question
When document metadata field is read to determin the 'Type', I have realised that the Metadatafield 'Type'(Key) actually pulls out as 'Type+TaxHTField0' and value for the Key pulls out as value|GUID
So for example if my Metadata field is called Doc_x0020_Type when it returns from the API it comes out as Doc_x0020_TypeTaxHTField0 the value for this should be just 'products' but it comes out as
products|21EC2020-3AEA-1069-A2DD-08002B30309D
Is there a setting we can set in sharepoint to eleminate adding extra charaters and GUID to both Key and Value for metadata fields?
Below is what I've done to rectify the issue, but wondered if it's a setting we can set in sharepoint
public String GetLibrary(Hashtable itemProperties)
{
String typeMetaField = "Doc_x0020_TypeTaxHTField0";
String sKey = String.Empty;
foreach (DictionaryEntry deEntry in itemProperties)
{
sKey = deEntry.Key.ToString();
if (sKey == typeMetaField){
_type = deEntry.Value.ToString();
string[] value = _type.Split('|');
_type = value[0].Trim();
}
}
return GetDocumentLibrary(_type);
}
This is by design.
If you add a taxonomy field to your own contenttype (for instance named 'MyTaxField') SharePoint will autogenerate a hidden 'Notes' field that contains the label and the guid of the values you select in the UI.
This is quite helpful when using SPSiteDataQuery since it will return empty values for taxonomy fields that allow multiple values (works with single value taxonomy fields though).
The only way to get the taxonomy values is to have a for the hidden field named 'MyTaxFieldTaxHTField0'.
But as you have discovered, this field might not be formatted as youd like :).
I have not tested this, but did you check if your contenttype contains a field called "Doc_x0020_Type" (possible of type TaxonomyFieldValue(Collection))?

Getting RoleCollection as a string

We can get the roles of an SPUser by SPUser.Roles. But it will return SPRoleCollection. If we want to list all the roles we need to loop that.
For example an User has "Full Control","Read","Design" we need to loop the SPRoleCollection object.
How can i get all the roles as a string with ',' separator?
As a rough guess, try:
var user = SPUser // However you get the user.
var roles = Sring.Join(",", (from r in user.Roles select r.Name).ToArray()));
Though if you're using SharePoint 2010, the Name property is obsolete apparently.

Setting author field in SPListItem won't persist

I am trying to copy an SPListItem (with file) from one site collection to another. I do this by creating the file like this:
var archiveFile = newsArchive.Lists[listName].RootFolder.Files.Add(originalItem.File.Name, originalItem.File.OpenBinary());
var archiveItem = archiveFile.Item;
through a utility method I wrote i then set all field values of the new item to correspond with the original item like so
Utilities.PopulateListItemMetadata(....)
The thing is, this does not persist the Author field.
I tried setting the Author field explicitely in every way imaginable, for instance like so:
string userName = originalItem.GetUser("Created by").LoginName;
SPUser user = newsArchive.SiteUsers[userName];
archiveItem["Author"] = user.ID + ";#" + user.LoginName;
archiveItem.Update();
And like so
string userName = originalItem.GetUser("Created by").LoginName;
SPUser user = newsArchive.SiteUsers[userName];
archiveItem["Author"] = user;
archiveItem.Update();
But as soon as the SPListItem.Update() method is called, the archiveItem["Author"] field has reverted to sharepoint\system. I'm a bit at a loss here, this should work..
P.S. the SPListItem.GetUser method is an extension method
P.P.S. Code is being run from a timer job...
Edit: Did some more digging by adding a new field to the content type and then setting that field to reflect the Author of the original item, but that is not set either. However, the web.EnsureUser(username) does return the correct user. Is this weird or what!?!
Found the answer, using
SPFieldUserValue val = new SPFieldUserValue(newsArchive, user.ID, user.Name);
archiveItem["Author"] = val;
archiveItem.SystemUpdate(false);
did the trick!
I've experienced the same problem. Have a look at this question.
The way that worked for me is to wrap the same code you have in your final example in elevated privileges.
Edit
Why don't you try replacing:
SPUser user = newsArchive.SiteUsers[userName];
with:
SPUser user = newsArchive.EnsureUser(userName);
Then you will know the user is in the web and also get a reference to them. The SiteUsers collection gives you the users in the site collection - they have not necessarily been added to the web. If SharePoint doesn't find the user it will probably use system account.

Resources