从.Net Core api返回html文件

7
我正在尝试使用这个这个来获得一个html文件作为输出,但是遇到了错误500
我的应用程序的目标基于api请求,服务器将生成所请求的输出作为html文件,并将其发送给用户请求。
使用的代码如下:
using Microsoft.AspNetCore.Mvc;  // for Controller, [Route], [HttpPost], [FromBody], JsonResult and Json
using System.IO;   // for MemoryStream
using System.Net.Http; // for HttpResponseMessage
using System.Net;  // for HttpStatusCode
using System.Net.Http.Headers;  // for MediaTypeHeaderValue

namespace server{
    [Route("api/[controller]")]
    public class FileController : Controller{
    [HttpGet]
    public HttpResponseMessage Get()
    {
        string r = @" 
            Hello There
        ";
        var stream = new MemoryStream();
        StreamWriter writer = new StreamWriter(stream);
        writer.Write(r);
        writer.Flush();
        stream.Position = 0;

       // processing the stream.
       byte[] Content = convert.StreamToByteArray(stream);
       var result = new HttpResponseMessage(HttpStatusCode.OK);


        result.Content.Headers.ContentDisposition =
            new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
        {
            FileName = "welcome.html"
        };
        result.Content.Headers.ContentType =
            new MediaTypeHeaderValue("application/octet-stream");

        return result;
    }
  }
}

并且:

using System.IO;  // for MemoryStream

namespace server{
    class convert{
            public static byte[] StreamToByteArray(Stream inputStream)
            {
                byte[] bytes = new byte[16384];
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    int count;
                    while ((count = inputStream.Read(bytes, 0, bytes.Length)) > 0)
                    {
                        memoryStream.Write(bytes, 0, count);
                    }
                    return memoryStream.ToArray();
                }
            }
    }
}

我需要返回的结果是一个 .html 文件,这样我就可以使用 JavaScript 打开一个新的浏览器窗口,例如 var a = window.open(returnedFile, "name");enter image description here

你想将页面作为附件发送吗?如果不是,那么这个答案应该能帮到你:https://dev59.com/FFoT5IYBdhLWcg3w2SUS#38106167 - Marcus Höglund
@MarcusH 我明天会测试一下,但是看起来这将直接显示在浏览器中,我需要用户接收一个 file,所以使用 JavaScript 我可以在另一个窗口中打开它,而不是在已打开的窗口中,例如 var a = window.open(url, "name"); - Hasan A Yousef
流式传输是必要的吗? - J. Doe
@J.Doe 不太确定,我只是在另一个与我的情况相似的解决方案中找到了这个。 - Hasan A Yousef
3个回答

22

对于.NET Core 2 API,您可以使用以下内容

return Content(html, "text/html", Encoding.UTF8);

13

感谢@Marcus-h的反馈和答案,我通过使用[Produces("text/html")]并将返回值设为string来解决了问题,完整代码如下:

namespace server{
    [Route("api/[controller]")]
    public class FileController : Controller{
        [HttpGet]
        [Produces("text/html")]
        public string Get()
        {
            string responseString = @" 
            <title>My report</title>
            <style type='text/css'>
            button{
                color: green;
            }
            </style>
            <h1> Header </h1>
            <p>Hello There <button>click me</button></p>
            <p style='color:blue;'>I am blue</p>
            ";
            return responseString;
        }
    }
}

为了在浏览器窗口中打开它,我使用了:
var report = window.open('', 'myReport', 'location=no,toolbar=0');
// or var report = window.open(''); // if I need the user to be able to use the browser actions, like history
report.document.title = 'My report';  // if title not added in the server code
fetch('http://localhost:60000/api/File', {
       method: 'get'
      })
      .then(function(response) {
            return response.text();
      }).then(function(text) { 
            report.document.body.innerHTML = text;
      });

不错的解决方案!对于“Produces”属性我还不太了解,会去查一下。 - Marcus Höglund
它在 .Net Core 1.0 上运行正常,但在 2.0 上不起作用。你需要手动添加一个输出格式化器来处理 "text/html",请参考:https://github.com/aspnet/Mvc/issues/6657 - Akli

1
为了通过API返回HTML页面,您可以使用HttpResponseMessage并将内容类型设置为“text/html”。 问题是,.net core默认不支持HttpResponseMessage响应。
步骤1
为了从Web API方法启用响应类型,请按照svick的答案中的步骤进行操作。
步骤2
将以下方法应用于控制器。
[HttpGet]
public HttpResponseMessage Get()
{
    string responseString = @" 
        Hello There
    ";
    var response = new HttpResponseMessage();
    response.Content =  new StringContent(responseString);
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
    return response;
}

步骤三

window.open方法中直接调用API,默认情况下会在新窗口(_blank)中打开。

window.open('http://localhost:2222/api/file')

1
响应字符串未出现,而是得到了以下输出:{"version":{"major":1,"minor":1,"build":-1,"revision":-1,"majorRevision":-1,"minorRevision":-1},"content":{"headers":[{"key":"Content-Type","value":["text/html"]}]},"statusCode":200,"reasonPhrase":"OK","headers":[],"requestMessage":null,"isSuccessStatusCode":true} - Hasan A Yousef
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Marcus Höglund
我和你一样,但是得到了我告诉你的结果。 - Hasan A Yousef
@HasanAYousef 更新了我的答案。 - Marcus Höglund
我在project.json中添加了"Microsoft.AspNetCore.Mvc.WebApiCompatShim":"1.1.0",但是出现了以下错误:Package Microsoft.AspNet.WebApi.Client 5.2.2 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1)。我尝试使用其他所有的version号码,但仍然出现相同的错误。 - Hasan A Yousef

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接