C# 如何使用MemoryStream将Xml附加到.net邮件附件?

C# 如何使用MemoryStream将Xml附加到.net邮件附件?,c#,xml,asp.net-mvc-3,asp.net-mail,C#,Xml,Asp.net Mvc 3,Asp.net Mail,我在mvc中有一个填充xml的cshtml视图,例如: @model myproject.net.Models.mymodel @{ Layout = null; Response.ContentType = "application/vnd.ms-excel"; Response.AddHeader("Content-Disposition", "attachment; " + "filename=" + Model.myusername.ToStri

我在mvc中有一个填充xml的cshtml视图,例如:

@model myproject.net.Models.mymodel
@{
    Layout = null;
    Response.ContentType = "application/vnd.ms-excel";
    Response.AddHeader("Content-Disposition", "attachment; " + "filename=" + 
        Model.myusername.ToString()  + "(" + 
        Model.mydate.Date.ToShortDateString() + ").xls");
}

<?xml version="1.0" encoding="utf-8"?>
<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
    <Styles>
        <Style ss:ID="s25">
            <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
            <Borders>
                <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
            </Borders>
            <Interior ss:Color="#FFA500" ss:Pattern="Solid"/>
        </Style>
    </Styles>
    <ss:Worksheet ss:Name="Sheet1">
        <ss:Table>
        @if (Model.someNumerableContent.Count > 0)
        {
            <!-- MyContent -->
            <ss:Row>
                <ss:Cell><ss:Data ss:Type="String">Content Header</ss:Data></ss:Cell>
            </ss:Row>
            <ss:Row>
                <ss:Cell><ss:Data ss:Type="String">SubHeader 1</ss:Data></ss:Cell>
                <ss:Cell><ss:Data ss:Type="String">SubHeader 2</ss:Data></ss:Cell>
                <ss:Cell><ss:Data ss:Type="String">SubHeader 3</ss:Data></ss:Cell>
                <ss:Cell><ss:Data ss:Type="String">SubHeader 4</ss:Data></ss:Cell>
                <ss:Cell><ss:Data ss:Type="String">SubHeader 5</ss:Data></ss:Cell>
            </ss:Row>
            foreach (var subContent in Model.someNumerableContent)
            {
            <ss:Row>
                <ss:Cell><ss:Data ss:Type="String">@subContent.mydate.Date.ToShortDateString()</ss:Data></ss:Cell>
                <ss:Cell><ss:Data ss:Type="String">@subContent.number</ss:Data></ss:Cell>
                <ss:Cell><ss:Data ss:Type="String">@subContent.name</ss:Data></ss:Cell>
                <ss:Cell><ss:Data ss:Type="String">@subContent.surname</ss:Data></ss:Cell>
                <ss:Cell><ss:Data ss:Type="String">@subContent.issue</ss:Data></ss:Cell>
            </ss:Row>
            }
            <ss:Row> </ss:Row>
        }
        </ss:Table>
    </ss:Worksheet>
</ss:Workbook>

那么我如何才能做到这一点呢?

这取决于excel的版本或您需要的功能。也许就够了。它有点过时,但适用于简单的excel工作簿

如果需要自己滚动模板,请签出以将模型渲染为字符串。将字符串传递到
并附加到电子邮件

更新

要首先使用razor模板,您需要一个视图

@* Generator: Template *@
@inherits The.NameSpace.RazorTemplateBase<dynamic>

@functions  {
    public object Model { get; set; }
}

<your typical markup goes here...>

我无法成功实现razor view,但在它上工作了30个小时之后。我找到了另一种方法

首先,我创建了一个XmlString,如下所示:

