【问题标题】:Reading HTTP File AND Form data without writing to disk using Web API使用 Web API 在不写入磁盘的情况下读取 HTTP 文件和表单数据
【发布时间】:2019-10-12 10:03:14
【问题描述】:

我的问题与此类似: webapi-file-uploading-without-writing-files-to-disk

但是,这个问题和大多数其他类似问题都停留在读取文件数据上。我已经使该位工作正常,但我也想读取表单中的其余表单数据,其中包含其他上传元素,例如“标题”等。这来自上述问题中的解决方案:

            var filesToReadProvider = await Request.Content.ReadAsMultipartAsync();

filesToReadProvider 是 HTTPContent 对象的集合,所以我尝试了:

        List<HttpContent> uploadedstuff = filesToReadProvider.Contents.ToList();
        Image image = new Image(); ;        // The image object we will create
        Stream filestream;  // The file stream object to use with the image
        foreach (var thing in uploadedstuff)
        {
            try
            {
                string name = thing.Headers.ContentDisposition.Name.Replace("\"", ""); // String is quoted "\""namestring"\"" so need it stripped out
                List<NameValueHeaderValue> parameters = thing.Headers.ContentDisposition.Parameters.ToList();
                if (name == "file")
                {
                    image.LocalFileName = thing.Headers.ContentDisposition.FileName;
                    filestream = await thing.ReadAsStreamAsync();
                }
                if (name == "Title")
                {
                    // vvv- this line causes an exception.
                    NameValueCollection titleData = await thing.ReadAsFormDataAsync();
                }
            }
            catch (System.Exception e)
            {
                var message = "Something went wrong";
                HttpResponseMessage err = new HttpResponseMessage() { StatusCode = HttpStatusCode.ExpectationFailed, ReasonPhrase = message };
                return ResponseMessage(err);
            }
        }

任何想法我应该做些什么来获得例如:“标题”表单数据?我觉得我很接近,但可能采取了错误的方法? 非常感谢。

【问题讨论】:

  • 表单多部分内容的每个部分都有自己的内容类型。试试thing.ReadAsStringAsync() 看看有什么回报。如果是我认为的,我会详细说明
  • 太棒了,谢谢!...是的,就是这样。我觉得我很接近,这得到了它。当场。

标签: c# asp.net-web-api http-headers


【解决方案1】:

现在它已在 cmets 中整理出来,我将发布此答案以帮助其他人。

form multipart content 像这样将数据发送回服务器”

---------------------------acebdf13572468
Content-Disposition: form-data; name="file"; 
Content-Type: image/*

<@INCLUDE *App.jpg*@>
---------------------------acebdf13572468
Content-Disposition: form-data; name="TextField";
Content-Type: application/octet-stream

Text Value
---------------------------acebdf13572468
Content-Disposition: form-data; name="JsonField";
Content-Type: application/json

{
"Json" : "Object"
}
---------------------------acebdf13572468--

用分隔线分隔的每个部分(即---------------------------acebdf13572468)都是它自己的内容,因此是多部分。

您可以如上所示在一个字段中以 json 格式发送数据,也可以发送文本或任何内容。通常浏览器将每个控件发送到它自己的单个部分中。您可以通过在控制器参数中指定 [FromForm] 来通过 ASP.Net 模型绑定器读取此类数据。

或者在这种特殊情况下,您可以使用thing.ReadAsStreamAsync();thing.ReadAsStringAsync(); 阅读它

--编辑--

所以上述方法在直接读取数据或其他非 MVC 项目时很有用。如果您使用的是 MVC,则可以轻松阅读此类内容。

假设你有一个类似的模型

public class Model
{
    public string Title { get; set; }
}

然后你会像这样创建一个控制器和动作:

public class MainController : Controller
{
    [HttpPost]
    public async Task<IActionResult> UploadImage([FromForm]Model model)
    {
        var files = Request.Files;
        var title = model.Title
        //And you can save or use files and content at the same time.
    }
}

这通常是您在 MVC 场景中所做的事情,如果您在客户端使用 Razor 或 Pages,您甚至不需要指定 [FromForm] 属性。

希望对你有帮助。

免责声明。我已经在浏览器中编写了所有这些。可能包含语法和其他错误。

【讨论】:

  • 再次感谢@Emad...所以我想再问你一个小问题,因为理想情况下,我希望有一个 API 签名,例如: public async Task UploadImage(ImageFile,ImageDTO图像)
  • ...你是说我可以通过在签名中添加 [Fromform] 来更自动地做到这一点......就像 [FromBody] 一样?如果是这样,那将使它变得更简单。我已经放弃了这种方法,因为我找不到任何有希望的文档来描述如何。我预测这将成为一个很好读的帖子。我会试一试,如果我再次回来,请原谅我。谢谢
  • 请查看编辑。我已经尽力解释了。
  • 嗨,Emad,请注意,我今天早上尝试了这个,但无法正常工作。它有点回到我开始的地方,但我注意到没有提供 [FromForm],我认为您必须指的是 .NET Core 中的工具。我目前的目标是 .NET 4.6,准备很快迁移到核心 3,但这是我以后需要解决的另一个问题。我现在将回到我的工作解决方案,也许再看看核心 3 时间。再次感谢。
  • 这在 .Net 框架中是不同的。我有点忘记了当时的情况,或者我会编辑答案以包含它。据我记得。您需要有一个与您在每个部分中发送的属性完全相同的对象。请测试它是否有效告诉我编辑
猜你喜欢
  • 1970-01-01
  • 2018-02-25
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多