Сначала я хотел бы описать нашу архитектуру, она состоит из:
- Надстройка Outlook Web (размещается на IIS локально)
- веб-API ASP.NET (размещенный локально)
- REST API Microsoft Graph в облаке
- SOAP WebService (не под моим контролем, локально).
Процесс можно описать следующими шагами:
- Пользователь нажимает кнопку в надстройке Outlook Web
- Запрос Ajax выполняется из веб-надстройки к веб-API с идентификатором сообщения в качестве параметра.
- Веб-API запрашивает сообщение от Graph через
GraphServiceClient
- Веб-API упаковывает вложения из сообщения в запрос SOAP и отправляет его в службу SOAP.
Вложения в Microsoft Graph возвращаются в виде байтового массива и сохраняются в памяти. Таким образом, мы можем столкнуться с проблемами памяти и производительности.
У меня вопрос: можно ли передавать вложения из Microsoft Graph непосредственно в службу SOAP?
Получение вложений из MS Graph Rest API
var mail = graphClient
.Users["mailbox"]
.Messages["id"]
.Request()
.Expand("attachments");
foreach (var attachment in message.Attachments)
{
if (attachment.GetType() == typeof(FileAttachment))
{
var fileAttachment = (FileAttachment) attachment;
// ==> fileAttachment.ContentBytes already contains the bytes of the attachment
}
}
Следует ли получать байты вложения вторым запросом? Как это можно стечь?
Определение прикрепляемой части в wsdl мыльной службы
<xsd:complexType name="DocumentData">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="extension" type="xsd:string"/>
<xsd:element name="content" type="xsd:base64Binary"/>
</xsd:sequence>
</xsd:complexType>
... создается в ссылке на службу как
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3062.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://is.uniqa.at/UniqaDocumentWF.WS:startDoWFProcess")]
public partial class DocumentData : object, System.ComponentModel.INotifyPropertyChanged
{
private string nameField;
private string extensionField;
private byte[] contentField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
this.RaisePropertyChanged("name");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 1)]
public string extension
{
get
{
return this.extensionField;
}
set
{
this.extensionField = value;
this.RaisePropertyChanged("extension");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "base64Binary", Order = 2)]
public byte[] content
{
get
{
return this.contentField;
}
set
{
this.contentField = value;
this.RaisePropertyChanged("content");
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null))
{
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
... и может быть создан так:
DoWF.DocumentData data = new DocumentData();
data.name = name;
data.extension = extension;
// At the moment content is set to
// "fileAttachment.ContentBytes" before
// the request is send to the soap service
data.content = content;
Как и где я могу передать байты вложений из Rest API через «мой» веб-API, а затем в службу SOAP?
Также был бы признателен за совершенно другой подход к решению этой проблемы.