zoukankan      html  css  js  c++  java
  • 通过JavaScript调用SOAP终结点执行实体消息

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复148或者20150813可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me!

    利用OData终结点可以方便的对实体执行增删改查操作,可是要执行其他的消息呢?比如案例的关闭(CloseIncidentRequest)消息,实体的共享消息(GrantAccessRequest) 等等怎么办?大家知道用C#代码执行这些消息很方便简单。但是如果使用JavaScript来执行就需要费点功夫了,但是也是可行的,某些情况下很有用,可以使用JavaScript调用OData终结点来执行任何可以执行的消息。请参考SDK的 Walkthrough: Use the Modern app SOAP endpoint with JavaScript 章节进行操作,我这里就实地演示下,最关键的是获取执行消息时候的请求消息文本,我这里是授人以渔。
     
    打开 SDKSampleCodeCSClientSOAPLogger 的这个解决方案,我用的是 Visual Studio 2012打开的,没问题,重新生成下,确保能重新生成成功,如果不成功自己解决。
     
    打开解决方案中的 SOAPLogger.cs 文件,找到下面两行代码
    //Add the code you want to test here:
    // You must use the SoapLoggerOrganizationService 'slos' proxy rather than the IOrganizationService proxy you would normally use.
    就是在这里写你要执行的消息,我这里以分享一个客户记录的读取权限给一个CRM的用户为例,C#版本的代码是这么写的:
    var request = new GrantAccessRequest()
    {
    PrincipalAccess = new PrincipalAccess()
    {
    AccessMask = AccessRights.ReadAccess,
    Principal = new EntityReference("systemuser", new Guid("CC06819E-9AD3-E411-80BC-00155D09F02E"))
    },
    Target = new EntityReference("account", new Guid("FB9A903E-FC3F-E511-80DF-00155D1D7B07"))
    };
    slos.Execute(request);
    确保编译能通过后调试起来,我这里按 F5 启动起来,弹出如下窗口,我输入如下,我这个CRM环境没有做IFD,但是是使用HTTS绑定的,所以第二个选项我输入了Y,大家根据自己的环境做选择啊。
     
    按 Enter 键退出程序后在刚才程序的 binDebug 目录下找到一个名称为 output.txt 的文件,我这里摘录内容如下:
    HTTP REQUEST
    --------------------------------------------------
    POST https://crm2015.luoyong.com/SuGeGeDev/XRMServices/2011/Organization.svc/web
    Content-Type: text/xml; charset=utf-8
    SOAPAction: http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute
    
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
    <Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <request i:type="b:GrantAccessRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">
    <a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
    <a:KeyValuePairOfstringanyType>
    <c:key>Target</c:key>
    <c:value i:type="a:EntityReference">
    <a:Id>fb9a903e-fc3f-e511-80df-00155d1d7b07</a:Id>
    <a:LogicalName>account</a:LogicalName>
    <a:Name i:nil="true" />
    </c:value>
    </a:KeyValuePairOfstringanyType>
    <a:KeyValuePairOfstringanyType>
    <c:key>PrincipalAccess</c:key>
    <c:value i:type="b:PrincipalAccess">
    <b:AccessMask>ReadAccess</b:AccessMask>
    <b:Principal>
    <a:Id>cc06819e-9ad3-e411-80bc-00155d09f02e</a:Id>
    <a:LogicalName>systemuser</a:LogicalName>
    <a:Name i:nil="true" />
    </b:Principal>
    </c:value>
    </a:KeyValuePairOfstringanyType>
    </a:Parameters>
    <a:RequestId i:nil="true" />
    <a:RequestName>GrantAccess</a:RequestName>
    </request>
    </Execute>
    </s:Body>
    </s:Envelope>
    --------------------------------------------------
    
    HTTP RESPONSE
    --------------------------------------------------
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
    <ExecuteResponse xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <ExecuteResult i:type="b:GrantAccessResponse" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">
    <a:ResponseName>GrantAccess</a:ResponseName>
    <a:Results xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
    </ExecuteResult>
    </ExecuteResponse>
    </s:Body>
    </s:Envelope>
    --------------------------------------------------
    可以知道这个文件既记载了请求的消息文本,也记载了返回的消息文本。
    然后我去 http://crm2011soap.codeplex.com/ 下载这个工具,包括了源码,我们就不打开和编译了,直接双击打开 binDebug 文件夹下面的 CRM2011SoapFormatter.exe 文件,如下图:说明,这个工具不是必须的,只是能帮我们更快的转换前面的请求消息为JavaScript代码,当然你也可以手工进行操作。
     
     这个工具怎么使用,官方有一篇文章:CRM 2011 Jscript Soap Request Formatter RELEASED!!   不过国内不能阅读到,原因你懂的,不懂的话你可能是比较少在中国大陆生活。我这里直接上用法了。
    将前面 output.txt 中的请求消息放入到Soap Message的文本框中,其他的字段值根据需要输入,然后点击 Generate 按钮。
     
    我这点击后效果如下,就是Soap Message中的内容变换了,帮你生成代码了。
     
    我这里将前面生成的东西稍微改造下,如下:
    function ShareAccountReadRightRequest(AccountId,SystemUserId)
    {
    var requestMain = ""
    requestMain += "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        ";
        requestMain += " <s:Body>
            ";
            requestMain += " <Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                ";
                requestMain += " <request i:type="b:GrantAccessRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">
                    ";
                    requestMain += " <a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
                        ";
                        requestMain += " <a:KeyValuePairOfstringanyType>
                            ";
                            requestMain += " <c:key>Target</c:key>";
                            requestMain += " <c:value i:type="a:EntityReference">
                                ";
                                requestMain += " <a:Id>
                                    ";
                                    requestMain += AccountId;
                                    requestMain += "
                                </a:Id>";
                                requestMain += " <a:LogicalName>account</a:LogicalName>";
                                requestMain += " <a:Name i:nil="true" />";
                                requestMain += "
                            </c:value>";
                            requestMain += "
                        </a:KeyValuePairOfstringanyType>";
                        requestMain += " <a:KeyValuePairOfstringanyType>
                            ";
                            requestMain += " <c:key>PrincipalAccess</c:key>";
                            requestMain += " <c:value i:type="b:PrincipalAccess">
                                ";
                                requestMain += " <b:AccessMask>ReadAccess</b:AccessMask>";
                                requestMain += " <b:Principal>
                                    ";
                                    requestMain += " <a:Id>
                                        ";
                                        requestMain += SystemUserId;
                                        requestMain += "
                                    </a:Id>";
                                    requestMain += " <a:LogicalName>systemuser</a:LogicalName>";
                                    requestMain += " <a:Name i:nil="true" />";
                                    requestMain += "
                                </b:Principal>";
                                requestMain += "
                            </c:value>";
                            requestMain += "
                        </a:KeyValuePairOfstringanyType>";
                        requestMain += "
                    </a:Parameters>";
                    requestMain += " <a:RequestId i:nil="true" />";
                    requestMain += " <a:RequestName>GrantAccess</a:RequestName>";
                    requestMain += "
                </request>";
                requestMain += "
            </Execute>";
            requestMain += "
        </s:Body>";
        requestMain += "
    </s:Envelope>";
    var req = new XMLHttpRequest();
    //req.open("POST", Xrm.Page.context.getClientUrl() + "/XRMServices/2011/Organization.svc/web", true);
    req.open("POST", GetGlobalContext().getClientUrl() + "/XRMServices/2011/Organization.svc/web", true);
    req.setRequestHeader("Accept", "application/xml, text/xml, */*");
    req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
    req.onreadystatechange = function () { CallSOAPResponse(req); };
    req.send(requestMain);
    }
    
    function CallSOAPResponse(req)
    {
    if (req.readyState == 4) {
    req.onreadystatechange = null; //avoids memory leaks
    if (req.status == 200) {
    //成功我这里什么都不做
    }
    else {
    Xrm.Utility.alertDialog("共享客户失败。请确保共享给的用户对客户实体至少具有最低级别的读取权限。");
    }
    }
    }
     这样就可以方便的在JavaScript中调用了。
     
     
  • 相关阅读:
    sql中实现先排序后分组
    mysql中的锁机制之概念篇
    PHP对程序员的要求更高
    给初学PHP的学习线路和建议
    设计模式六大原则
    Mysql忘记密码怎么办
    数据库 sql
    精准优化 if…else ,干掉,过多,烂代码!
    JDK1.8 新特性(全)
    mysql 如何修改 删除 添加 表主键
  • 原文地址:https://www.cnblogs.com/luoyong0201/p/Dynamics_365_Execute_Message_Through_SOAP_Endpoint.html
Copyright © 2011-2022 走看看