1

首先我想描述一下我们的架构,它包括:

  • Outlook Web 插件(托管在本地 IIS 上)
  • 一个 ASP.NET Web API(本地托管)
  • 云中的 Microsoft Graph REST API
  • 一个 SOAP WebService(不在我的控制之下,在本地)。

该流程可以通过以下步骤来描述:

  1. 用户单击 Outlook Web 加载项中的按钮
  2. Ajax 请求是从 Web 插件向 Web API 发出的,其中消息的 ID 作为参数。
  3. Web API 通过以下方式从 Graph 请求消息GraphServiceClient
  4. Web 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; 

如何以及在何处通过“我的”Web API 将来自 Rest API 的附件字节流式传输到 SOAP 服务?

我也将感谢一种完全不同的方法来解决这个问题。

4

1 回答 1

0

鉴于所涉及的层数以及您无法控制工作流任一端的 API,我不确定这种方法是否可行。更重要的是,我怀疑即使你做到这一点,你也会发现它非常脆弱。

我会根据文档中的这篇文章提出一些建议:Get attachments of an Outlook item from the server。此使用示例使用 Exchange Web 服务而不是 Microsoft Graph,但一般流程是相同的:

  1. 用户单击加载项中的按钮
  2. 加载项将userPrincipalName消息传递id给 Web API
  3. Web API 将附件下载到临时存储。
  4. Web API 将附件从临时存储上传到 SOAP 服务。

为了完成这项工作,您的 Web API 将需要使用客户端凭据通过Mail.Read应用程序范围连接到 Microsoft Graph 。这将允许 Web API 连接到任何邮箱并下载附件。

于 2019-10-11T14:54:15.617 回答