Microsoft Dynamics CRM 2016 Web API Put request cl

2019-09-10 23:20发布

问题:

I'm trying to use a put request to update Dynamics CRM. When I run the following python code I get a 204 response, but instead of updating a value it clears it. For example firstname gets updated to null instead of "WebApiUpdate".

import adal
import json
import urllib2
import requests

endpoint = "https://login.microsoftonline.com/00000000-0000-0000-0000-000000000002"
username = "example@example.com"
password = "password"
resource_uri = "https://orgname.crm.dynamics.com"

token_response = adal.acquire_token_with_username_password(endpoint,username,password,resource= resource_uri)
print token_response['accessToken']




payload = { "value": "WebApiUpdate"}
url = "http://xxxxx.crm.dynamics.com/api/data/v8.0/contacts(00000000-0000-0000-0000-000000000001)/firstname"
headers = {"Authorization":"Bearer "+token_response['accessToken']}
r = requests.put(url,data=payload,headers=headers)
print r.content

回答1:

Solution:

  1. set the url to be https:// instead of http://
  2. set data = payload to json = payload in the request. ex:

    r = requests.put(url,json=payload,headers=headers)
    

What was going wrong:

  1. The initial call, which included the payload (regardless of if it was set to data or json), received a response of HTTP/1.0 301 Moved Permanently. In this response was a header with the new location. This location simply included https:// in the url. Then my code sent out a second put request that went to the correct https url, had the correct header parameters, but did not include the payload. This caused my put request to not include the value to update to, so Microsoft Dynamics CRM set the value to null.

  2. Microsoft Dynamics CRM requires the put request payload to be formatted in json. After I updated the link to be https:// and the payload was included, it was formatted as x-www-form-urlencoded.That means the payload was appended to the request as value=WebApiUpdate. This caused a reply of HTTP/1.1 400 Bad Request. Changing the payload to be formatted as json means the payload will be appended to the request as {"value": "WebApiUpdate"}.

How I solved it:

  1. I set my program to output the http put call it was making by adding the below code that I found from this stack overflow question. I then noticed that there were two non identical put calls and went from there.

    import logging
    
    try:
        import http.client as http_client
    except ImportError:
        # Python 2
        import httplib as http_client
    http_client.HTTPConnection.debuglevel = 1
    logging.basicConfig() 
    logging.getLogger().setLevel(logging.DEBUG)
    requests_log = logging.getLogger("requests.packages.urllib3")
    requests_log.setLevel(logging.DEBUG)
    requests_log.propagate = True
    
  2. I read the documentation on the request method here which I found on this stack overflow question