首先,我想描述一下我们的架构,它包括:
- Outlook Web Addin(托管在本地 IIS 上(
- ASP.NET Web API(托管在本地(
- 云中的Microsoft图形 REST API
- 一个SOAP WebService(不受我的控制,在本地(。
可以通过以下步骤来描述流程:
- 用户单击 Outlook Web 加载项中的按钮
- Ajax 请求从 Web 外接程序向 Web API 发出,并将消息的 ID 作为参数。
- Web API 通过
GraphServiceClient
从图形请求消息 - Web API 将消息中的附件打包到 SOAP 请求中,并将其发送到 SOAP 服务。
图形Microsoft附件以字节数组的形式返回并存储在内存中。因此,我们可能会遇到内存和性能问题。
我的问题是,是否可以将附件从 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
}
}
是否应该通过第二个请求获取附件的字节数? 怎么能流下来?
SOAP 服务 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;
如何以及在何处通过"我的"Web API 将附件字节从 Rest API 流式传输到 SOAP 服务?
我也希望能用完全不同的方法来解决这个问题。
考虑到所涉及的层数以及您无法控制工作流两端的 API,我不确定这种方法是否有效。更重要的是,我怀疑即使你能做到这一点,你也会发现它非常脆弱。
我会从文档中建议与本文类似的内容:从服务器获取 Outlook 项目的附件。此使用示例使用 Exchange Web 服务而不是Microsoft图形,但一般流程是相同的:
- 用户单击加载项中的按钮
- 外接程序将
userPrincipalName
和消息id
传递给 Web API - Web API 将附件下载到临时存储。
- Web API 将附件从临时存储上传到 SOAP 服务。
若要实现此目的,Web API 需要使用客户端凭据通过Mail.Read
应用程序范围连接到Microsoft Graph。这将允许 Web API 连接到任何邮箱并下载附件。