从Notes实体下载附件并保存到Microsoft Dynamics CRM中的本地计算机时出现插件路径错误

时间:2016-09-07 10:40:19

标签: c#-4.0 plugins dynamics-crm crm dynamics-crm-online

业务流程错误

  

System.ArgumentException:路径中的非法字符。在   System.IO.Path.GetFileName(String path)at   System.IO.File.InternalWriteAllBytes(String path,Byte [] bytes,   布尔checkHost)at   RetrieveAttachments.RetrieveClass.Execute(的IServiceProvider   的ServiceProvider)

代码如下:

QueryExpression notes = new QueryExpression { EntityName = "annotation", ColumnSet = new ColumnSet("filename", "subject", "annotationid", "documentbody","mimetype") };
                    notes.Criteria.AddCondition("annotationid", ConditionOperator.Equal, annotationid);
                    EntityCollection NotesRetrieve = service.RetrieveMultiple(notes);
                    if (NotesRetrieve != null && NotesRetrieve.Entities.Count > 0)
                    {
                        foreach (var note in NotesRetrieve.Entities)
                        {
                        string fileName = note.GetAttributeValue<string>("filename");
                        //string fileType = note.GetAttributeValue<string>("mimetype");
                        FileIOPermission f = new FileIOPermission(FileIOPermissionAccess.Write, "D:\\note");
                        string fileLocation = f+ fileName;
                        byte[] fileContent = Convert.FromBase64String(NotesRetrieve.Entities[0].Attributes["documentbody"].ToString());
                        System.IO.File.WriteAllBytes(fileLocation, fileContent); 
                        }

                     }
                   }
                  catch (Exception ex)
                   {
                    throw new InvalidPluginExecutionException(ex.ToString());
                   }

4 个答案:

答案 0 :(得分:1)

  

D:\ note是我的机器下载文件的路径。

如果上述方法意味着您尝试使用CRM插件将数据写入本地计算机 - 而不是CRM服务器 - 那么这将无法正常工作。

该插件在CRM服务器上运行,因此无法访问您的客户端计算机。例如。当插件在CRM服务器上运行时查找D:\note - 而不是在您的个人计算机上。

如果要将文件下载到本地计算机,最好创建一个在本地计算机上运行的控制台应用程序。

在任何情况下都有附件下载here的示例。在您的情况下,filePath将是D:\note(但这仍然无法在插件中工作)。

public void ExportDocuments(IOrganizationService service, String filePath)
{
     String fetch = @"<fetch mapping='logical' count='100' version='1.0'>
          <entity name='annotation'>
               <attribute name='filename' />
               <attribute name='documentbody' />
               <attribute name='mimetype' />
          </entity>
     </fetch>";

     foreach (Entity e in service.RetrieveMultiple(new FetchExpression(fetch)))
     {
          if (!String.IsNullOrWhiteSpace(e.Attributes["documentbody"].ToString()))
          {
               byte[] data = Convert.FromBase64String(e.Attributes["documentbody"].ToString());

               File.WriteAllBytes(filePath + e.Attributes["filename"].ToString(), data);
          }
     }
}

答案 1 :(得分:0)

这一行是你罪魁祸首的一部分:

string fileLocation = f+ fileName;

这一行将创建一个无效的文件名,因为FileIOPermission.ToString()返回一个XML片段。

以下是修复该问题的示例,清除非法字符的文件名,并使用Path.Combine构建有效的文件路径。

string fileName = note.GetAttributeValue<string>("filename");
string cleanFileName = string.Empty;

    foreach (var chr in fileName.ToCharArray().ToList())
    {
        if (!Path.GetInvalidFileNameChars().Contains(chr)) cleanFileName = cleanFileName + chr; 
    }

FileIOPermission f = new FileIOPermission(FileIOPermissionAccess.Write, @"D:\note");
string fileLocation = Path.Combine(@"D:\note", cleanFileName);
byte[] fileContent = Convert.FromBase64String(NotesRetrieve.Entities[0].Attributes["documentbody"].ToString());
System.IO.File.WriteAllBytes(fileLocation, fileContent);

答案 2 :(得分:0)

CRM Online仅支持沙盒模式,这意味着它可以隔离代码,您无法在沙箱模式下访问外部环境,在您的情况下,您可以使用本地计算机驱动器。

为了实现您的目标,您可以创建一个控制台应用程序,如James Wood所述,它将文件写入您的本地计算机。

答案 3 :(得分:0)

桑托什,

您可以使用以下代码从Dynamics CRM Online中的Note实体下载附件。

<。cc文件的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Tooling.Connector;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int choice;
            CrmServiceClient crmConn = new CrmServiceClient(ConfigurationManager.ConnectionStrings["CRM"].ConnectionString);
            IOrganizationService crmService = crmConn.OrganizationServiceProxy;
                    QueryExpression w_query = new QueryExpression { EntityName = "annotation", ColumnSet = new ColumnSet("filename","documentbody") };

                    EntityCollection w_account = crmService.RetrieveMultiple(w_query);
                     string name = "";
                    foreach (var count in w_account.Entities)
                    {
                        name = count.GetAttributeValue<string>("filename");

                        string doc_content = count.GetAttributeValue<string>("documentbody");
                        System.IO.FileStream wFile;
                        byte[] byteData = null;
                        if (name != null)
                        {
                            byte[] doc = Convert.FromBase64String(count.GetAttributeValue<string>("documentbody"));
                            byteData = doc;
                            wFile = new FileStream("D:\\attachments\\" + name, FileMode.Append);
                            wFile.Write(byteData, 0, byteData.Length);
                            wFile.Close();
                        }
                    }

                    Console.WriteLine("Please find all attachments in your local D: drive");
                    Console.WriteLine("Press any key to exit...");
                    Console.ReadKey();

            }
        }

    }

.config文件的代码:

<?xml version="1.0" encoding="utf-8"?>
<configuration>


  <connectionStrings>
    <add name="CRM" connectionString="AuthType=Office365;Url=https://your_organization_url; Username=your_user_name; Password=Your_password" />
  </connectionStrings>


    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.22.0.0" newVersion="2.22.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.22.0.0" newVersion="2.22.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

您只需编辑.config文件代码,这应该适合您。

注意:您必须创建C#控制台应用程序并从Nuget添加所需的程序集。