Revit二次开发高级应用(1)——利用wcf做简单的族库管理

版权声明: https://blog.csdn.net/niuge8905/article/details/82931252

因为对应用场景不是特别明确,暂时就用wcf做一个可以上传和下载的功能来管理族库。

1、用WCF做服务端的上传下载管理

首先添加上传下载的接口:

[ServiceContract]
    public interface IFileService
    {
        //上传文件
        [OperationContract]
        UpFileResult UpLoadFile(UpFile filestream);

        //下载文件
        [OperationContract]
        DownFileResult DownLoadFile(DownFile downfile);
    }

    [MessageContract]
    public class DownFile
    {
        [MessageHeader]
        public string FileName { get; set; }
    }

    [MessageContract]
    public class UpFileResult
    {
        [MessageHeader]
        public bool IsSuccess { get; set; }
        [MessageHeader]
        public string Message { get; set; }
    }

    [MessageContract]
    public class UpFile
    {
        [MessageHeader]
        public long FileSize { get; set; }
        [MessageHeader]
        public string FileName { get; set; }
        [MessageBodyMember]
        public Stream FileStream { get; set; }
    }

    [MessageContract]
    public class DownFileResult
    {
        [MessageHeader]
        public long FileSize { get; set; }
        [MessageHeader]
        public bool IsSuccess { get; set; }
        [MessageHeader]
        public string Message { get; set; }
        [MessageBodyMember]
        public Stream FileStream { get; set; }
    }

然后实现接口:

public class FileService : IFileService
    {
        public UpFileResult UpLoadFile(UpFile filedata)
        {
            UpFileResult result = new UpFileResult();

            string path = System.AppDomain.CurrentDomain.BaseDirectory + @"\service\";

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            byte[] buffer = new byte[filedata.FileSize];

            FileStream fs = new FileStream(path + filedata.FileName, FileMode.Create, FileAccess.Write);

            int count = 0;
            while ((count = filedata.FileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                fs.Write(buffer, 0, count);
            }
            //清空缓冲区
            fs.Flush();
            //关闭流
            fs.Close();

            result.IsSuccess = true;

            return result;

        }

        //下载文件
        public DownFileResult DownLoadFile(DownFile filedata)
        {

            DownFileResult result = new DownFileResult();

            string path = System.AppDomain.CurrentDomain.BaseDirectory + @"\service\" + filedata.FileName;

            if (!File.Exists(path))
            {
                result.IsSuccess = false;
                result.FileSize = 0;
                result.Message = "服务器不存在此文件";
                result.FileStream = new MemoryStream();
                return result;
            }
            Stream ms = new MemoryStream();
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            fs.CopyTo(ms);
            ms.Position = 0;  //重要,不为0的话,客户端读取有问题
            result.IsSuccess = true;
            result.FileSize = ms.Length;
            result.FileStream = ms;

            fs.Flush();
            fs.Close();
            return result;
        }
    }

开启服务:

 static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(FileService));
            host.Open();
            Console.WriteLine("开启服务");
            Console.ReadKey();
        }

配置net.tcp绑定,NetTcpBinding用于跨机器交互表现的效果较好,所以这里用这个绑定。对应的环境设置:

<system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
      <bindings>
        <netTcpBinding>
          <binding name="MyTcpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" sendTimeout="00:30:00" transferMode="Streamed"   >
            <security mode="None"></security>
          </binding>
        </netTcpBinding>
      </bindings>
      <services>
            <service name="ServiceTest.FileService">
                <endpoint address="net.tcp://localhost/mysever" binding="netTcpBinding" contract="ServiceTest.IFileService" bindingConfiguration="MyTcpBinding">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8733/Design_Time_Addresses/ServiceTest/Service1/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>

2.客户端实现上传下载

这其中有个重要的一点是,客户端不能用App.config来配置服务环境,所以这里需要用代码来实现配置,这点非常重要,不然会报错,实现不了。根据服务端来实现客户端的绑定配置:

Uri baseUri = new Uri("net.tcp://localhost/mysever");
            EndpointAddress epaddr = new EndpointAddress(baseUri);
            NetTcpBinding binding = new NetTcpBinding();
            binding.Name = "MyTcpBinding";
            binding.MaxBufferSize = 2147483647;
            binding.MaxReceivedMessageSize = 2147483647;
            binding.SendTimeout = new TimeSpan(0,30,0);
            binding.TransferMode = TransferMode.Streamed;
            binding.Security.Mode = SecurityMode.None;

然后客户端还需要写接口,这个跟服务端一样即可。

wpf页面的后台完整代码:

IFileService m_instance;
        public UpDateFileView()
        {
            InitializeComponent();
            Uri baseUri = new Uri("net.tcp://localhost/mysever");
            EndpointAddress epaddr = new EndpointAddress(baseUri);
            NetTcpBinding binding = new NetTcpBinding();
            binding.Name = "MyTcpBinding";
            binding.MaxBufferSize = 2147483647;
            binding.MaxReceivedMessageSize = 2147483647;
            binding.SendTimeout = new TimeSpan(0,30,0);
            binding.TransferMode = TransferMode.Streamed;
            binding.Security.Mode = SecurityMode.None;
            m_instance = ChannelFactory<IFileService>.CreateChannel(binding, epaddr);
        }
        private void updataFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog Fdialog = new OpenFileDialog();

            if (Fdialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {

                using (Stream fs = new FileStream(Fdialog.FileName, FileMode.Open, FileAccess.Read))
                {
                    this.filepath.Text = Fdialog.SafeFileName;
                    UpFileResult result = m_instance.UpLoadFile(new UpFile() {FileName= Fdialog.SafeFileName,FileSize= fs.Length,FileStream= fs});

                    if (result.IsSuccess == true)
                    {
                        System.Windows.MessageBox.Show("上传成功!");
                    }
                    else
                    {
                        System.Windows.MessageBox.Show("上传失败!");
                    }
                }
            }
        }

        private void downloadFile_Click(object sender, RoutedEventArgs e)
        {
            string filename = this.filename.Text;
            string path = System.AppDomain.CurrentDomain.BaseDirectory + @"\client\";
            Stream filestream = new MemoryStream();
            //long filesize = m_instance.DownLoadFile(filename, out issuccess, out message, out filestream);
            DownFileResult filesize = m_instance.DownLoadFile(new DownFile() { FileName = filename });
            if (filesize.IsSuccess)
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                byte[] buffer = new byte[filesize.FileSize];
                FileStream fs = new FileStream(path + filename, FileMode.Create, FileAccess.Write);
                int count = 0;
                while ((count = filestream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    fs.Write(buffer, 0, count);
                }

                //清空缓冲区
                fs.Flush();
                //关闭流
                fs.Close();
                System.Windows.MessageBox.Show("下载成功!");

            }
            else
            {

                System.Windows.MessageBox.Show("下载失败!");

            }
        }

这样就实现了客户端的截面逻辑。

最后实现一下 IExternalCommand接口即可。

namespace Revit
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
    public class Class1 : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UpDateFileView view = new UpDateFileView();
            view.ShowDialog();
            return Result.Succeeded;
        }
    }
}

当然还有许多工作要做,比如上传路径,限定上传文件的后缀名,上传的族文件的管理,用户名及密码的验证等等,这些细节处理好后,就可以实现族库管理的功能。

猜你喜欢

转载自blog.csdn.net/niuge8905/article/details/82931252