Botframework v4:将图像上传到另一个 class 中的机器人
Botframework v4: Uploading image to the bot in another class
我在主机器人 class 的 OnTurnAsync()
中有这段代码,它允许用户上传图像并将其保存在本地,并且工作正常。
但是如果我想在不同的 class 中像 MainDialog class 那样做,我该怎么做呢?
更新:我设法通过下面的代码做到了。但是它接受一切,我如何做一个只接受图像的验证?
更新:回答如下。
public class MainDialog : ComponentDialog
{
private const string InitialId = "mainDialog";
private const string TEXTPROMPT = "textPrompt";
private const string ATTACHPROMPT = "attachPrompt";
public MainDialog(string dialogId)
: base(dialogId)
{
WaterfallStep[] waterfallSteps = new WaterfallStep[]
{
FirstStepAsync,
SecondStepAsync,
};
AddDialog(new WaterfallDialog(InitialId, waterfallSteps));
AddDialog(new AttachmentPrompt(ATTACHPROMPT));
}
private static async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
return await stepContext.PromptAsync(
ATTACHPROMPT,
new PromptOptions
{
Prompt = MessageFactory.Text($"upload photo."),
RetryPrompt = MessageFactory.Text($"upload photo pls."),
});
}
private static async Task<DialogTurnResult> SecondStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
var activity = stepContext.Context.Activity;
if (activity.Attachments != null && activity.Attachments.Any())
{
foreach (var file in stepContext.Context.Activity.Attachments)
{
var remoteFileUrl = file.ContentUrl;
var localFileName = Path.Combine(Path.GetTempPath(), file.Name);
using (var webClient = new WebClient())
{
webClient.DownloadFile(remoteFileUrl, localFileName);
}
await stepContext.Context.SendActivityAsync($"Attachment {stepContext.Context.Activity.Attachments[0].Name} has been received and saved to {localFileName}.");
}
}
return await stepContext.EndDialogAsync();
}
设法用这段代码做到了。
var activity = stepContext.Context.Activity;
if (activity.Attachments != null && activity.Attachments.Any())
{
foreach (var file in stepContext.Context.Activity.Attachments)
{
if (file.ContentType.EndsWith("/jpg") || file.ContentType.EndsWith("/png") || file.ContentType.EndsWith("/bmp") || file.ContentType.EndsWith("/jpe"))
{
var remoteFileUrl = file.ContentUrl;
var localFileName = Path.Combine(Path.GetTempPath(), file.Name);
using (var webClient = new WebClient())
{
webClient.DownloadFile(remoteFileUrl, localFileName);
}
await stepContext.Context.SendActivityAsync($"Attachment {stepContext.Context.Activity.Attachments[0].Name} has been received and saved to {localFileName}.");
return await stepContext.NextAsync();
}
else
{
await stepContext.Context.SendActivityAsync($"Attachment {file.Name} is not an image, it is {file.ContentType}.");
// restart the dialog from top
return await stepContext.ReplaceDialogAsync(InitialId);
}
}
}
正如 Nicolas R 所说,您可以像这样进行一些基本验证:
foreach (var file in activity.Attachments)
{
if (file.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
{
await turnContext.SendActivityAsync($"Attachment {file.Name} is an image of type {file.ContentType}.");
}
else
{
await turnContext.SendActivityAsync($"Attachment {file.Name} is not an image, it is {file.ContentType}.");
}
}
这当然会允许任何内容类型以 "image/" 开头的附件。您可能不想允许以 "image/" 开头的任何内容类型,在这种情况下,您可能希望制作一个可接受类型的列表,例如 "image/png" 和 "image/jpeg"。您也可以考虑检查文件扩展名(看它是“.png”还是“.jpg”等)
我在主机器人 class 的 OnTurnAsync()
中有这段代码,它允许用户上传图像并将其保存在本地,并且工作正常。
但是如果我想在不同的 class 中像 MainDialog class 那样做,我该怎么做呢?
更新:我设法通过下面的代码做到了。但是它接受一切,我如何做一个只接受图像的验证?
更新:回答如下。
public class MainDialog : ComponentDialog
{
private const string InitialId = "mainDialog";
private const string TEXTPROMPT = "textPrompt";
private const string ATTACHPROMPT = "attachPrompt";
public MainDialog(string dialogId)
: base(dialogId)
{
WaterfallStep[] waterfallSteps = new WaterfallStep[]
{
FirstStepAsync,
SecondStepAsync,
};
AddDialog(new WaterfallDialog(InitialId, waterfallSteps));
AddDialog(new AttachmentPrompt(ATTACHPROMPT));
}
private static async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
return await stepContext.PromptAsync(
ATTACHPROMPT,
new PromptOptions
{
Prompt = MessageFactory.Text($"upload photo."),
RetryPrompt = MessageFactory.Text($"upload photo pls."),
});
}
private static async Task<DialogTurnResult> SecondStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
var activity = stepContext.Context.Activity;
if (activity.Attachments != null && activity.Attachments.Any())
{
foreach (var file in stepContext.Context.Activity.Attachments)
{
var remoteFileUrl = file.ContentUrl;
var localFileName = Path.Combine(Path.GetTempPath(), file.Name);
using (var webClient = new WebClient())
{
webClient.DownloadFile(remoteFileUrl, localFileName);
}
await stepContext.Context.SendActivityAsync($"Attachment {stepContext.Context.Activity.Attachments[0].Name} has been received and saved to {localFileName}.");
}
}
return await stepContext.EndDialogAsync();
}
设法用这段代码做到了。
var activity = stepContext.Context.Activity;
if (activity.Attachments != null && activity.Attachments.Any())
{
foreach (var file in stepContext.Context.Activity.Attachments)
{
if (file.ContentType.EndsWith("/jpg") || file.ContentType.EndsWith("/png") || file.ContentType.EndsWith("/bmp") || file.ContentType.EndsWith("/jpe"))
{
var remoteFileUrl = file.ContentUrl;
var localFileName = Path.Combine(Path.GetTempPath(), file.Name);
using (var webClient = new WebClient())
{
webClient.DownloadFile(remoteFileUrl, localFileName);
}
await stepContext.Context.SendActivityAsync($"Attachment {stepContext.Context.Activity.Attachments[0].Name} has been received and saved to {localFileName}.");
return await stepContext.NextAsync();
}
else
{
await stepContext.Context.SendActivityAsync($"Attachment {file.Name} is not an image, it is {file.ContentType}.");
// restart the dialog from top
return await stepContext.ReplaceDialogAsync(InitialId);
}
}
}
正如 Nicolas R 所说,您可以像这样进行一些基本验证:
foreach (var file in activity.Attachments)
{
if (file.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
{
await turnContext.SendActivityAsync($"Attachment {file.Name} is an image of type {file.ContentType}.");
}
else
{
await turnContext.SendActivityAsync($"Attachment {file.Name} is not an image, it is {file.ContentType}.");
}
}
这当然会允许任何内容类型以 "image/" 开头的附件。您可能不想允许以 "image/" 开头的任何内容类型,在这种情况下,您可能希望制作一个可接受类型的列表,例如 "image/png" 和 "image/jpeg"。您也可以考虑检查文件扩展名(看它是“.png”还是“.jpg”等)