Microsoft Bot Framework部署Azure后遇DirectoryNotFoundException文件访问问题
问题分析
Azure App Service的运行环境和本地开发环境存在差异,导致你遇到DirectoryNotFoundException:
- 本地运行时,
OtherFiles目录在项目根目录下,程序能正常找到;但发布到Azure后,部署路径与本地不同,相对路径@"OtherFiles/Appointment.txt"指向的目录可能不存在。 - Azure App Service的本地文件系统是临时存储,实例重启、缩放或部署新版本时,临时存储中的数据会被清空,不适合持久化业务数据。
解决办法
临时修复:确保目录存在
如果只是临时测试,可以在写入文件前先检查并创建目标目录,修改代码如下:
private async Task<DialogTurnResult> FullName(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var activity = stepContext.Context.Activity.CreateReply(""); activity.SuggestedActions = new SuggestedActions(); var text = stepContext.Context.Activity.Text; if (text != "القائمة الرئيسية") { try { // 用当前程序运行目录拼接文件路径 var filePath = Path.Combine(Environment.CurrentDirectory, "OtherFiles", "Appointment.txt"); var dirPath = Path.GetDirectoryName(filePath); // 检查目录是否存在,不存在则创建 if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } File.WriteAllText(filePath, String.Empty); using (StreamWriter writer = new StreamWriter(filePath, true)) { writer.WriteLine(text); } } catch (Exception e) { await stepContext.Context.SendActivityAsync(e.ToString()); } await stepContext.Context.SendActivityAsync("ادخل الاسم كامل لو سمحت"); } return await stepContext.PromptAsync(Actions.Prompt, new PromptOptions() { Prompt = activity }); }
注意:这种方式仅适合临时验证,数据无法持久化,实例重启后会丢失。
推荐方案:使用Azure持久化存储
对于需要长期保存的聊天数据,应该使用Azure的云存储服务,比如Azure Blob存储,步骤如下:
- 在Azure门户创建一个存储账户。
- 安装NuGet包
Azure.Storage.Blobs。 - 修改代码替换本地文件操作:
// 依赖注入BlobServiceClient(在Program.cs/Startup.cs中配置) private readonly BlobServiceClient _blobServiceClient; // 构造函数注入 public YourDialogClass(BlobServiceClient blobServiceClient) { _blobServiceClient = blobServiceClient; } private async Task<DialogTurnResult> FullName(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var activity = stepContext.Context.Activity.CreateReply(""); activity.SuggestedActions = new SuggestedActions(); var text = stepContext.Context.Activity.Text; if (text != "القائمة الرئيسية") { try { // 获取Blob容器(不存在则创建) var containerClient = _blobServiceClient.GetBlobContainerClient("appointment-data"); await containerClient.CreateIfNotExistsAsync(); // 先清空Blob内容 var blobClient = containerClient.GetBlobClient("Appointment.txt"); await blobClient.UploadAsync(new MemoryStream(Encoding.UTF8.GetBytes(string.Empty)), overwrite: true); // 追加文本内容 var appendBlobClient = containerClient.GetAppendBlobClient("Appointment.txt"); await appendBlobClient.AppendTextAsync(text + Environment.NewLine); } catch (Exception e) { await stepContext.Context.SendActivityAsync(e.ToString()); } await stepContext.Context.SendActivityAsync("ادخل الاسم كامل لو سمحت"); } return await stepContext.PromptAsync(Actions.Prompt, new PromptOptions() { Prompt = activity }); }
- 在Azure App Service的「配置」→「应用程序设置」中添加存储账户的连接字符串,避免硬编码。
部署配置检查
如果坚持使用本地文件(不推荐),需要确保OtherFiles目录被包含到部署包:
- 在Visual Studio中右键
OtherFiles目录→「属性」,将「复制到输出目录」设置为「始终复制」或「如果较新则复制」。
内容的提问来源于stack exchange,提问作者hamzah jazi
相关产品推荐
相关产品推荐

