通过Web服务创建实体随机失败,出现0x80048405(访问被拒绝)

时间:2011-01-12 10:15:28

标签: web-services dynamics-crm dynamics-crm-4

我们有一个公共ASP.NET Web UI,用作底层CRM4实例的有限前端。通过CRM4 SDK Web服务实现通信:

var service = new Microsoft.Crm.SdkTypeProxy.CrmService();
service.Credentials = new System.Net.NetworkCredential("user", "pass", "domain");
service.Url = server + "/MSCRMServices/2007/CrmService.asmx";

var token = new CrmAuthenticationToken();
token.OrganizationName = organizationName;
service.CrmAuthenticationTokenValue = token;    
service.PreAuthenticate = true;

使用xml查询调用fetch总是成功,但有时实体创建失败:

var entity = new DynamicEntity("some_entity");
var resultGuid = service.Create(entity);

创建iisreset后总是失败。 IIS日志说两个对CRM服务的POST请求:

  1. 无用户,HTTP 401.5
  2. 域/用户,HTTP 500.0
  3. 返回的异常是:

    [SoapException: Server was unable to process request.]
       System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) +1769861
       System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +345
       Microsoft.Crm.SdkTypeProxy.CrmService.Create(BusinessEntity entity) +79
    

    Soapexception详情:

    <detail><error>
      <code>0x80048405</code>
      <description>Access is denied.</description>
      <type>Platform</type>
    </error></detail>
    

    当任何人使用CRM自己的UI手动创建some_entity时,事情会变得奇怪。之后,Web服务访问没有问题。

    更多说明:

    1. 在CRM自己的UI中删除或更新不会修复Web服务访问
    2. CRM apppool使用最多1个工作进程。
    3. 一段时间后,Web服务再次中断“拒绝访问”(可能是回收wp)
    4. 错误不依赖于数据。
    5. 删除PreAuthenticate并未改变任何内容。
    6. 在事件日志中没有任何用处。
    7. 有人能帮助我摆脱那种奇怪的拒绝访问错误吗?为什么触摸CRM UI会改变Web服务行为?

      编辑: 尽管Michael M提供了错误的解决方法,但我仍然不明白CRM UI为何/如何影响CrmService身份验证。

1 个答案:

答案 0 :(得分:3)

您的令牌可能不正确。根据您的身份验证类型,您可能还需要更改令牌的AuthenticationType。请尝试以下方法来获取服务的实例。

private static CrmService GetService(string organization, string server, string domain,
                     string username, string password)
    {
        server = server.TrimEnd(new[] {'/'});

        // Initialize an instance of the CrmDiscoveryService Web service proxy.
        var disco
            = new CrmDiscoveryService
                {
                    Url = String.Format("{0}/MSCRMServices/2007/SPLA/CrmDiscoveryService.asmx", server)
                };

        //Retrieve a list of available organizations.
        var orgResponse =
            (RetrieveOrganizationsResponse) disco.Execute(
                new RetrieveOrganizationsRequest
                    {
                        UserId = domain + "\\" + username,
                        Password = password
                    });

        //Find the desired organization.
        foreach (var orgDetail in orgResponse.OrganizationDetails)
        {
            if (orgDetail.OrganizationName != organization)
                continue;

            //Retrieve the ticket.
            var ticketResponse =
                (RetrieveCrmTicketResponse) disco.Execute(
                    new RetrieveCrmTicketRequest
                        {
                            OrganizationName = organization,
                            UserId = domain + "\\" + username,
                            Password = password
                        });

            //Create the CrmService Web service proxy.
            var token = new CrmAuthenticationToken
                {
                    AuthenticationType = 2,
                    OrganizationName = organization,
                    CrmTicket = ticketResponse.CrmTicket
                };

            return new CrmService
                {
                    CrmAuthenticationTokenValue = token,
                    Url = orgDetail.CrmServiceUrl
                };
        }
        return null;
    }