Error while trying to change attribute with "Put"

Jul 15, 2010 at 1:34 PM
Hi all, Im using the client to change an attribute of a user, but i get the following error: {"The endpoint could not dispatch the request."} i am able to create accounts successfully but for some reason cant change their attributes. i also checked the MPR and verified that administrators can change this attribute... here is my code: using (DefaultClient client = new DefaultClient()) { // set credentials and refresh schema client.ClientCredential = new System.Net.NetworkCredential("administrator", "password", "domain"); client.RefreshSchema(); foreach (RmPerson person in client.Enumerate("/Person[EmployeeID=60001]")) { RmResourceChanges changes = new RmResourceChanges(person); try { person.Department = "Approved"; client.Put(changes);. changes.AcceptChanges(); } catch(Exception ex) { changes.DiscardChanges(); throw; } } Any help will be much appreciated! Thanks, Guy.
Developer
Jul 15, 2010 at 2:45 PM

Do you see the Request in the request log on the portal?

Are there any clues in the request information about the error that occurred?

-Jeremy

Coordinator
Jul 15, 2010 at 2:56 PM

You must add a call to changes.BeginChanges immediately after creating the RmResourceChanges object. 

The call (my fault) was missing in the documentation, now I fixed the example. Check "modifying a resource" in the "Use of the DefaultClient" page.

Cheers,
Paolo

Jul 18, 2010 at 7:42 AM
Hi Paolo, It works :) thanks alot!!!! Guy.
Developer
Nov 4, 2010 at 5:00 PM
Edited Nov 4, 2010 at 5:00 PM

I too get this error message, but do have the changes.BeginChanges() call in my code.

I'm working on a RmResource object, trying to add in an attribute.

I'm able to create entities okay, but upadting via Put() fails.

I don't see anything in the Requests list in FIM.

 

Any pointers?

Developer
Nov 5, 2010 at 9:18 AM
Edited Nov 5, 2010 at 10:19 AM

Here's my code. Debugging it shows everything is as expected up until client.Put(changes), that's when it blows up.

I'm trying to add in a new attribute (or update an existing one if it exists).

 

 

var query = string.Format("/Team[globalid='123']";
            var resources = client.Enumerate(query);
            var resource = resources.ElementAt(0);
            var changes = new RmResourceChanges(resource);

            try
            {
                changes.BeginChanges();

                // only supporting reference attribute updates for now...
                // reference attributes.
                foreach (var kvp in rmorefattrs)
                {
                    var key = new RmAttributeName(kvp.Key);
                    var isMva = kvp.Value.Contains(",");
                    var stringSeparators = new[] { "," };
                    var values = isMva ? kvp.Value.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries) : new[] { kvp.Value };
                    var attributeValue = new RmAttributeValue(isMva);

                    foreach (var res in values.SelectMany(client.Enumerate))
                        attributeValue.Values.Add(res.Attributes[new RmAttributeName("ObjectID")].Value.ToString());

                    if (resource.Attributes.ContainsKey(key))
                        resource.Attributes[key] = attributeValue;
                    else
                        resource.Attributes.Add(key, attributeValue);
                }

                client.Put(changes);
                changes.AcceptChanges();
                return true;
            }
            catch (Exception ex)
            {
                changes.DiscardChanges();
                throw;
            }

Edit: I dumped all the existing attribute code and just tried updating a simple attribute and it worked, so clearly there's a problem with adding in this new attribute. This code was taken from the create-entity method I have, which does work though. Ergh, a lead at least...

Edit2: The FIM event-log shows this helpful entry:

 

Requestor: urn:uuid:a0acb76b-9f5f-4837-8977-03b9d08fe866
System.Runtime.Serialization: System.Xml.XmlException: The value '' cannot be parsed as the type 'UniqueId'. ---> System.FormatException: UniqueId cannot be zero length.
   at System.Xml.UniqueId..ctor(String value)
   at System.Xml.XmlDictionaryReader.ReadElementContentAsUniqueId()
   --- End of inner exception stack trace ---
   at System.Xml.XmlDictionaryReader.ReadElementContentAsUniqueId()
   at Microsoft.ResourceManagement.WebServices.XPathLevel1DialectParser.ParseXPathFragmentValue(String attributeName, XmlNode xpathFragmentValue)
   at Microsoft.ResourceManagement.WebServices.XPathLevel1DialectParser.ParseXPathFragmentType(FragmentType xpathFragment)
   at Microsoft.ResourceManagement.WebServices.XPathLevel1DialectParser.ParseUpdate(PutFragmentType[] putFragments)
   at Microsoft.ResourceManagement.WebServices.ResourceManagementService.Put(Message request)

Developer
Nov 5, 2010 at 10:44 AM

Okay, I think this is a client bug, as the request message being sent to FIM looks like this:

 

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action>
  </s:Header>
  <s:Body>
    <ModifyRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Dialect="http://schemas.microsoft.com/2006/11/ResourceManagement/Dialect/IdentityAttributeType-20080602" xmlns="http://schemas.microsoft.com/2006/11/IdentityManagement/DirectoryAccess">
      <Change Operation="Replace">
        <AttributeType>Manager</AttributeType>
        <AttributeValue>
          <Manager xmlns="http://schemas.microsoft.com/2006/11/ResourceManagement" />
        </AttributeValue>
      </Change>
    </ModifyRequest>
  </s:Body>
</s:Envelope>

There's no guid value in there, and I suspect the Operation parameter should be "Create" not "Replace", as that's what's sent if I do this via the FIM portal.

Developer
Nov 5, 2010 at 11:10 AM

Yep, it's a bug in the client.

Microsoft.ResourceManagement.ObjectModel.RmResourceChanges

Line 142:

//changedAttributes.Add(new RmAttributeChange(sourceItem.Key, null, RmAttributeChangeOperation.Replace));
changedAttributes.Add(new RmAttributeChange(sourceItem.Key, sourceItem.Value.ToString(), RmAttributeChangeOperation.Add));

Comment-out line is the original. Line below is my change which works. The sourceItem.Value when cast as IComparable returned null, I'm not sure why, so the string cast solved that, but I don't know if that's a viable fix for all cases?