Exemple #1
0
        public override async Task <FileReply> GetResourceById(StringId request, ServerCallContext context)
        {
            var reply = new FileReply();

            if (string.IsNullOrWhiteSpace(request.Id))
            {
                reply.Error = Error.InvalidArguments;
                return(reply);
            }

            if (!Guid.TryParse(request.Id, out var fileId))
            {
                reply.Error = Error.NoSuchEntity;
                return(reply);
            }

            var items = _service.All().Where(f => f.Type == (int)FileType.Resource);

            items = await FilterPrivate(items, context);

            var file = await items.Where(k => k.Id == fileId).FirstOrDefaultAsync();

            if (file != null)
            {
                reply.File = Converter(file);
            }

            return(reply);
        }
Exemple #2
0
        public IActionResult toReplyTo(QuestionAnswer model, string returnUrl = null)
        {
            // var us = await GetCurrentUserAsync();
            FileReply am = new FileReply();

            am.RefAId = model.AId;
            am.QId    = model.QId;
            // am.UserName=Model.UserName;
            return(PartialView("ReplyTo", am));
        }
Exemple #3
0
        public override async Task <FileReply> Move(MoveRequest request, ServerCallContext context)
        {
            var reply = new FileReply();
            var user  = await _userService.GetUser(context.GetHttpContext());

            if (user == null)
            {
                reply.Error = Error.NeedLogin;
                return(reply);
            }

            if (!user.HasWritePermission())
            {
                reply.Error = Error.NoPermission;
                return(reply);
            }

            if (!Guid.TryParse(request.Id, out var id) || !Guid.TryParse(request.ParentId, out var parentId))
            {
                reply.Error = Error.InvalidArguments;
                return(reply);
            }

            var file = await _service.All().Where(i => i.Id == id).Include(i => i.Parent).FirstOrDefaultAsync();

            if (file == null)
            {
                reply.Error = Error.NoSuchEntity;
                return(reply);
            }

            var parent = await _service.All().Where(i => i.Id == parentId && i.Type == (int)FileType.Folder)
                         .FirstOrDefaultAsync();

            if (parent == null)
            {
                reply.Error = Error.NoSuchEntity;
                return(reply);
            }

            using (var trans = _service.Context.BeginTransaction())
            {
                if (file.Type == (int)FileType.Normal && file.Parent != null &&
                    file.Parent.Type == (int)FileType.Folder)
                {
                    file.Parent.Weight = Math.Max(0, (file.Parent.Weight ?? 0) - 1);
                    await _service.Update(file.Parent);
                    await ClearFolderVersionsCache();
                }
                else if (file.Type == (int)FileType.Folder)
                {
                    await ClearFolderVersionsCache();
                }

                var childrenPathSuffix = file.Path + PathSep;
                file.ParentId = parent.Id;
                file.Parent   = parent;
                file.Path     = JoinPath(parent.Path, file.Name);
                file          = await _service.Update(file);

                var children = _service.All()
                               .Where(n => n.Path !.StartsWith(childrenPathSuffix));
                if (children.Any())
                {
                    foreach (var sub in children)
                    {
                        sub.Path = JoinPath(file.Path, sub.Path !.Substring(childrenPathSuffix.Length));
                    }

                    await _service.UpdateRange(children);
                }

                if (file.Type == (int)FileType.Normal && file.Parent != null &&
                    file.Parent.Type == (int)FileType.Folder)
                {
                    file.Parent.Weight = Math.Max(0, (file.Parent.Weight ?? 0) + 1);
                    await _service.Update(file.Parent);
                }

                await trans.Commit();
            }

            reply.File = Converter(file);
            return(reply);
        }
