Question

I'm trying to create an alert on a list. The alert should only trigger on a subset of the list items for which a certain managed metadata field has a certain value. So I'm setting the Filter-Property of the AlertCreationInformation to a CAML-query. There is no problem getting the filter to work for say filtering on a choice field using

ClientContext = GetMy365Context(...);
Web web = ctx.Web;
List list = web.Lists.GetByTitle("NotifyTest");
User user = ctx.Web.SiteUsers.GetByEmail("someone@example.com");
ctx.Load(web);
ctx.Load(list);
ctx.Load(user);
ctx.ExecuteQuery();

AlertCreationInformation aci = new AlertCreationInformation()
{
    AlertFrequency = AlertFrequency.Immediate,
    AlertType = AlertType.List,
    AlwaysNotify = true,
    EventType = AlertEventType.All,
    DeliveryChannels = AlertDeliveryChannel.Email,
    Title = "Alert filtered on choice",
    User = user,
    AlertTemplateName = "SPAlertTemplateType.GenericList"

};
aci.List = list;
aci.Filter = "<Query><Eq><FieldRef Name=\"MyChoiceField\" /><Value Type=\"Text\">MyChoiceValue</Value></Eq></Query>";

web.Alerts.Add(aci);
ctx.ExecuteQuery();

But, I was unable to find any proper documentation on the supported CAML for Filter. E.g. <In> is not supported as well as Type="Choice"

So my question is, what query can I use to filter on a multivalue managed metadata field? So far I have tried using the GUID of the term, the lookup id of the term in the taxonomy hidden list, the text-value of the term, the <contains>-operator, the <eq>-operator but without any luck.

Était-ce utile?

La solution

The problem you are running into is that Alert.filter accepts a very limited subset of CAML and what that subset allows is anybody's guess (i.e. completely undocumented, of course you already know that by now).

A while back I read an answer on a forum to a similar question that provide a novel approach to figure out what worked. I would reference it here, but I can't seem to find it now. Anyway, the approach was:

  1. Create a view that filters the way you want the alert to filter.
  2. Setup an alert on that view.
  3. Programmatically, look at that alert and look at the filter.

The reason this works is because the alert isn't actually tied to the view, it copies the filter. So if the view changes, the alert will be out of sync with it.

So I setup a quick test with a multi-select metadata site column, creatively named ManagedMetadata, containing some fruits and vegetables, created a list that used the field, and a view that only showed items with Broccoli as a value. Finally, I created an alert on that view. Then I created some items with and without Broccoli and checked that the alert works, which it does.

Now, I launch the debug console and run this code:

var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var alerts = web.get_alerts();

ctx.load(web);
ctx.load(alerts);

ctx.executeQueryAsync(
    function() {
        var en = alerts.getEnumerator();
        while (en.moveNext()) {
            console.log(en.get_current());
        }
    },
    function(sender, args) {
        console.log(args.get_message());
    }
);

When I run that code, this what gets dumped for that alert:

enter image description here

The actual filter is:

<Query><Eq><FieldRef Name=\"ManagedMetadata\"/><Value type=\"string\">brocoli</Value></Eq></Query>

The only difference I see is that the value type is set to string instead of text like you have. Why? I cannot say, but it seems to work.

Note that I'm doing this in SharePoint online. If you mentioned what version of SharePoint you're on, I missed it. Anyway, hope this helps.

Autres conseils

There are 2 methods to query a list/library that contains a managed metadata column:

Query against Term Name

Query Against WSSID

Method 1 (will look something similar to this):

alert.Filter = @"<Query>
              <Contains>
                  <FieldRef Name='" + MyTaxonomyFieldName + @"' />
                  <Value Type='Text'>" + tagName + @"</Value>
              </Contains>
            </Query>";

Method 2:

alert.Filter = @"<Query>
              <In>
               <FieldRef LookupId='TRUE' Name='" + MyTaxonomyField + @"' />
                <Values>
                   <Value Type='Integer'>" + tagLookupID + @"</Value>
                </Values>
              </In>
             </Query>";

it is recommended to use the second method to avoid situations where the term name is used under different term groups!

Licencié sous: CC-BY-SA avec attribution
Non affilié à sharepoint.stackexchange
scroll top