【问题标题】:CRM16 - Trigger custom action from WebApiCRM16 - 从 WebApi 触发自定义操作
【发布时间】:2017-01-24 12:28:43
【问题描述】:

我在 CRM 中构建了一个自定义操作,我需要通过其 WebAPI 触发该操作。自定义操作已激活,创建时我在 CRM 中没有遇到任何错误。

我尝试从 VB.NET 应用程序中调用此操作,例如:

Dim httpch As New HttpClientHandler
Dim requestUri As String = "contacts(1fcfd54a-15d3-e611-80dc-0050569ea396)/Microsoft.Dynamics.CRM.new_addnotetocontact"
httpch.Credentials = New NetworkCredential("username", "password", "domain")
Dim httpClient As New HttpClient(httpch)
httpClient.BaseAddress = New Uri(CRMWebApiUri)
httpClient.Timeout = New TimeSpan(0, 2, 0)
httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0")
httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0")
httpClient.DefaultRequestHeaders.Add("Prefer", "odata.include-annotations='OData.Community.Display.V1.FormattedValue'")
httpClient.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
Dim jsonNote As JObject = New JObject(New JProperty("NoteTitle", "'Mails have been deleted'"), New JProperty("NoteText", "This contacts SmarterMail data has been deleted due to inactivity"))
Dim postData = New StringContent(jsonNote.ToString(), Encoding.UTF8, "application/json")

Dim retrieveContactResponse As HttpResponseMessage = httpClient.PostAsync(requestUri, postData).Result

我得到的是带有消息的状态 400:

请求消息有未解析的参数。

我可以对同一站点进行其他调用并获取所有联系人作为示例

这是什么意思,我该如何解决?

【问题讨论】:

标签: vb.net asp.net-web-api dynamics-crm crm dynamics-crm-webapi


【解决方案1】:

这是什么意思,我该如何解决?

引用Request message has unresolved parameters.

当您在调用操作时收到此错误时,在 CRM 中。那么可能会有 背后的三个原因

  1. 您传递的某些参数有误。 (确保动作名称正确传递)
  2. 您的操作未激活
  3. 您的操作名称重复,一个操作处于活动模式,另一个处于草稿状态。(因为这是从 CRM 端完成的,必须处于 仅草稿两个同名操作不会同时处于活动状态。)

没有。 2 已被处理,因为它已经声明自定义操作已激活。

没有。 3 在链接的文章中得到解决,如果您在 CRM 中两次导入操作或无意中创建了两个具有相同名称的操作,则该操作是合理的。

为了解决第一个问题,我建议创建一个对象模型来保存要发送的数据

Public Class Note 
    Public Property NoteTitle As String
    Public Property NoteText As String
End Class

CRM 对正确的参数格式非常挑剔。参数名称也区分大小写。 NoteTitle 中的 '' 会在序列化时引起问题。 此外,如果可能,请使用 NewtonSoft.Json 来制作 JSON 有效负载,而不是尝试自行构建。

'Handler with credentials
Dim httpClientHandler As New HttpClientHandler With {
    .Credentials = New NetworkCredential("username", "password", "domain")}
'Create and configure HTTP Client 
Dim httpClient As New HttpClient(httpClientHandler) With {
    .BaseAddress = New Uri(CRMWebApiUri),
    .Timeout = New TimeSpan(0, 2, 0)}
httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0")
httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0")
httpClient.DefaultRequestHeaders.Add("Prefer", "odata.include-annotations='OData.Community.Display.V1.FormattedValue'")
httpClient.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))

'Create and populate data to be sent
Dim model As New Note With { 
    .NoteTitle = "Mails have been deleted", 
    .NoteText = "This contacts SmarterMail data has been deleted due to inactivity"}
'Serialize mode to well formed JSON
Dim json As String = JsonConvert.SerializeObject(model)
Dim postData = New StringContent(json, Encoding.UTF8, "application/json")
'invoking action using the fully qualified namespace of action message
Dim requestUri As String = "contacts(1fcfd54a-15d3-e611-80dc-0050569ea396)/Microsoft.Dynamics.CRM.new_addnotetocontact"
'POST the data
Dim retrieveContactResponse As HttpResponseMessage = Await httpClient.PostAsync(requestUri, postData)

其他参考Dynamics CRM 2016: Use Web API actions

调用绑定函数时,必须包含函数的全名 包括Microsoft.Dynamics.CRM 命名空间的函数。如果你不 包括全名,您将收到以下错误:Status Code:400 请求消息有未解析的参数。

【讨论】:

    【解决方案2】:

    把名字new_addnotetocontact改成new_AddNoteToContact就行了。

    Dim requestUri As String = "contacts(1fcfd54a-15d3-e611-80dc-0050569ea396)/Microsoft.Dynamics.CRM.new_AddNoteToContact"
    

    流程架构如下:

    <Action Name="new_AddNoteToContact" IsBound="true">
      <Parameter Name="entity" Type="mscrm.contact" Nullable="false" />
      <Parameter Name="NoteTitle" Type="Edm.String" Nullable="false" Unicode="false" />
      <Parameter Name="NoteText" Type="Edm.String" Nullable="false" Unicode="false" />
      <ReturnType Type="mscrm.annotation" Nullable="false" />
    </Action>
    

    唯一名称: new_AddNoteToContact

    参考:https://msdn.microsoft.com/en-us/library/mt607600.aspx#Anchor_3

    更新:如果您在创建操作后编辑了唯一名称,则将在 Processes 实体中创建重复项。请从 Adv.Find 中删除欺骗

    【讨论】:

      【解决方案3】:

      我前段时间解决了这个问题,但没有时间回复它。就我而言,问题是我自己提出请求的方式

      而不是问题中所述的以下方式:

      Dim postData = New StringContent(jsonNote.ToString(), Encoding.UTF8, "application/json")
      Dim retrieveContactResponse As HttpResponseMessage = httpClient.PostAsync(requestUri, postData).Result
      

      我没有使用httpClient.PostAsync方法并直接提供StringContent对象,而是使用HttpRequestMessage对象并给出StringContent对象,然后将HttpRequestMessage对象提供给httpClient的SendAsync方法,这似乎已经解决了我的问题,因为它现在正在工作。另请注意,在原始问题中,我在要发布的 JObject 中的第一个 JProperty 的值中有引号,但我不确定这与它有什么关系,但只是将它发布在这里,因为它与原始的不同代码:

      Dim jsonNote As JObject = New JObject(New JProperty("NoteTitle", "Mails have been deleted"), New JProperty("NoteText", "This contact's SmarterMail data has been deleted automatically due to inactivity on their CRM account"))
      ...
      Dim reqMsg As New HttpRequestMessage(HttpMethod.Post, CRMWebApiUri + requestUri)
      reqMsg.Content = New StringContent(jsonNote.ToString(), Encoding.UTF8, "application/json")
      Dim retrieveContactResponse As HttpResponseMessage = httpClient.SendAsync(reqMsg).Result
      

      【讨论】: