SharePoint: How do you reference a localized list? - sharepoint

I have a SharePoint list that gets installed by a feature.
I need to enable content types which I do so in a feature receiver:
SPList list = site.Lists["NameOfList"];
list.ContentTypesEnabled = true;
list.Update();
The problem is that it seems the method:site.Lists["NameOfList"], is really looking at the Title not the ID.
How can I get the list by using the ID and NOT the title which is subject to change because of Localization...
<ListInstance
TemplateType="10051"
Id="ThisISTheIDField" //Want to retrieve list instance based on this field.
Title="$Resources:MyFile,MyResourceName;"
Url="Lists/URLOFList"
OnQuickLaunch="TRUE">
</ListInstance>
Thanks in advance. And 10 years of hail Maries for the MS SharePoint developer who wrote this internal dare I say - c.r.a.p?

So your list is a custom list, right?
You can add:
EnableContentTypes=TRUE
To your list definition and you won't need the feature?
See: List Element

There is no site.Lists (Maybe is a SPWeb? The naming is awkward, I Know)
<SPWeb Instance>.Lists.GetList(Guid uniqueId, bool bFetchMetadata)
<SPWeb Instance>.Lists.GetList(Guid uniqueId, bool bFetchMetadata, bool bFetchSecurityData)
<SPWeb Instance>.GetList(string strUrl)
The third option could combine the url and use the internal name to grab it (in the URL lists are accessed by the internal name)

If the operation has to be completed only once in a lifetime, I'd suggest looping throuhg the .Lists collection and checking if the baseTemplate matches:
For Each oList In web.Lists
If (list1.BaseTemplate = 10051) Then
oList.ContentTypesEnabled=True
End If
Next

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.

Can a SharePoint list item have it's Targeted Audience calculated or otherwise automatically specified?

