C# 将CSV文件从Angular7传递到MVC.Net Core

C# 将CSV文件从Angular7传递到MVC.Net Core,c#,csv,asp.net-core,file-upload,angular7,C#,Csv,Asp.net Core,File Upload,Angular7,我正在尝试将CSV文件传递到后端,以利用库解析CSV数据 我有一个Angular7前端,带有一个C#.Net核心MVC后端,它利用typescript中的HttpClient来向后端传递数据和对象 我已经尝试了很多解决方案,但都没有成功(最接近的是我可以在代码中找到控制器,但文件永远不会被传入) 我试图避免对CSV进行任何类型的序列化或转换,直到它到达控制器,所以我想找到一个解决方案,在那里我可以将整个CSV发送到后端 任何帮助都将不胜感激 服务.ts // Parse CSV // The C

我正在尝试将CSV文件传递到后端,以利用库解析CSV数据

我有一个Angular7前端,带有一个C#.Net核心MVC后端,它利用typescript中的HttpClient来向后端传递数据和对象

我已经尝试了很多解决方案,但都没有成功(最接近的是我可以在代码中找到控制器,但文件永远不会被传入)

我试图避免对CSV进行任何类型的序列化或转换,直到它到达控制器,所以我想找到一个解决方案,在那里我可以将整个CSV发送到后端

任何帮助都将不胜感激

服务.ts

