SharePoint / sp-dev-docs

SharePoint & Viva Connections Developer Documentation
https://docs.microsoft.com/en-us/sharepoint/dev/
Creative Commons Attribution 4.0 International
1.24k stars 1k forks source link

Updating Managed Metadata Column in an item #9909

Open abdollahkahne opened 2 weeks ago

abdollahkahne commented 2 weeks ago

Target SharePoint environment

SharePoint Server 2016 (on-premise)

What SharePoint development model, framework, SDK or API is this about?

SharePoint REST API

Developer environment

Windows

What browser(s) / client(s) have you tested

Additional environment details

No response

Describe the bug / error

I am using client side features of SharePoint to update an item which have three managed meta data column. One of them is multiple and should be update using hidden field associated with that column and I can update it with usual REST API. The other is a single term column and it can be updated similar to multi one. But the third column can not be update in same way. Actually it updates the item but It returns TaxCatchAll field only with just one term which is implicate an error in the item. I have to manually open the item in edit form and then save it without any change an everything get okay for TaxCatchAll endpoint. I believe that there is some step which is not done in this column by normal REST API. I try to update that column with other client side feature and I get same error in case of JSOM too. But fortunately I can solve the error with old SOAP APIs. I attached my code here and I appreciate every similar experience and the workaround for this problem. The following is my three version of code (REST API, JSOM and SOAP APIs):

updateItem: function (url, listEntityType, fieldsValue, formDigest) {
        fieldsValue['__metadata'] = { type: listEntityType };
        return new Promise((resolve, reject) => {
            $.ajax({
                //url:fullUrl,
                url: url,
                type: 'POST',
                data: JSON.stringify(fieldsValue),
                headers: {
                    'accept': 'application/json;odata=verbose',
                    'content-type': 'application/json;odata=verbose',
                    'X-RequestDigest': formDigest,
                    'X-HTTP-Method': 'MERGE',
                    "IF-MATCH": "*",
                },
                success: function (response, status, xhr) {
                    resolve(response);
                },
                error: function (response, status, xhr) {
                    reject("Item Update Error:" + status);
                }
            });
        });
    },
    updateItemWithJSOM: function (siteUrl, listTitle, itemID, updates) {
        return new Promise((resolve, reject) => {
            SP.SOD.loadMultiple(['sp.js'], function () {
                // create client context
                var ctx = new SP.ClientContext(siteUrl);
                // get list
                var list = ctx.get_web().get_lists().getByTitle(listTitle);
                // get item
                var item = list.getItemById(itemID);

                // set fields
                var formValues = [];
                $.each(Object.keys(updates), function (idx, key) {
                    item.set_item(key, updates[key]);
                    // var field = {
                    //     "FieldName": key,
                    //     "FieldValue": updates[key],
                    // }
                    // formValues.push(field);
                });
                // commit changes                
                // item.validateUpdateListItem(formValues, false);
                item.update();
                ctx.load(item);
                // var values = item.fieldValuesForEdit();
                // ctx.load(values);
                ctx.executeQueryAsync(function () {
                    resolve(item);
                    // item.set_item("Title", values["Title"]);
                    // $.each(Object.keys(updates), function (idx, key) {
                    //     item.set_item(key, values[key]);
                    // });
                    // item.update(); // we double update Item in case of Termstore columns that gives error!
                    // ctx.executeQueryAsync(function () { resolve(item); }, function (err) { reject(err) });
                }, function (err) { reject(err) });
            });

        });
    },
    updateItemWithSOAP: function (url, listname, item_ID, updates, formDigest) {
        var UpdateXML = `<Field Name='ID'>${item_ID}</Field>`;
        $.each(Object.keys(updates), function (idx, key) {
            UpdateXML += `<Field Name='${key}'>${updates[key]}</Field>`;
        });
        UpdateXML = `<Batch><Method ID='1'  Cmd='Update'>${UpdateXML}</Method></Batch>`;
        var soapXML = '<?xml version="1.0" encoding="utf - 8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://schemas.microsoft.com/sharepoint/soap/">' +
            `<soap:Header/><soap:Body><m:UpdateListItems><m:listName>${listname}</m:listName><m:updates>${UpdateXML}</m:updates></m:UpdateListItems></soap:Body></soap:Envelope>`;

        // soapXML=soapXML.trim();// No space allowed at start
        return new Promise((resolve, reject) => {
            var apiUrl = url + "/_vti_bin/lists.asmx";
            $.ajax({
                url: apiUrl,
                type: 'POST',
                dataType: "xml",
                processData: false,
                data: soapXML,
                headers: {
                    "Accept": "text/xml",
                    "X-RequestDigest": formDigest,
                    "content-type": "text/xml; charset=utf-8",
                },
                success: function (response, status, xhr) {
                    debugger
                    resolve(response);
                },
                error: function (response, status, xhr) {
                    reject("Term Add Error:" + status);
                }
            });
        });
    },

Steps to reproduce

It is happened in this case and I am not sure how we can reproduce that bug in other environment. May be I can share that list as template!

Expected behavior

All Column behave similarly and as expected with REST APIs

abdollahkahne commented 5 days ago

After some test and trials I get the following result: The SOAP API works always in case of Updating item/document but REST API apparently do not work for updating although it is okay with creation of item in case of single Taxonomy fields. In case of multi taxonomy both SOAP and REST approaches works. Both single column response same to APIs already with no difference. Possibly it was my mistake that I have though they were different

abdollahkahne commented 5 days ago

REST API also works for updating document metadata in case of uploading documents