Exemple #4
0
        public override async Task <FileReply> UpdateName(UpdateNameRequest request, ServerCallContext context)
        {
            var reply = new FileReply();
            var user  = await _userService.GetUser(context.GetHttpContext());

            if (user == null)
            {
                reply.Error = Error.NeedLogin;
                return(reply);
            }

            if (!user.HasWritePermission())
            {
                reply.Error = Error.NoPermission;
                return(reply);
            }

            if (!ValidateFileName(request.Name))
            {
                reply.Error = Error.InvalidArguments;
                return(reply);
            }

            if (!Guid.TryParse(request.Id, out var id))
            {
                reply.Error = Error.InvalidArguments;
                return(reply);
            }

            var item = await _service.All().Where(i => i.Id == id).FirstOrDefaultAsync();

            if (item == null)
            {
                reply.Error = Error.NoSuchEntity;
                return(reply);
            }

            using (var trans = _service.Context.BeginTransaction())
            {
                var childrenPathSuffix = item.Path + PathSep;
                item.Name = request.Name;
                item.Path = JoinPath(GetParentPath(item.Path), item.Name);
                item      = await _service.Update(item);

                var children = _service.All()
                               .Where(n => n.Path !.StartsWith(childrenPathSuffix));
                if (children.Any())
                {
                    foreach (var sub in children)
                    {
                        sub.Path = JoinPath(item.Path, sub.Path !.Substring(childrenPathSuffix.Length));
                    }

                    await _service.UpdateRange(children);
                }

                await trans.Commit();
            }

            reply.File = Converter(item);
            if (item.Type == (int)FileType.Folder)
            {
                await ClearFolderVersionsCache();
            }
            if (item.Type == (int)FileType.Normal || item.Type == (int)FileType.Folder)
            {
                await ClearFileWeightsCache(item.Path);
            }

            return(reply);
        }
Exemple #5
0
        public override async Task <FileReply> Add(AddRequest request, ServerCallContext context)
        {
            var reply = new FileReply();
            var user  = await _userService.GetUser(context.GetHttpContext());

            if (user == null)
            {
                reply.Error = Error.NeedLogin;
                return(reply);
            }

            if (!user.HasWritePermission())
            {
                reply.Error = Error.NoPermission;
                return(reply);
            }

            if (!ValidateFileName(request.Name))
            {
                reply.Error = Error.InvalidArguments;
                return(reply);
            }

            var file = new File
            {
                Type = (int)request.FileType, Name = request.Name, Created = DateTime.Now, Modified = DateTime.Now
            };

            if (!string.IsNullOrWhiteSpace(request.ParentId))
            {
                if (!Guid.TryParse(request.ParentId, out var parentId))
                {
                    reply.Error = Error.NoSuchEntity;
                    return(reply);
                }

                var parent = await _service.All()
                             .FirstOrDefaultAsync(f => f.Id == parentId && f.Type == (int)FileType.Folder);

                if (parent == null)
                {
                    reply.Error = Error.NoSuchEntity;
                    return(reply);
                }

                file.Parent = parent;
                file.Path   = JoinPath(parent.Path, file.Name);
            }
            else
            {
                file.Path = PathSep + file.Name;
            }

            using (var trans = _service.Context.BeginTransaction())
            {
                file = await _service.Add(file);

                if (file.Type == (int)FileType.Normal && file.Parent != null &&
                    file.Parent.Type == (int)FileType.Folder)
                {
                    file.Parent.Weight = (file.Parent.Weight ?? 0) + 1;
                    await _service.Update(file.Parent);
                    await ClearFolderVersionsCache();
                }
                else if (file.Type == (int)FileType.Folder)
                {
                    await ClearFolderVersionsCache();
                }
                if (file.Type == (int)FileType.Normal)
                {
                    await ClearFileWeightsCache(file.Path);
                }

                await trans.Commit();
            }

            reply.File = Converter(file);
            return(reply);
        }