// Parse CSV
// The CSV always reaches this part of the code and I can inspect it.
parseCsv$(file: File): Observable<Dto> {
    const request$ = this.http.post<Dto>(
        location.origin + '/api/csvimport',
        file,
        { headers: new HttpHeaders({ 'Content-Type': 'multipart/form-data' }) }
    ).pipe(
        map((response: <Dto>) => response)
    );

    request$.subscribe();

    return request$;
}
    [HttpPost]
    [ProducesResponseType(typeof(Dto), 200)]

    // The 'file' variable below is always null
    public async Task<IActionResult> ParseCsv([FromBody]IFormFile file)
    {
        // do work here
parseCsv$(files: FileList): Observable<Dto> {
    const formData = new FormData();
    Array.from(files).forEach(
        (file: File) => formData.append(file.name, file)
    );

    return this.http.post<Dto>(
        location.origin + '/api/csvimport',
        formData)
    .pipe(
        map((response: <Dto>) => response)
    );
}
[HttpPost]
[ProducesResponseType(typeof(Dto), 200)]
public async Task<IActionResult> ParseCsv(IEnumerable<IFormFile> files)
{
    // Work here...
//解析CSV
//CSV总是到达代码的这一部分,我可以检查它。
parseCsv$(文件:file):可观察{
const request$=this.http.post(
location.origin+'/api/csvimport',
文件
{headers:new-HttpHeaders({'Content-Type':'multipart/form-data'})}
).烟斗(
映射((响应:)=>响应)
);
请求$.subscribe();
返回请求$;
}
CsvImportController.cs

// Parse CSV
// The CSV always reaches this part of the code and I can inspect it.
parseCsv$(file: File): Observable<Dto> {
    const request$ = this.http.post<Dto>(
        location.origin + '/api/csvimport',
        file,
        { headers: new HttpHeaders({ 'Content-Type': 'multipart/form-data' }) }
    ).pipe(
        map((response: <Dto>) => response)
    );

    request$.subscribe();

    return request$;
}
    [HttpPost]
    [ProducesResponseType(typeof(Dto), 200)]

    // The 'file' variable below is always null
    public async Task<IActionResult> ParseCsv([FromBody]IFormFile file)
    {
        // do work here
parseCsv$(files: FileList): Observable<Dto> {
    const formData = new FormData();
    Array.from(files).forEach(
        (file: File) => formData.append(file.name, file)
    );

    return this.http.post<Dto>(
        location.origin + '/api/csvimport',
        formData)
    .pipe(
        map((response: <Dto>) => response)
    );
}
[HttpPost]
[ProducesResponseType(typeof(Dto), 200)]
public async Task<IActionResult> ParseCsv(IEnumerable<IFormFile> files)
{
    // Work here...
[HttpPost]
[产品响应类型(类型(Dto),200)]
//下面的“file”变量始终为空
公共异步任务ParseCsv([FromBody]格式文件)
{
//你在这里工作吗

在文件上载中不应使用FromBody参数

您应该使用,来获取上载的文件, 或

您可以在控制器操作中使用IList,如下所示

下面的API获取文件列表,这些文件保存在服务器上的临时文件夹中

[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
    long size = files.Sum(f => f.Length);

    // full path to file in temp location
    var filePath = Path.GetTempFileName();

    foreach (var formFile in files)
    {
        if (formFile.Length > 0)
        {
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await formFile.CopyToAsync(stream);
            }
        }
    }

    // process uploaded files
    // Don't rely on or trust the FileName property without validation.

    return Ok(new { count = files.Count, size, filePath});
}
[HttpPost(“上传文件”)]
公共异步任务发布(列表文件)
{
long size=files.Sum(f=>f.Length);
//临时位置中文件的完整路径
var filePath=Path.GetTempFileName();
foreach(文件中的var formFile)
{
如果(formFile.Length>0)
{
使用(var stream=newfilestream(filePath,FileMode.Create))
{
等待formFile.CopyToAsync(流);
}
}
}
//处理上载的文件
//未经验证,请勿依赖或信任FileName属性。
返回Ok(新的{count=files.count,size,filePath});
}

希望这能有所帮助。

所以我能找到答案

我需要将
文件
更改为
文件列表
,然后使用
FormData
附加该文件。我还需要删除我的内容头,因为让后端处理键入内容本身可以阻止抛出错误。在我的控制器中,我必须使用
IEnumerable
,这样才能完全工作

我不完全理解为什么只有在 上传一个文件,但这是必要的,以便沿 如果我发现更多,我会更新我的答案

编辑:针对上述问题,在MDN文档中,它指出“所有
元素节点上都有一个
文件列表
类型的文件属性,允许访问此列表中的项目”()因此,为了访问一个文件,实际上需要访问第一个索引(
文件列表[0]
)关于
文件列表
数组。我可能误解了这一点,请随意评论

服务.ts

// Parse CSV
// The CSV always reaches this part of the code and I can inspect it.
parseCsv$(file: File): Observable<Dto> {
    const request$ = this.http.post<Dto>(
        location.origin + '/api/csvimport',
        file,
        { headers: new HttpHeaders({ 'Content-Type': 'multipart/form-data' }) }
    ).pipe(
        map((response: <Dto>) => response)
    );

    request$.subscribe();

    return request$;
}
    [HttpPost]
    [ProducesResponseType(typeof(Dto), 200)]

    // The 'file' variable below is always null
    public async Task<IActionResult> ParseCsv([FromBody]IFormFile file)
    {
        // do work here
parseCsv$(files: FileList): Observable<Dto> {
    const formData = new FormData();
    Array.from(files).forEach(
        (file: File) => formData.append(file.name, file)
    );

    return this.http.post<Dto>(
        location.origin + '/api/csvimport',
        formData)
    .pipe(
        map((response: <Dto>) => response)
    );
}
[HttpPost]
[ProducesResponseType(typeof(Dto), 200)]
public async Task<IActionResult> ParseCsv(IEnumerable<IFormFile> files)
{
    // Work here...
parseCsv$(文件:文件列表):可观察{
const formData=new formData();
Array.from(files.forEach)(
(file:file)=>formData.append(file.name,file)
);
返回this.http.post(
location.origin+'/api/csvimport',
表格数据)
.烟斗(
映射((响应:)=>响应)
);
}
CsvImportController.cs

// Parse CSV
// The CSV always reaches this part of the code and I can inspect it.
parseCsv$(file: File): Observable<Dto> {
    const request$ = this.http.post<Dto>(
        location.origin + '/api/csvimport',
        file,
        { headers: new HttpHeaders({ 'Content-Type': 'multipart/form-data' }) }
    ).pipe(
        map((response: <Dto>) => response)
    );

    request$.subscribe();

    return request$;
}
    [HttpPost]
    [ProducesResponseType(typeof(Dto), 200)]

    // The 'file' variable below is always null
    public async Task<IActionResult> ParseCsv([FromBody]IFormFile file)
    {
        // do work here
parseCsv$(files: FileList): Observable<Dto> {
    const formData = new FormData();
    Array.from(files).forEach(
        (file: File) => formData.append(file.name, file)
    );

    return this.http.post<Dto>(
        location.origin + '/api/csvimport',
        formData)
    .pipe(
        map((response: <Dto>) => response)
    );
}
[HttpPost]
[ProducesResponseType(typeof(Dto), 200)]
public async Task<IActionResult> ParseCsv(IEnumerable<IFormFile> files)
{
    // Work here...
[HttpPost]
[产品响应类型(类型(Dto),200)]
公共异步任务ParseCsv(IEnumerable文件)
{
//在这里工作。。。