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); }
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)); }
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); }
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); }
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); }
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}"); }
/// <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}】"); }