ASP.NET Core 8 Web API Swagger 与 PowerShell 后端集成中的文件上传问题

问题描述 投票:0回答:1

我是创建 API 的新手,目前不确定我的 API 是否可以在 Swagger 中成功执行。但现在的问题是,我在 Swagger 中执行后,按预期弹出了文件对话框窗口,但选择所需的

.CSV
文件后,页面一直在加载,没有任何进一步的响应。有什么我可以解决这个问题或者它可以显示消息成功设置基线或无法在 Swagger 中设置基线吗?

这是我的 ASP.NET Core 8 Web API:

using System.Management.Automation;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Security.AccessControl;
using System.IO;

namespace myAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ApiController : ControllerBase
    {
        [HttpPost("setbaseline")]
        public IActionResult SetBaseline()
        {
            // Path to your PowerShell script
            string scriptPath = @"my own file path";

            // Start PowerShell process
            using (Process process = new Process())
            {
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = scriptPath,
                    Arguments = $"-ExecutionPolicy Bypass -File \"{scriptPath}\"",
                    RedirectStandardInput = true, // Redirect standard input to send commands to the PowerShell process
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                };

                process.StartInfo = startInfo;
                process.Start();

                // Automatically enter "F" to simulate user input
                process.StandardInput.WriteLine("F");

                process.WaitForExit();

                // Read output and error streams
                string output = process.StandardOutput.ReadToEnd();
                string error = process.StandardError.ReadToEnd();

                if (process.ExitCode == 0)
                {
                    // PowerShell script executed successfully
                    return Ok(output);
                }
                else
                {
                    // PowerShell script failed to execute
                    return StatusCode(StatusCodes.Status500InternalServerError, error);
                }
            }

            return Ok("Set baseline triggered successfully.");
        }
    }
}

这段代码是我的Powershell后端脚本:

Add-Type -AssemblyName System.Windows.Forms

Function Set-BaselineFilePath {
    $inputFilePick = New-Object System.Windows.Forms.OpenFileDialog
    $inputFilePick.Filter = "CSV (*.csv) | *.csv" #only restrict user to select .csv file
    $inputFilePick.ShowDialog()
    $global:baselineFilePath = $inputFilePick.FileName
    if (Test-Path -Path $global:baselineFilePath) {
        if ($global:baselineFilePath.Substring($global:baselineFilePath.Length - 4, 4) -eq ".csv") {
            return $global:baselineFilePath
        } else {
            Write-Host "Invalid file: The file must be a CSV file." -ForegroundColor Red
            exit 1
            return $null
        }
    } else {
        Write-Host "Invalid file path for baseline." -ForegroundColor Red
        return $null
    }
}

Function Show-Menu {
    do {
         Write-Host "    a) Set baseline file ; Current set baseline $($global:baselineFilePath)" -ForegroundColor Magenta

        $response = Read-Host -Prompt "Please enter 'A', 'B', 'C', 'D', 'E', 'F', 'G', or 'H'"

        switch ($response.ToUpper()) {

            "F" { # Handle option F
                $global:baselineFilePath = Set-BaselineFilePath
                if ($global:baselineFilePath) {
                    Write-Host "Baseline file path set to: $global:baselineFilePath" -ForegroundColor Green
                    Write-Host "Baseline file path successfully set." -ForegroundColor Green
                    exit 0
                } else {
                    Write-Host "Baseline file path not set." -ForegroundColor Yellow
                }
            }
            
        }
    } while ($response -ne "C")
}

# Main script logic
Show-Menu

因为在选择所需的 CSV 文件后,这一行也指示下面的错误

string error = process.StandardError.ReadToEnd();

这是我得到的错误:

System.InvalidOperationException:StandardError 尚未重定向。

c# powershell visual-studio asp.net-core-webapi .net-8.0
1个回答
0
投票

首先,我想与您分享的是,您使用的方法“执行启动文件对话框的 PowerShell 脚本以从 Windows 窗体应用程序手动选择文件”不适合托管在服务器上的 Web api 服务,因为它是非交互式的。 Web 服务将无法访问客户端的本地文件或 UI。

相反,您可以设计您的 API 端点:

// POST api/apicontroller/setbaseline
[HttpPost("setbaseline")]
public async Task<IActionResult> SetBaseline(IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest("No file uploaded.");
    }
    try
    {
        using (var memoryStream = new MemoryStream())
        {
            await file.CopyToAsync(memoryStream);
            memoryStream.Seek(0, SeekOrigin.Begin);

            // code to process the memory stream pass the stream to a method that parses the CSV file
            bool isProcessed = ProcessCsvStream(memoryStream);
            if (isProcessed)
            {
                return Ok("Set baseline triggered successfully.");
            }
            else
            {
                return StatusCode(StatusCodes.Status500InternalServerError, "Failed to process file.");
            }
        }
    }
    catch (Exception ex)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
    }
}

private bool ProcessCsvStream(MemoryStream memoryStream)
{
    // CSV processing logic here
    // Return true on success or false on failure
    return true;
}

通过使用此方法,您不需要使用 PowerShell 脚本或任何单独的进程。这个 Api 端点将处理一切。之后您可以使用 Swagger UI 进行文件上传:

  1. 导航到您的 Swagger UI(通常为
    http://localhost:<port>/swagger
    )。
  2. 找到并选择
    setbaseline
    端点。
  3. 使用文件选择器选择 CSV 文件。
  4. 单击“执行”将文件发送到您的端点。

如果我们谈论错误,您将收到“System.InvalidOperationException:StandardError 尚未重定向。”表示您尝试从标准错误流中读取数据,而没有配置

ProcessStartInfo
来重定向标准错误。要解决此问题,您可以添加代码
RedirectStandardError = true;

© www.soinside.com 2019 - 2024. All rights reserved.