ServiceStack 的 HttpResult class 未正确格式化 CSV 文件

ServiceStack's HttpResult class does not properly format CSV files

我正在尝试使用 ServiceStack 中的服务端点输出 CSV 文件,使用 HttpResult class。

CSV 字符串本身是通过 StringWriter 和 CsvHelper 构建的。

如果内容类型设置为 "text/plain",当点击端点 URL 时,文本会正常显示在浏览器屏幕上。但是,如果设置为"text/csv",生成的是CSV文件,但里面的信息不正确。

例如:

预期输出:

Header 1, Header 2, Header 3

实际输出:

H,e,a,d,e,r, ,1,,, ,H,e,a,d,e,r, ,2,,, ,H,e,a,d,e,r, 3,"

我可能遗漏了什么吗?

另外,附带说明一下,如何为文件本身设置文件名?看来我必须使用 HttpHeaders.ContentDisposition,但是当我尝试设置它时,出现了一个错误,即具有多个 header 元素。

编辑:抱歉忘记包含代码片段。

string response = string.Empty;

using (var writer = new StringWriter())
{
    using (var csv = new CsvWriter(writer))
    {
        csv.WriteHeader<TestClass>();
        foreach (var element in elements)
        {
            csv.WriteField(elements.header1);
            csv.WriteField(elements.header2);
            csv.WriteField(elements.header3);
            csv.NextRecord();
        }
    }

    //apparently double quotes can cause the rendered CSV to go wrong in some parts, so I added this as part of trying
    response = writer.ToString().Replace("\"", "");
}

return new HttpResult(response)
{
    StatusCode = HttpStatusCode.OK,
    ContentType = "test/csv"
};

以及关于 TestClass 的信息:

public class TestClass
{
    public string Header1 { get; set; }
    public string Header2 { get; set; }
    public string Header3 { get; set; }
}

根据您的描述,您的 HttpResult 文件响应可能由内置 CSV Format.

序列化

如果您不使用它,可以通过以下方式将其删除:

Plugins.RemoveAll(x => x is CsvFormat);

否则,如果您正在使用它,您可以通过在您的服务实现中写入 CSV 文件来规避它的序列化,例如:

public class MyCsv : IReturn<string> {}

public async Task Any(MyCsv request)
{
    var file = base.VirtualFileSources.GetFile("path/to/my.csv");
    if (file == null)
        throw HttpError.NotFound("no csv here");

    Response.ContentType = MimeTypes.Csv;
    Response.AddHeader(HttpHeaders.ContentDisposition, 
        $"attachment; filename=\"{file.Name}\";");
    using (var stream = file.OpenRead())
    {
        await stream.CopyToAsync(Response.OutputStream);
        await Response.OutputStream.FlushAsync();
        Response.EndRequest(skipHeaders:true);
    }
}        

编辑,因为您返回的是原始 CSV string,您可以将其写入响应:

Response.ContentType = MimeTypes.Csv;
await Response.WriteAsync(response);
Response.EndRequest(skipHeaders:true);