11

I have yet to find a clear answer to this topic, so I'm writing this question in hope that someone can explain me the correct way to achieve my goal. I must also add that all my test was done on SharePoint 2007, but as far as I know the behavior should be the same when using the 2010 version. Edit: I have conducted some test on SP 2010 and I can now confirm that the behavior seems to be the same.

Premise: I was trying to build a custom choice field that supports localization. Since the choice labels will change based on the current locale (let's forget SP 2010 multi-language for a moment and suppose that only one-language web site are used) I started to search a way to implement locale-independent values for my custom field, something like the classical "id-value" concept used by traditional ASP choice controls.

I found on this page (also linked here) references to a <MAPPINGS> tag defined by the Field CAML element schema. The page states that the tag "Contains mappings of values to the choices displayed within a Choice field."

As a reference here is the sample field definition taken from the linked page:

<Field ID="{c15b34c3-ce7d-490a-b133-3f4de8801b76}" Type="Choice" Name="Status" DisplayName="$Resources:core,Tasks_Status;" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Status">
<CHOICES>
   <CHOICE>$Resources:core,Tasks_NotStarted;</CHOICE>
   <CHOICE>$Resources:core,Tasks_InProgress;</CHOICE>
   <CHOICE>$Resources:core,Tasks_Completed;</CHOICE>
   <CHOICE>$Resources:core,Tasks_Deferred;</CHOICE>
   <CHOICE>$Resources:core,Tasks_Waiting;</CHOICE>
</CHOICES>
<MAPPINGS>
   <MAPPING Value="1">$Resources:core,Tasks_NotStarted;</MAPPING>
   <MAPPING Value="2">$Resources:core,Tasks_InProgress;</MAPPING>
   <MAPPING Value="3">$Resources:core,Tasks_Completed;</MAPPING>
   <MAPPING Value="4">$Resources:core,Tasks_Deferred;</MAPPING>
   <MAPPING Value="5">$Resources:core,Tasks_Waiting;</MAPPING>
</MAPPINGS>
<Default>$Resources:core,Tasks_NotStarted;</Default>

As you can see the sample defines five choices that will be localized, then procedes to map them to the values from 1 to 5.

The problem is that I had never been able to read the mapped value from custom code -no one of the field read method would return the expected value. It would seems that all mapping defined by the CAML field definition are simply ignored.

Some sources states that the tag has no real effect on the developer side and only affect the valued stored by SharePoint in the content database. EDIT: After some more excavations, I can confirm that the content db only seems to contain the unmapped data, so this option seem a no-go

Others indicates it as a form of feng-shui that can be used to enhance the cosmic energy flows in your feature files, but no one seems to have a concrete answer.

Anyone know what this tag should be used for?

PS: I also considered using the SPFieldMultiChoice.Mappings Property and build an extension method to implement some logic that would decode the field choice "text" to the mapped value (I should be able to to that, the property contains the full xml mapping node taken from the field definition), but before I try this solution I would like to know if I have misunderstood the tag usage.


EDIT: I have conducted some more research on the topic. While I didn't found any concrete answer (seems that someone is asking the same question on msdn without much luck...) I am starting to believe that the tag could indeed be a sophisticate form of feng-shui.

Take a look to the OOB definition for the HealtRuleScope field:

<?xml version="1.0" encoding="utf-16"?>
<Field ID="{E59F08C9-FA34-4f94-A00A-F6458B1D3C56}" Name="HealthRuleScope" DisplayName="Scope" Type="Choice" Description="..." Group="_Hidden" SourceID="http://schemas.microsoft.com/sharepoint/v3/fields" StaticName="HealthRuleScope" AllowDeletion="FALSE" Required="TRUE">
   <CHOICES>
      <CHOICE>All Servers</CHOICE>
      <CHOICE>Any Server</CHOICE>
   </CHOICES>
   <MAPPINGS>
      <MAPPING Value="1">All Servers</MAPPING>
      <MAPPING Value="2">Any Server</MAPPING>
   </MAPPINGS>
   <Default>Any Server</Default>
</Field>

This definition was taken from the site column on the central administration web site, using the SharePoint Manager tool (you could do the same with a custom application, but no need to re-invent anything). As you see the MAPPING section is still present, as per the field.xml feature definition in the 14 folder.

If you look at the same field on the Healt Rule list in Central Administration (use a tool like SharePoint Manager 2010) you will see that the whole mapping section is missing. That would seem that in this case the mapping ISN'T propagated to the child field on the list instance. On the other hand, I have tried to build a custom feature for a field that uses the mapping section and I was able to propagate the info to the list (still no luck at retrieving the mapped value). It could still be possible that the mapping info is read from the parent field when the SharePoint object model requires it, but as now I am starting to think that this feature is simply un-implemented... Not even the LinqToSharePoint mapping seems to use it:

public enum Scope : int {   
   None = 0,    
   Invalid = 1,

   [Microsoft.SharePoint.Linq.ChoiceAttribute(Value="All Servers")]
   AllServers = 2,  
   [Microsoft.SharePoint.Linq.ChoiceAttribute(Value="Any Server")]
   AnyServer = 4,
}

EDIT: As Amit suggested in his answer, I had a quick look to the official "Collaborative Application Markup Language (CAML) Structure Specification" document. It is indeed suspicious that the latest versions of the document had removed any reference to the schema element - that could indicate that the element is indeed unused/unimplemented. On the opposite hand, the HealthRuleScope field uses the mappings declaration - and as far as I know it was introduced only with SP 2010...

2
  • 1
    +1 Very interesting question. I saw this element previously and took a look at it for the few minutes; until I realised it was going to be another time-devouring documentation black hole. :/
    – Stu Pegg
    Commented Nov 24, 2011 at 22:16
  • 1
    @StuartPegg Thanks, Stuart. Yes, I fear that this question won't find an answer any time soon, but I'm leaving it here anyway for anybody that might be wondering about this "feature". I have also updated the question with the results of my latest test... nothing mayor, but fell free to have a look (seem that the mapped value aren't available even at the db level). Commented Nov 25, 2011 at 8:17

3 Answers 3

3

You can find details about <Mappings> in [MS-WSSCAML]: Collaborative Application Markup Language (CAML) Structure Specification V0.1

"MAPPINGS: A set of MAPPING string elements that represents a canonical, languageagnostic identifier for a corresponding CHOICE with the value specified by the MAPPING element. The reader MUST ignore MAPPINGS if the Type attribute is not Choice or MultiChoice. The writer SHOULD omit MAPPINGS if the Type attribute is not Choice or MultiChoice."

"2.3.2.13 MAPPINGDEFINITIONS Type The MAPPINGDEFINITIONS type is a container for one or more MAPPINGS.
MAPPINGS MUST NOT be defined for fields other than Choice or MultiChoice. There MUST be either no MAPPINGDEFINITION elements defined for a Choice field, or exactly one MAPPING element for each corresponding CHOICE element"

You can find the latest(and all) versions of the Specification here : http://msdn.microsoft.com/en-us/library/cc313121(v=office.12).aspx . But the latest version dont have any info on <Mappings>!!

1
  • 1
    So THERE IS a Rosetta stone for the caml schema! That said, if I'm not interpreting the runes wrong, the linked document would confirm that the Mappings section could be use to support localization of a choice/multichoice field. The problem is... how? As I said, I didn't find any way to read the mapped value in codebehind. Take the example in my question: the "All Server" choice for the HealthRuleScope field is saved in the database "as-is" - the mapped value "1" is nowhere to be found. Commented Nov 29, 2011 at 15:22
2

In the end I have followed the direction proposed by Stuart and marked this still another SharePoint blackhole, so I have left any hope of using this CAML tag as last for now.

During my research I had a look at many classes in the framework but I cannot find anything related to using the mapping "attribute", so I can only assume that it was an uncompleted feature - will see if SP 2013 changes that.

THAT said, I have tested an alternative solution which utilizes the Mappings property on the Field object to manually parse the mapping xml and simulate the expected behaviour. That quickly grew out of hand when MUI support comes into play, so in the end I left that road too (seems there are some issue involved with dialogs and so on but it may have depended from some other issue I was experiencing at the time from some CU applied in wrong order, so take this with a grain of salt).

0

Using your example of list "Resources" (objList) with SPFieldChoice "Status", where multiple selection is not allowed. objItem is an item in objList where you want to know the index of the Status field:

int i;
i = ((SPFieldChoice)objList.Fields["Status"])Choices.IndexOf(objItem["Status"].ToString());
1
  • only problem: I don't want to know the index. I want to recover the "MAPPING Value". Strictly speaking, I could map every value on a random number... that would void every possibility of a "match" between the mapped value and the index. That said... your idea could still be useful: the index shouldn't change based on the site locale, so maybe it could be used instead of the label. Commented Dec 9, 2013 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.