#autodesk-forge #autodesk-designautomation
#autodesk-forge #autodesk-designautomation
Вопрос:
Я нахожусь в процессе изучения платформы Forge. В настоящее время я использую пример (Jigsawify), написанный Кином Уолмсли, потому что он наиболее точно описывает мои цели. Я столкнулся с проблемой загрузки моего файла из учетной записи хранилища Azure в Forge. Ошибка, которую я получаю, заключается в том, что «Значение для одного из HTTP-заголовков не в правильном формате». Мой вопрос заключается в том, как кто-то устраняет неполадки в протоколе HTTP при написании, в данном случае, workitem в коде? Я могу ввести точку останова для просмотра рабочего элемента, но я недостаточно сведущ, чтобы понять, где ошибка в заголовке HTTP, или даже где ее найти. Есть ли какое-то конкретное свойство workitem, на которое я должен обратить внимание? Если бы я мог найти инструкцию HTTP, я мог бы ее протестировать, но я не знаю, где я должен ее найти.
Или я просто полностью сбился с базы?
В любом случае, вот код. Это модифицированная версия того, что написал Кин:
static void SubmitWorkItem(Activity activity)
{
Console.WriteLine("Submitting workitem...");
CloudStorageAccount storageAccount =
CloudStorageAccount.Parse(Microsoft.Azure.CloudConfigurationManager.GetSetting("StorageConnectionString"));
StorageCredentials crd = storageAccount.Credentials;
CloudFileClient fileClient = storageAccount.CreateCloudFileClient();
CloudFileShare ShareRef = fileClient.GetShareReference("000scrub");
CloudFileDirectory rootDir = ShareRef.GetRootDirectoryReference();
CloudFile Fileshare = rootDir.GetFileReference("3359fort.dwg");
// Create a workitem
var wi = new WorkItem()
{
Id = "", // Must be set to empty
Arguments = new Arguments(),
ActivityId = activity.Id
};
if (Fileshare.Exists())
{
wi.Arguments.InputArguments.Add(new Argument()
{
Name = "HostDwg", // Must match the input parameter in activity
Resource = Fileshare.Uri.ToString(),
StorageProvider = StorageProvider.Generic // Generic HTTP download (vs A360)
});
}
wi.Arguments.OutputArguments.Add(new Argument()
{
Name = "Results", // Must match the output parameter in activity
StorageProvider = StorageProvider.Generic, // Generic HTTP upload (vs A360)
HttpVerb = HttpVerbType.POST, // Use HTTP POST when delivering result
Resource = null, // Use storage provided by AutoCAD.IO
ResourceKind = ResourceKind.ZipPackage // Upload as zip to output dir
});
container.AddToWorkItems(wi);
container.SaveChanges();
// Polling loop
do
{
Console.WriteLine("Sleeping for 2 sec...");
System.Threading.Thread.Sleep(2000);
container.LoadProperty(wi, "Status"); // HTTP request is made here
Console.WriteLine("WorkItem status: {0}", wi.Status);
}
while (
wi.Status == ExecutionStatus.Pending ||
wi.Status == ExecutionStatus.InProgress
);
// Re-query the service so that we can look at the details provided
// by the service
container.MergeOption =
Microsoft.OData.Client.MergeOption.OverwriteChanges;
wi = container.WorkItems.ByKey(wi.Id).GetValue();
// Resource property of the output argument "Results" will have
// the output url
var url =
wi.Arguments.OutputArguments.First(
a => a.Name == "Results"
).Resource;
if (url != null)
DownloadToDocs(url, "SGA.zip");
// Download the status report
url = wi.StatusDetails.Report;
if (url != null)
DownloadToDocs(url, "SGA-Report.txt");
}
Приветствуется любая помощь,
Патрон
Ответ №1:
Azure требует, чтобы вы указывали заголовок типа x-ms-blob при загрузке на предварительно указанный URL. Смотрите https://github.com/Autodesk-Forge/design.automation-.net-input.output.sample/blob/master/Program.cs#L167
Комментарии:
1. Значит ли это, что большие двоичные объекты — единственный тип хранилища файлов, который я могу использовать? Я пытался использовать стандартный протокол SMB 3.0 для хранения файлов.
2. Итак, чтобы ответить на мой собственный вопрос, да, я считаю, что вы можете использовать стандартное файловое хранилище SMB 3.0, но по умолчанию оно частное, где большой двоичный объект по умолчанию является общедоступным. Если это неверно, кто-нибудь, пожалуйста, скажите мне. В любом случае, использовать большой двоичный объект проще.
3. Итак, на этот раз я пытаюсь сослаться на файл dwg, находящийся в общей папке на созданном мной веб-сайте. Я могу получить доступ к нему напрямую с помощью Google или Postman, но мой Workitem всегда выдает 404 с сообщением о сбое загрузки в файле результатов. Является ли путь к файлу («InputDwg») во внешнем документе простой строкой URL? Чего мне не хватает?
Ответ №2:
Итак, я смог выяснить, как загрузить мой файл из Azure в Forge, используя предложение Альберта о переходе на службу больших двоичных объектов. Вот код:
static void SubmitWorkItem(Activity activity)
{
Console.WriteLine("Submitting workitem...");
CloudStorageAccount storageAccount =
CloudStorageAccount.Parse(Microsoft.Azure.CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudBlobClient BlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = BlobClient.GetContainerReference("000scrub");
CloudBlockBlob blockBlob = cloudBlobContainer.GetBlockBlobReference("3359fort.dwg");
// Create a workitem
var wi = new WorkItem()
{
Id = "", // Must be set to empty
Arguments = new Arguments(),
ActivityId = activity.Id
};
if (blockBlob.Exists())
{
wi.Arguments.InputArguments.Add(new Argument()
{
Name = "HostDwg", // Must match the input parameter in activity
Resource = blockBlob.Uri.ToString(),
StorageProvider = StorageProvider.Generic, // Generic HTTP download (vs A360)
Headers = new System.Collections.ObjectModel.ObservableCollection<Header>()
{
new Header() { Name = "x-ms-blob-type", Value = "BlockBlob" } // This is required for Azure.
}
});
}
wi.Arguments.OutputArguments.Add(new Argument()
{
Name = "Results", // Must match the output parameter in activity
StorageProvider = StorageProvider.Generic, // Generic HTTP upload (vs A360)
HttpVerb = HttpVerbType.POST, // Use HTTP POST when delivering result
Resource = null, // Use storage provided by AutoCAD.IO
ResourceKind = ResourceKind.ZipPackage, // Upload as zip to output dir
});
container.AddToWorkItems(wi);
container.SaveChanges();
// Polling loop
do
{
Console.WriteLine("Sleeping for 2 sec...");
System.Threading.Thread.Sleep(2000);
container.LoadProperty(wi, "Status"); // HTTP request is made here
Console.WriteLine("WorkItem status: {0}", wi.Status);
}
while (
wi.Status == ExecutionStatus.Pending ||
wi.Status == ExecutionStatus.InProgress
);
// Re-query the service so that we can look at the details provided
// by the service
container.MergeOption =
Microsoft.OData.Client.MergeOption.OverwriteChanges;
wi = container.WorkItems.ByKey(wi.Id).GetValue();
// Resource property of the output argument "Results" will have
// the output url
var url =
wi.Arguments.OutputArguments.First(
a => a.Name == "Results"
).Resource;
if (url != null)
DownloadToDocs(url, "SGA.zip");
// Download the status report
url = wi.StatusDetails.Report;
if (url != null)
DownloadToDocs(url, "SGA-Report.txt");
}
Что не завершено, так это раздел результатов. В ZIP-файле ничего нет, но, эй, маленькие шаги, верно?
Спасибо Альберту. -Патрон