在 ASP .NET 中尝试 POST 时出现错误请求

Bad Request when trying POST in ASP .NET

我有一个非常简单的系统:ASP .NET Core 服务器托管在 domain.ru 上。在 API 控制器中,我有两种方法:

    [HttpGet("{id}")]
    public string Get(int id)
    {
        try
        {
            using (FileStream fstream = new FileStream(string.Format(@"{0}\data{1}.txt", _path, id.ToString()), FileMode.OpenOrCreate))
            {
                byte[] array = System.Text.Encoding.Default.GetBytes(id.ToString());
                fstream.Write(array, 0, array.Length);
                return "It's ok!";
            }
        }
        catch
        {
            return "Something went wrong";
        }
    }
    [HttpPost]
    public string Post(string resolvedString)
    {
        try
        {
            using (FileStream fstream = new FileStream(string.Format(@"{0}\dataPost.txt", _path), FileMode.OpenOrCreate))
            {
                byte[] array = System.Text.Encoding.Default.GetBytes(resolvedString);
                fstream.Write(array, 0, array.Length);
                return "It's ok!";
            }
        }
        catch
        {
            return "Something went wrong";
        }
    }

所以基本上它们都只是在 _path 目录中创建文本文件。我无法理解的部分是当我尝试通过 url 域调用 Get 方法时。ru/api/values/1 我可以看到在 _path 目录,我收到“没问题!”的回复。这就是我如何调用 Get:

        var client = new HttpClient();
        client.BaseAddress = new Uri(uri);
        HttpResponseMessage response = await client.GetAsync("api/values/1");
        string result = await response.Content.ReadAsStringAsync();
        textBox1.Text = result.ToString();

但是,当我尝试使用 Post 进行相同操作时,我要么在使用 C# 时收到错误请求,要么在使用 Postman 时收到“出错了”。 我就是这样称呼 Post

        var client = new HttpClient();
        client.BaseAddress = new Uri(uri);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        MultipartFormDataContent content = new MultipartFormDataContent();
        StringContent str = new StringContent("1");
        content.Add(str);
        HttpResponseMessage response = await client.PostAsync("api/values/", content);
        string returnString = await response.Content.ReadAsStringAsync();
        MessageBox.Show(returnString);

Here's what the request shows when I try to manually debug this

也是最有趣的部分。当我的服务器托管在 IIS(本地服务器)上时,当我尝试执行所有相同的操作时,它工作得很好!我真的不知道我做错了什么。请帮忙。

UPD. 感谢 Jonathan,我要求我的主机在 Plesk 中禁用 ModSecurity,上面的代码在将 [HttpPost] 替换为 [Http] 后开始工作Post("{resolvedString}")]。到目前为止一切顺利!

然后我尝试向服务器发送一个 zip 存档。这是服务器的控制器代码:

    [HttpPost]
    public string ImportZip(IFormFile file)
    {
        DirectoryInfo dirInfo = new DirectoryInfo(_extractPath);
        try
        {
            foreach (FileInfo myfile in dirInfo.GetFiles())
            {
                myfile.Delete();
            }
            string path = _path + "tmp.zip";
            if (Request.HasFormContentType)
            {
                var form = Request.Form;
                foreach (var formFile in form.Files)
                {
                    using (var fileStream = new FileStream(path, FileMode.Create))
                    {
                        formFile.CopyTo(fileStream);
                    }
                    ZipFile.ExtractToDirectory(_path + "tmp.zip", _extractPath);
                }
            }
            return "It's OK! At least we've entered the method.";
        }
        catch
        {
            return "Oh no no no...";
        }

    }

我在客户那里就是这样称呼它的:

        string filepath = _zipFile;
        string filename = _fileName;
        var client = new HttpClient();
        client.BaseAddress = new Uri(uri);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        MultipartFormDataContent content = new MultipartFormDataContent();
        ByteArrayContent fileContent = new ByteArrayContent(File.ReadAllBytes(filepath));
        content.Add(fileContent, "file", filename);
        HttpResponseMessage response = await client.PostAsync("File/ImportZip/", content);
        string result = await response.Content.ReadAsStringAsync();
        textBox1.Text = result;

再一次,当我 运行 在我的计算机上同时使用服务器和客户端时,它可以正常工作。我可以在目标目录中看到下载的存档和提取的文件。 但是当我将我的服务器上传到主机并尝试再次执行我的查询时,我得到了同样的错误: an example of an error

嗯,看来我自己找到了答案。会把它留在这里,以便它可以帮助某人(将来可能是我)。

客户端发送方法代码:

        string uri = "https://example.com/controller/action/";
        string zipFile = @"C:\Path\To\Your\File.txt";
        string response;
        using (WebClient client = new WebClient())
        {
            response = Encoding.Default.GetString(client.UploadFile(uri, zipFile));
        }
        MessageBox.Show(response);

这里我们只是编写一个请求并发送一个文件。路径和 url 被硬编码为 ex.

服务器保存方式代码:

[HttpPost]
    public string ImportZip(IFormFile file)
    {
        try
        {
            string path = _path + "tmp.zip";
            if (Request.HasFormContentType)
            {
                var form = Request.Form;
                foreach (var formFile in form.Files)
                {
                    using (var fileStream = new FileStream(path, FileMode.Create))
                    {
                        formFile.CopyTo(fileStream);
                    }
                }
                return "Done";
            }
            return "Empty request";
        }
        catch
        {
            return "No access";
        }
    }

只要我只发送一个文件并且我知道它的扩展名并且我希望它被称为“tmp”,我就可以硬编码它的名称和扩展名。您可以使用文件的默认值 name/extension 将其按原样保存。 然后我将请求中的所有文件保存到选定的 _path 目录中。

基本上就是这样。