Exemple #6
0
        public async Task <IActionResult> ReplyToQ(FileReply model, string returnUrl = null)
        {
            var us = await GetCurrentUserAsync();

            if (ModelState.IsValid)
            {
                // {   Console.WriteLine(model.Reply);
                AnswerModel qt = new AnswerModel {
                    // Reply=model.Reply,
                    // QId = model.QId,
                    // Time = DateTime.Now,
                    // ApplicationUser = us,
                    // RefAId = model.RefAId

                    Reply    = model.Reply,
                    QId      = model.QId,
                    Time     = DateTime.Now,
                    UserName = us.UserName,
                    RefAId   = model.RefAId
                };

                // var size=model.File.Length;



                // static string filePath = IHostingEnvironment.ContentRootPath + "\\wwwroot\\files\\"+ fileName;

                // if (model.File==null){
                //     Console.WriteLine("Nothing!");
                // }
                // model.File.SaveAs(IHostingEnvironment.ContentRootPath + "\\wwwroot\\files\\"+ fileName);
                if (model.File != null && model.File.Length != 0)
                {
                    var fileName = ContentDispositionHeaderValue
                                   .Parse(model.File.ContentDisposition)
                                   .FileName.Trim('"');
                    var path = Path.Combine(
                        "files",
                        fileName);

                    using (var stream = new FileStream(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/", path), FileMode.Create))
                    {
                        await model.File.CopyToAsync(stream);
                    }
                    qt.FilePath     = path;
                    qt.FileName     = fileName;
                    qt.FileUploaded = true;
                }



                db.Answers.Add(qt);
                db.SaveChanges();
                //return RedirectToAction("QuestionPage","Question", new { QId = qt.QId });
            }



            QuestionAnswer _model = new QuestionAnswer();

            _model.Answers  = db.Answers.ToList();
            _model.UserName = us.UserName;
            _model.QId      = model.QId;

            var fa = from i in db.Questions where i.QId == model.QId select i;
            var fe = fa.ToList <QuestionModel>().FirstOrDefault();

            _model.QuestionTitle   = fe.Title;
            _model.QuestionContent = fe.Description;
            //_model.Time=fe.Time;
            return(PartialView("QuestionPage", _model));



            // AnswerModel am=new AnswerModel();
            // am.RefAId=model.AnswerId;
            // am.QId=model.QId;
            // am.ApplicationUser=us;
            // return (am);
        }
        /// <summary>
        /// 文件下载
        /// </summary>
        /// <param name="request">下载请求</param>
        /// <param name="responseStream">文件写入流</param>
        /// <param name="context">站点上下文</param>
        /// <returns></returns>
        public override async Task FileDownload(FileRequest request, global::Grpc.Core.IServerStreamWriter <FileReply> responseStream, global::Grpc.Core.ServerCallContext context)
        {
            List <string> lstSuccFiles = new List <string>(); //传输成功的文件
            DateTime      startTime    = DateTime.Now;        //传输文件的起始时间
            int           chunkSize    = 1024 * 1024;         //每次读取的数据
            var           buffer       = new byte[chunkSize]; //数据缓冲区
            FileStream    fs           = null;                //文件流

            try
            {
                //reply.Block数字的含义是服务器和客户端约定的
                for (int i = 0; i < request.FileNames.Count; i++)
                {
                    string    fileName = request.FileNames[i];                      //文件名
                    string    filePath = Path.GetFullPath($".//Files\\{fileName}"); //文件路径
                    FileReply reply    = new FileReply
                    {
                        FileName = fileName,
                        Mark     = request.Mark
                    };                                                    //应答数据
                    Console.WriteLine($"{request.Mark},下载文件:{filePath}"); //写入日志,下载文件
                    if (File.Exists(filePath))
                    {
                        fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, chunkSize, useAsync: true);

                        //fs.Length  可以告诉客户端所传文件大小
                        int readTimes = 0;//读取次数
                        while (true)
                        {
                            int readSise = fs.Read(buffer, 0, buffer.Length); //读取数据
                            if (readSise > 0)                                 //读取到了数据,有数据需要发送
                            {
                                reply.Block   = ++readTimes;
                                reply.Content = Google.Protobuf.ByteString.CopyFrom(buffer, 0, readSise);
                                await responseStream.WriteAsync(reply);
                            }
                            else//没有数据了,就告诉对方,读取完了
                            {
                                reply.Block   = 0;
                                reply.Content = Google.Protobuf.ByteString.Empty;
                                await responseStream.WriteAsync(reply);

                                lstSuccFiles.Add(fileName);
                                Console.WriteLine($"{request.Mark},完成发送文件:{filePath}"); //日志,记录发送成功
                                break;                                                  //跳出去
                            }
                        }
                        fs?.Close();
                    }
                    else
                    {
                        Console.WriteLine($"文件【{filePath}】不存在。"); //写入日志,文件不存在
                        reply.Block = -1;                         //-1的标记为文件不存在
                        await responseStream.WriteAsync(reply);   //告诉客户端,文件状态
                    }
                }
                //告诉客户端,文件传输完成
                await responseStream.WriteAsync(new FileReply
                {
                    FileName = string.Empty,
                    Block    = -2,//告诉客户端,文件已经传输完成
                    Content  = Google.Protobuf.ByteString.Empty,
                    Mark     = request.Mark
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{request.Mark},发生异常({ex.GetType()}):{ex.Message}");
            }
            finally
            {
                fs?.DisposeAsync();
            }
            Console.WriteLine($"{request.Mark},文件传输完成。共计【{lstSuccFiles.Count / request.FileNames.Count}】,耗时:{DateTime.Now - startTime}");
        }
Exemple #8
0
        /// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="filesPath">文件路径</param>
        /// <param name="mark">标记</param>
        /// <param name="cancellationToken">异步取消命令</param>
        /// <returns>下载任务(是否成功、原因、成功的文件名)</returns>
        public static async Task <TransferResult <List <string> > > FileUpload(List <string> filesPath, string mark, System.Threading.CancellationToken cancellationToken = new System.Threading.CancellationToken())
        {
            var result = new TransferResult <List <string> > {
                Message = "没有文件需要下载"
            };

            if (filesPath.Count == 0)
            {
                return(await Task.Run(() => result));//没有文件需要下载
            }
            result.Message = "未能连接到服务器。";
            var lstSuccFiles = new List <string>();//传输成功的文件
            int chunkSize    = 1024 * 1024;

            byte[]     buffer  = new byte[chunkSize]; //每次发送的大小
            FileStream fs      = null;                //文件流
            Channel    channel = null;                //申明通信频道

            GrpcService.FileTransfer.FileTransferClient client = null;
            DateTime startTime = DateTime.Now;

            try
            {
                (channel, client) = GetClient();
                using (var stream = client.FileUpload())//连接上传文件的客户端
                {
                    //reply.Block数字的含义是服务器和客户端约定的
                    foreach (var filePath in filesPath)//遍历集合
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            break;//取消了传输
                        }
                        FileReply reply = new FileReply()
                        {
                            FileName = Path.GetFileName(filePath),
                            Mark     = mark
                        };
                        if (!File.Exists(filePath))                 //文件不存在,继续下一轮的发送
                        {
                            Console.WriteLine($"文件不存在:{filePath}"); //写入日志
                            continue;
                        }
                        fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, chunkSize, useAsync: true);
                        int readTimes = 0;
                        while (true)
                        {
                            if (cancellationToken.IsCancellationRequested)
                            {
                                reply.Block   = -1;                           //取消了传输
                                reply.Content = Google.Protobuf.ByteString.Empty;
                                await stream.RequestStream.WriteAsync(reply); //发送取消传输的命令

                                break;                                        //取消了传输
                            }
                            int readSize = fs.Read(buffer, 0, buffer.Length); //读取数据
                            if (readSize > 0)
                            {
                                reply.Block   = ++readTimes;//更新标记,发送数据
                                reply.Content = Google.Protobuf.ByteString.CopyFrom(buffer, 0, readSize);
                                await stream.RequestStream.WriteAsync(reply);
                            }
                            else
                            {
                                Console.WriteLine($"完成文件【{filePath}】的上传。");
                                reply.Block   = 0;                            //传送本次文件发送结束的标记
                                reply.Content = Google.Protobuf.ByteString.Empty;
                                await stream.RequestStream.WriteAsync(reply); //发送结束标记

                                //等待服务器回传
                                await stream.ResponseStream.MoveNext(cancellationToken);

                                if (stream.ResponseStream.Current != null && stream.ResponseStream.Current.Mark == mark)
                                {
                                    lstSuccFiles.Add(filePath); //记录成功的文件
                                }
                                break;                          //发送下一个文件
                            }
                        }
                        fs?.Close();
                    }
                    if (!cancellationToken.IsCancellationRequested)
                    {
                        result.IsSuccessful = true;
                        result.Message      = $"完成文件上传。共计【{lstSuccFiles.Count}/{filesPath.Count}】,耗时:{DateTime.Now - startTime}";

                        await stream.RequestStream.WriteAsync(new FileReply
                        {
                            Block = -2, //传输结束
                            Mark  = mark
                        });             //发送结束标记
                    }
                }
            }
            catch (Exception ex)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    fs?.Close();//释放文件流
                    result.IsSuccessful = false;
                    result.Message      = $"用户取消了上传文件。已完成【{lstSuccFiles.Count}/{filesPath.Count}】,耗时:{DateTime.Now - startTime}";
                }
                else
                {
                    result.Message = $"文件上传发生异常({ex.GetType()}):{ex.Message}";
                }
            }
            finally
            {
                fs?.Dispose();
            }
            Console.WriteLine(result.Message);
            result.Tag = lstSuccFiles;
            //关闭通信、并返回结果
            return(await channel?.ShutdownAsync().ContinueWith(t => result));
        }
        /// <summary>
        /// 文件下载
        /// </summary>
        /// <param name="request">下载请求</param>
        /// <param name="responseStream">文件写入流</param>
        /// <param name="context">站点上下文</param>
        /// <returns></returns>
        public override async Task DownloadFile(FileRequest request, IServerStreamWriter <FileReply> responseStream, ServerCallContext context)
        {
            List <string> lstSuccFiles = new List <string>(); //传输成功的文件
            int           chunkSize    = 1024 * 1024 * 10;    //每次读取的数据
            var           buffer       = new byte[chunkSize]; //数据缓冲区
            FileStream    fs           = null;                //文件流

            try
            {
                for (int i = 0; i < request.FileNames.Count; i++)
                {
                    string    fileName = request.FileNames[i];
                    string    filePath = $"{AppContext.BaseDirectory}\\{Config.Options.JobDirectory}\\{fileName}".Replace('\\', Path.DirectorySeparatorChar);
                    FileReply reply    = new FileReply
                    {
                        FileName = fileName,
                        Mark     = request.Mark
                    };
                    Console.WriteLine($"{request.Mark},下载文件:{filePath}");
                    if (File.Exists(filePath))
                    {
                        fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, chunkSize, useAsync: true);

                        int readTimes = 0;//读取次数
                        while (true)
                        {
                            int readSise = fs.Read(buffer, 0, buffer.Length);
                            if (readSise > 0)
                            {
                                reply.Block   = ++readTimes;
                                reply.Content = Google.Protobuf.ByteString.CopyFrom(buffer, 0, readSise);
                                await responseStream.WriteAsync(reply);
                            }
                            else
                            {
                                reply.Block   = 0;//没有数据了,读取完了
                                reply.Content = Google.Protobuf.ByteString.Empty;
                                await responseStream.WriteAsync(reply);

                                lstSuccFiles.Add(fileName);
                                Console.WriteLine($"{request.Mark},完成发送文件:{filePath}");
                                break;
                            }
                        }
                        fs?.Close();
                    }
                    else
                    {
                        Console.WriteLine($"文件【{filePath}】不存在。");
                        reply.Block = -1;//-1的标记为文件不存在
                        await responseStream.WriteAsync(reply);
                    }
                }
                //告诉客户端,文件传输完成
                await responseStream.WriteAsync(new FileReply
                {
                    FileName = string.Empty,
                    Block    = -2,
                    Content  = Google.Protobuf.ByteString.Empty,
                    Mark     = request.Mark
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{request.Mark},发生异常({ex.GetType()}):{ex.Message}");
            }
            finally
            {
                fs?.Dispose();
            }
            Console.WriteLine($"{request.Mark},文件传输完成。共计【{lstSuccFiles.Count / request.FileNames.Count}】");
        }