public String XmlToImplement(int id)
{
    // Add values from db to model
    MyModel model = new MyModel();
    model.contents = db.contents.Where(c => c.MyData.id == id).ToList();
    // XmlString
    String XmlString = @"<?xml version='1.0' encoding='utf-8'?>
    <ss:Workbook xmlns='urn:schemas-microsoft-com:office:spreadsheet'
                xmlns:o='urn:schemas-microsoft-com:office:office'
                xmlns:x='urn:schemas-microsoft-com:office:excel'
                xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet'
                xmlns:html='http://www.w3.org/TR/REC-html40'>
        <Styles>
            <Style ss:ID='s25'>
                <Alignment ss:Horizontal='Center' ss:Vertical='Bottom'/>
                <Borders>
                    <Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
                </Borders>
                <Interior ss:Color='#FFA500' ss:Pattern='Solid'/>
            </Style>
        </Styles>
        <ss:Worksheet ss:Name='Sheet1'>
            <ss:Table>";
            if (model.contents.Count > 0)
            {
                XmlString = XmlString + @"<!-- MyModelData -->
                <ss:Row>
                    <ss:Cell><ss:Data ss:Type='String'> MyModelData </ss:Data></ss:Cell>
                </ss:Row>
                <ss:Row>
                    <ss:Cell><ss:Data ss:Type='String'>Date</ss:Data></ss:Cell>
                    <ss:Cell><ss:Data ss:Type='String'>Number</ss:Data></ss:Cell>
                    <ss:Cell><ss:Data ss:Type='String'>Name/Surname</ss:Data></ss:Cell>
                </ss:Row>"; 
                foreach (var content in model.contents)
                {
                    XmlString = XmlString + @"<ss:Row>";
                    XmlString = XmlString + @"<ss:Cell><ss:Data ss:Type='String'>" + content.thedate.Date.ToShortDateString() + "</ss:Data></ss:Cell>";
                    XmlString = XmlString + @"<ss:Cell><ss:Data ss:Type='String'>" + content.number + "</ss:Data></ss:Cell>";
                    XmlString = XmlString + @"<ss:Cell><ss:Data ss:Type='String'>" + content.namesurname+ "</ss:Data></ss:Cell>";
                    XmlString = XmlString + @"</ss:Row>";
                }
                // An empty row for next value set
                XmlString = XmlString + "<ss:Row> </ss:Row>"; 
            }
            XmlString = XmlString + @"</ss:Table>
        </ss:Worksheet>
    </ss:Workbook>";
    return XmlString;
}
然后将
ContentType
定义为
Excel

// Content Type
ContentType contentType = new ContentType("application/vnd.ms-excel");
contentType.Name = UserName + "(" + FileDate + ").xls";
最后我把它附加到了.net邮件上

// Attach
mail.Attachment = new Attachment(memoryStream, contentType);
mail.Attachment.NameEncoding = UTF8Encoding.UTF8;
mail.Attachment.TransferEncoding = TransferEncoding.Base64;
mail.Attachment.ContentDisposition.DispositionType = DispositionTypeNames.Attachment;

而且效果很好。我可能无法将xml视图转换为邮件附件,但我可以轻松地将xml字符串转换为邮件附件,我希望这对解决此问题的其他人有所帮助。

