System.Net.ConnectStream 转换为 MemoryStream 内存流

项目经理来了一份奇特要求:

在asp.net 2.0 webfrom 的老项目页面上去调用 .net 4.0的webapi接口去下载Excel 哈哈 脑洞大开

非常迅速的创建了一个接口 返回Excel转换的数据流代码如下:

[HttpPost]
        public HttpResponseMessage ExportQuoteReport(ExportQuoteCountModel searchModel)
        {
            try
            {
                List<string> listtitle = new List<string>() { "群(", "本部", "事业部", "实施", "资源", "名称", "项目编号",
                    "项目名称", "客户", "状态","TS天数","正常报天数","0天数","无天数", "负责人编号", "负责人" };
                var list = ReportService.GetQuoteReportForExcel(searchModel);
                IWorkbook book = new XSSFWorkbook();
                ISheet sheet = book.CreateSheet("Sheet1");
                IRow rowTitle = sheet.CreateRow(0);
                ICellStyle style = book.CreateCellStyle();
                for (int i = 0; i < listtitle.Count; i++)
                {
                    rowTitle.CreateCell(i).SetCellValue(listtitle[i]);
                }
                for (int i = 0; i < list.Count; i++)
                {
                    var m = list[i];
                    IRow row = sheet.CreateRow(i + 1);
                    row.CreateCell(0).SetCellValue(m.BG);
                    row.CreateCell(1).SetCellValue(m.BD);
                    row.CreateCell(2).SetCellValue(m.BU);
                    row.CreateCell(3).SetCellValue(m.CC);
                    row.CreateCell(4).SetCellValue(m.ResNo);
                    row.CreateCell(5).SetCellValue(m.ResName);
                    row.CreateCell(6).SetCellValue(m.PrjCode);
                    row.CreateCell(7).SetCellValue(m.PrjName);
                    row.CreateCell(8).SetCellValue(m.ClientGroupName);
                    row.CreateCell(9).SetCellValue(m.ContractStatus);
                    row.CreateCell(10).SetCellValue(m.TSFillDay);
                    row.CreateCell(11).SetCellValue(m.NormalQuoteDay);
                    row.CreateCell(12).SetCellValue(m.ZeroQuoteDay);
                    row.CreateCell(13).SetCellValue(m.NoQuoteDay);
                    row.CreateCell(14).SetCellValue(m.PrjResEmpNo);
                    row.CreateCell(15).SetCellValue(m.PrjResEmpName);
                }
                NpoiMemoryStream ms = new NpoiMemoryStream();
                ms.AllowClose = false;
                book.Write(ms);
                ms.Flush();
                ms.Seek(0, SeekOrigin.Begin);
                ms.AllowClose = true;

                //测试用保存到本地
                //byte[] bytes = ms.GetBuffer();
                //var testPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log//");
                //FileStream outputFile = new FileStream(testPath + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx", FileMode.OpenOrCreate);
                //outputFile.Write(bytes, 0, bytes.Length);
                //outputFile.Flush();
                //outputFile.Close();
                //outputFile.Dispose();

                try
                {
                    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                    result.Content = new StreamContent(ms);
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                    result.Content.Headers.ContentDisposition.FileName = $"{System.DateTime.Now.ToString("yyyyMMddHHmmss")}.xls";
                    return result;
                }
                catch
                {
                    return new HttpResponseMessage(HttpStatusCode.NoContent);

                }
            }
            catch (Exception ex)
            {
                LogService.Write("ExportQuoteReport Exception:" + ex.ToString());
                return null;
            }
        }
导出excel webapi

在.net 2.0项目中去请求webapi接口 序列化实体时 意外遇到了 k_BackingField 问题;

参考了博友   https://www.cnblogs.com/jeffwongishandsome/archive/2012/05/31/2529196.html 的此篇文章后暴力解决;

 [DataContract]
    public class ExportQuoteCountModel
    {
        [DataMember]
        public long EmpID { get; set; }
        [DataMember]
        public DateTime StartDate { get; set; }
        [DataMember]
        public DateTime EndDate { get; set; }
        [DataMember]
        public string PrjInput { get; set; }
        [DataMember]
        public string ResInput { get; set; }
        public string Changer { get; set; }
    }
.net 2.0 序列化实体
 public static string WriteFromObject<T>(T obj) where T : class
        {
            DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(T));
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                dcjs.WriteObject(ms, obj);
                return Encoding.Default.GetString(ms.ToArray());
            }
        }



 public static T GetObjectByJson(string jsonString)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
            object ob = serializer.ReadObject(stream);
            T ls = (T)ob;
            return ls;
        }
.net 2.0 序列化 和反序列化

但是在转换数据流的时候又出现了这个错误:

无法将类型为“System.Net.ConnectStream”的对象强制转换为类型“System.IO.FileStream

在我坚持不懈的百度bing下找到了答案:

Stream sourceStream = ... // the ConnectStream
byte[] array;
using (var ms = new MemoryStream())
{
    sourceStream.CopyTo(ms);
    array = ms.ToArray();
}
可惜4.0才有 Stream.CopyTo

最终在我的bing下还是找到了终极方案 哈哈:

public static MemoryStream GetStreamByAPI(string uri, string parameters)
        {
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(parameters);//这里需要指定提交的编码
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
                webRequest.Method = "POST";
                webRequest.ContentType = "application/json";
                webRequest.Accept = "application/json";

                webRequest.ContentLength = bytes.Length;
                Stream dataStream = webRequest.GetRequestStream();
                dataStream.Write(bytes, 0, bytes.Length);
                dataStream.Close();

                HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
                MemoryStream ms = null;
                using (var stream = webResponse.GetResponseStream())
                {
                    Byte[] buffer = new Byte[webResponse.ContentLength];
                    int offset = 0, actuallyRead = 0;
                    do
                    {
                        actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);
                        offset += actuallyRead;
                    }
                    while (actuallyRead > 0);
                    ms = new MemoryStream(buffer);
                }
                webResponse.Close();
                return ms;
            }
            catch (Exception ex)
            {
                return null;
            }

        }
http请求返回MrmoryStream

 在webform 后台需要加上响应类型为文件类型

MemoryStream res = br.GetFileStream(param,url);
            if (res != null)
                exportBinaryToExcel(res.ToArray(), "test.xlsx");



private void exportBinaryToExcel(byte[] bytes, string filename)
        {
            Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
            Response.AddHeader("Content-Length", bytes.Length.ToString());
            Response.ContentType = "application/octet-stream";
            Response.BinaryWrite(bytes);
            Response.Flush();
        }
webform 后台调用

一次奇特的搜索经历记录下来

原文地址:https://www.cnblogs.com/yanghucheng/p/13503239.html