I want to show targeted (filtered) content from a list to users. I already have a column in the list that basically has the Target Audience value. This field is a multi-choice column (checkbox input) which I prefer over the current input field for Targeted Audiences.
To get audience filtering to work I unfortunately need to have the Targeted Audience field filled out for every list item. My current plan is to use a simple SharePoint designer workflow to set the Targeted Audiences field based on my other field, but I'm wondering if there is a better way. Am I just looking at this wrong?
Note that I know audiences can also be used to hide/show web parts, but that is not something I am interested in.
You could try and give this a whirl...
SPField audienceField = null;
try
{
audienceField = list.Fields[Microsoft.SharePoint.Publishing.FieldId.AudienceTargeting]
}
catch
{}
if(audienceField != null)
{
try
{
Audience siteAudience;
ServerContext context = ServerContext.GetContext(site);
AudienceManager audManager = new AudienceManager(context);
foreach (SPListItem item in list.Items)
{
string audienceName = item["fakeAudienceField"]; //should be the audience name created in SSP
siteAudience = audManager.GetAudience(audienceName);
Guid id = siteAudience.AudienceID;
item["Target Audiences"] = id.ToString()+";;;;";
item.Update();
}
}
catch
{}
I do not believe Target Audiences can be set up as a calculated field, in which case your options are workflow or a list item event receiver.
To set the audience field value, you can use AudienceManager.GetAudienceIDsAsText; Gary Lapointe has a post with example usage.
Maybe use a webpart to display the content of the list and use Audiences on the webpart sounds a solution easier to manage...

SharePoint List Error: "Value does not fall within the expected range"

Hi I am developing using the SharePoint namespace and I ran into the following error when I try to retrieve a URL column from one of my lsits.
"Value does not fall within the expected range"
All I am doing is:
item["URL"]
Can someone tell me what I can do about this?
The error definitely means that the field can't be found.
Debug the process and look at the ListItem.Fields.SchemaXML property to find its internal name, it may be saved internally as something other than URL. You can also use the following method to get a list item value.
SPField l_field = l_item.Fields.GetField("URL");
string l_fieldValue = l_item[l_field.Id].ToString();
The GetField method looks for a field by both DisplayName & InternalName.
To get the URL of an SPListItem, use Item.Url.
public static string GetItemURLValue(SPListItem item, string fieldName)
{
string exit = "";
SPFieldUrlValue link = new SPFieldUrlValue(item[fieldName].ToString());
exit = link.Url;
return exit;
}
This usually means "URL" is not a field in the list.
If it's a promoted InfoPath column, try deactivating and re-activating the form template to the site. I have noticed that I have to do this whenever I add a new promoted field to an infopath template.
There is a special method for retrieving URLs. Try this:
SPListItem li = ...
SPFieldUrlValue fuv = new SPFieldUrlValue(li[strFieldName].ToString());
return fuv.Url;
Mine is a Windows application. I used to get this exception after I created the set up and tried deploying.
My application needed to write in Excel and then save it. I used reference of COM component 'Microsoft Excel 11.0 Object'. I noticed when I add this reference actually 3 dll's appear in my reference list.
Microsoft.office.core
Excel
VBIDE
I removed the 'VBIDE' reference and my problem is solved.
If it's just a column name and in "Single line of Text" format, what about:
item["URL"] != null ? item["URL"].ToString() : "Not Found";

Cascading list boxes, with multi-select

I wound up modifying the source from a publically posted POC: http://datacogs.com/datablogs/archive/2007/08/26/641.aspx, which is a custom field definition for cascading drop downs. The modifications were to allow parent-child list boxes where a user can multiselect for filtering and selecting the values to be written back to a SharePoint list. I got the parent-child cascading behavior working, but the save operation only takes the first value that is selected from the list box. I changed the base type for the custom field control from "SPFieldText" to "SPMultiLineText", along with changing the FLD_TYPES field definition values from:
Text to Note and this did not work. So, I changed the field control base type to "SPFieldMultiChoice" and the FLD_TYPES to "MultiChoice" and still get the same result, which is only the first value that's selected, writing to the SharePoint list.
Does anyone have any idea how to get a custom field with multiple selections to write those multiple selections to a SharePoint list?
Thanks for taking the time to read through my post.
Cheers,
~Peter
I was able to accomplish this by inheriting from SPFieldLookup and overriding its internal handling of AllowMultipleValues:
In your FLDTYPES_*.xml set <ParentType>LookupMulti</ParentType>
In your extension of SPFieldLookup, be sure to override AllowMultipleValues (always true), FieldValueType (probably typeof(SPFieldLookupValueCollection)) and FieldRenderingControl. I also set base.LookupField = "LinkTitleNoMenu", though in retrospect I'm not sure why. :)
In your field editor control's OnSaveChange(), set the field's Mult value to true.
To set Mult, you can either string manipulation on field.SchemaXml:
string s = field.SchemaXml;
if (s.IndexOf(" Mult=", StringComparison.OrdinalIgnoreCase) < 0)
field.SchemaXml = s.Insert(s.IndexOf("/>", StringComparison.Ordinal), " Mult=\"TRUE\" ");
Or use reflection:
var type = field.GetType();
var mi = type.GetMethod("SetFieldBoolValue", BindingFlags.Instance | BindingFlags.NonPublic);
mi.Invoke(field, new object[] { "Mult", true });
It's been a while, so I might be forgetting something, but that should be most of it.

Accessing SPLIstItem properties in SharePoint

I'm trying something very simple - accessing my SharePoint list's items and their properties.
However, SPListItem.Properties count is zero for all normal lists. Everything works as expected for document and pages libraries. So, if the list items are based on document type, all is good. If they are based on item, properties are not returned.
I've tried in two environments, with new sites created from OOTB publishing templates, with new lists which are based on OOTB content types etc. Always the same thing.
Right amount of SPListItems is always returned. Title and Name are fine. It's just that the .Properties hashtable is totally empty.
In desperation, I wrote a web part that outputs the following (ugly!) diagnostics.
foreach (SPList list in SPContext.Current.Web.Lists)
{
foreach (SPListItem item in list.Items)
{
Label label = new Label();
label.Text = "Name: " + item.Name + "Property count: " + item.Properties.Count;
this.Controls.Add(label);
}
}
The only observation is that it works exactly as I described earlier. I just share the code to show that this is the most basic operation imaginable.
Here is sample output - I've added the line breaks for readability ;-)
Name: Test Property count: 0
Name: default.aspx Property count: 21
Obviously item "Test" is an item based list item and default.aspx is a page.
Has anyone ever encountered anything like this? Any ideas?
item["FieldName"] is the canonical way to get a value of a metadata column in a SharePoint list. If you need to get the list of available fields for a SharePoint list, check the parent SPList object's Fields property which is a collection of the fields in this list. Each of those field objects will have a property called InternalName and that is what you should use to access its value when you are working with an instance of SPListItem.
Are you trying to get the field Values? Sadly, they are not strongly typed:
string ModifiedBy = (string)item["Author"];
To get the proper names of the fields (they have to be the internal names), go to the List and then List Settings. You will find the List of Columns there. Click on any Column Name to go to the Edit Page, and then look at the URL in the Address Bar of your Browser. At the very end, there should be a parameter "Field=Editor" or similar - that's your internal field name.
If you wonder why a field like "Test Field" looks strange, that is because Sharepoint encodes certain characters. A Space would be encoded to x0020 hence the Internal Name for "Test Field" is "Test_x0020_Field".
In order to get the proper field type to cast to:
string FieldType = item["Author"].GetType().FullName;
(The Intermediate Window in Visual Studio is tremendously helpful for this!)
I have found the following extension to the SPListItem class to be very helpful.
internal static class SharePointExtensions
{
internal static Dictionary<string, object> PropertiesToDictionary(this SPListItem item)
{
// NOTE: This code might be temping - but don't do it! ...itdoes not work as there are often multiple field definitions with the same Title!
// return item.Fields.Cast<SPField>().ToDictionary(fld => fld.Title, fld => item[fld.Title]);
Dictionary<string, object> dict = new Dictionary<string, object>();
var fieldNames = item.Fields.Cast<SPField>().Select(fld => fld.Title).Distinct().OrderBy(sz => sz).ToArray();
foreach (fieldName in fieldNames)
dict.Add(sz, item[fieldName]);
return dict;
}
}
with it you can simply do:
item.PropertiesToDictionary()
...and you will have a nice Linq dictionary object that will work just the way you'd expect. Is it a little heavy-weight / low-performance? Sure. Are most people willing to make that trade-off? I think so...
Do you run SPListItem.Update() or .SystemUpdate() after setting the properties?
If you want to get an object out of a SPField of a SPListItem you've got to do like this:
SPField field = ((SPList)list).Fields.GetField("FieldName");
object fieldValue = field.GetFieldValue(((SPListItem)item)[field.Title].ToString());
The ListItem.Properties hashtable will be empty unless you assign to it.
SPListItem item = properties.ListItem;
item.Properties["Key"] = "value";
int total = item.Properties.Count;
Answer:
"total == 1"
SPList yourList = web.Lists["Your list name"];
string sColumnValue = oSPListItem[yourList.Fields["yourSiteColumn display
name"].InternalName].ToString();

Resources