There is no mechanism for retrieving the path for the file on disk, or the local path from where the user uploaded it (this is considered a security risk: how-to-get-full-path-of-selected-file-on-change-of-input-type-file-using-jav ).
The ContentUrl property is http://localhost:56057/v3/attachments/guid/views/original because the bot is connected to the emulator. This path is Bot Framework Channel specific. Your local emulator's server is hosted on port 56057. As stated by Simonare in the comments: you need to download the file, and save it somewhere.
This example demonstrates how to retrieve the bytes of the file: core-ReceiveAttachment
Crudely modified to save multiple files in a local folder: (This is not a good idea in a production scenario, without other safeguards in place. It would be better to upload the bytes to blob storage using Microsoft.WindowsAzure.Storage or something similar.)
if (message.Attachments != null && message.Attachments.Any())
{
using (HttpClient httpClient = new HttpClient())
{
// Skype & MS Teams attachment URLs are secured by a JwtToken, so we need to pass the token from our bot.
if ((message.ChannelId.Equals(ChannelIds.Skype, StringComparison.InvariantCultureIgnoreCase)
|| message.ChannelId.Equals(ChannelIds.Msteams, StringComparison.InvariantCultureIgnoreCase)))
{
var token = await new MicrosoftAppCredentials().GetTokenAsync();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
foreach (Attachment attachment in message.Attachments)
{
using (var responseMessage = await httpClient.GetAsync(attachment.ContentUrl))
{
using (var fileStream = await responseMessage.Content.ReadAsStreamAsync())
{
string path = Path.Combine(System.Web.HttpContext.Current.Request.MapPath("~\\Content\\Files"), attachment.Name);
using (FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write))
{
await fileStream.CopyToAsync(file);
file.Close();
}
}
var contentLenghtBytes = responseMessage.Content.Headers.ContentLength;
await context.PostAsync($"Attachment of {attachment.ContentType} type and size of {contentLenghtBytes} bytes received.");
}
}
}
}
This example for BotBuilder-v4 presents another method: 15.handling-attachments/AttachmentsBot.cs#L204
private static void HandleIncomingAttachment(IMessageActivity activity, IMessageActivity reply)
{
foreach (var file in activity.Attachments)
{
// Determine where the file is hosted.
var remoteFileUrl = file.ContentUrl;
// Save the attachment to the system temp directory.
var localFileName = Path.Combine(Path.GetTempPath(), file.Name);
// Download the actual attachment
using (var webClient = new WebClient())
{
webClient.DownloadFile(remoteFileUrl, localFileName);
}
reply.Text = $"Attachment \"{activity.Attachments[0].Name}\"" +
$" has been received and saved to \"{localFileName}\"";
}
}