我们也做过类似的工作,但我们总是将其保存到本地临时文件中,不确定是否可以在内存中完成。@BradPatton这才是实际情况。。我的意思是,你可以把它和内存连接起来,这样会使它更安全,更不需要硬盘。到底是什么问题?将模型呈现为xml或附加文件(内存流)电子邮件?@JasonMeckley我不知道如何检索视图数据并使用memoryStream将其附加,所以他们都是我的问题,我有点卡住了,但所有这些创建excel文件并通过邮件发送而不将其保存到任何地方的主要思想。@BerkerYüceer很高兴你能让它工作。我将在将来记住它。我如何将我的xml实现到它?我的意思是,如何将其作为viewresult | |字符串和atach返回到流中?你能再解释一下吗?也许有一些编码示例?我在“Razor Generator Templates”链接上尝试了一些示例,但没有成功。到目前为止,我非常感谢它的帮助,但我确实无法将myView实现为
string excelXml=new myView{Model=mymodel.complaints}.TransformText()当然不是它的使用方式。1。你的视野开阔吗?2.视图是否继承了
RazorTemplateBase
?3.视图是否将
@*生成器:Template*@
声明作为第一行?4.视图是否使用
RazorGenerator
作为自定义工具?如果是这样,这将自动创建一个类(类似webforms code behind),然后您可以将视图实例化为一个类并调用
TransformText()
。视图似乎不存在!出于这个原因,我没有办法这样称呼它
stringexcelxml=new
viewname
{Model=theData}.TransformText()查看代码时,
RazorTemplateBase
的命名空间与视图中的命名空间不同。如果设置了自定义工具,则应该在视图模板下嵌套一个类似于
MyView.cshtml.cs
的文件。也。。。您已经安装了nuget软件包,对吗?
public String XmlToImplement(int id)
{
    // Add values from db to model
    MyModel model = new MyModel();
    model.contents = db.contents.Where(c => c.MyData.id == id).ToList();
    // XmlString
    String XmlString = @"<?xml version='1.0' encoding='utf-8'?>
    <ss:Workbook xmlns='urn:schemas-microsoft-com:office:spreadsheet'
                xmlns:o='urn:schemas-microsoft-com:office:office'
                xmlns:x='urn:schemas-microsoft-com:office:excel'
                xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet'
                xmlns:html='http://www.w3.org/TR/REC-html40'>
        <Styles>
            <Style ss:ID='s25'>
                <Alignment ss:Horizontal='Center' ss:Vertical='Bottom'/>
                <Borders>
                    <Border ss:Position='Bottom' ss:LineStyle='Continuous' ss:Weight='1'/>
                </Borders>
                <Interior ss:Color='#FFA500' ss:Pattern='Solid'/>
            </Style>
        </Styles>
        <ss:Worksheet ss:Name='Sheet1'>
            <ss:Table>";
            if (model.contents.Count > 0)
            {
                XmlString = XmlString + @"<!-- MyModelData -->
                <ss:Row>
                    <ss:Cell><ss:Data ss:Type='String'> MyModelData </ss:Data></ss:Cell>
                </ss:Row>
                <ss:Row>
                    <ss:Cell><ss:Data ss:Type='String'>Date</ss:Data></ss:Cell>
                    <ss:Cell><ss:Data ss:Type='String'>Number</ss:Data></ss:Cell>
                    <ss:Cell><ss:Data ss:Type='String'>Name/Surname</ss:Data></ss:Cell>
                </ss:Row>"; 
                foreach (var content in model.contents)
                {
                    XmlString = XmlString + @"<ss:Row>";
                    XmlString = XmlString + @"<ss:Cell><ss:Data ss:Type='String'>" + content.thedate.Date.ToShortDateString() + "</ss:Data></ss:Cell>";
                    XmlString = XmlString + @"<ss:Cell><ss:Data ss:Type='String'>" + content.number + "</ss:Data></ss:Cell>";
                    XmlString = XmlString + @"<ss:Cell><ss:Data ss:Type='String'>" + content.namesurname+ "</ss:Data></ss:Cell>";
                    XmlString = XmlString + @"</ss:Row>";
                }
                // An empty row for next value set
                XmlString = XmlString + "<ss:Row> </ss:Row>"; 
            }
            XmlString = XmlString + @"</ss:Table>
        </ss:Worksheet>
    </ss:Workbook>";
    return XmlString;
}
// Create attachment
// Add XML to MemoryStream                                          /* MyXmlString */
MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(XmlToImplement(id)));
// Content Type
ContentType contentType = new ContentType("application/vnd.ms-excel");
contentType.Name = UserName + "(" + FileDate + ").xls";
// Attach
mail.Attachment = new Attachment(memoryStream, contentType);
mail.Attachment.NameEncoding = UTF8Encoding.UTF8;
mail.Attachment.TransferEncoding = TransferEncoding.Base64;
mail.Attachment.ContentDisposition.DispositionType = DispositionTypeNames.Attachment;