Web Api 2 RESTFUL 图像上传

7

我是Web Api的新手,正在进行我的第一个项目。我正在为我们公司开发移动CRM系统。

我想存储公司徽标、客户面部照片等等。

我找到了一些关于这个话题的教程,但不幸的是其中一些已经过时(没有使用异步),而其他一些则无法工作。

最后我找到了这个网站:http://www.intstrings.com/ramivemula/articles/file-upload-using-multipartformdatastreamprovider-in-asp-net-webapi/,它可以正常工作,但是我还有一些问题需要解决。

1)我应该使用App_Data(或任何其他文件夹,如/Uploads)来存储这些图像,还是应该将图像存储在数据库中?

2)我可以只设置支持的图像格式,如.jpg、.png,并拒绝任何其他文件吗?

3)如何在上传方法中处理图像?比如缩放、降低文件大小、质量等等?

谢谢。

3个回答

5
1)我们将文件存储在不同于app_data的位置。 我们有几个客户组,我们为每个组分配一个独特的文件夹,并从数据库中获取。 将其存储在数据库中也是一种选择,但如果您选择这条路,请确保保存的文件不直接属于您需要经常检索的表。 这没有对错之分,但请参阅此问题和答案以了解一些利弊。

2)如果您遵循了该指南,可以在循环内放置检查以检查文件结尾。

List<string> denyList = new List<string>();
denyList.Add(".jpg");

foreach (MultipartFileData file in provider.FileData) 
{
    string fileName = Path.GetFileName(file.LocalFileName);
    if(denyList.Contains(Path.GetExtension(fileName))
         throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

    files.Add(Path.GetFileName(file.LocalFileName)); 
}

3) 调整图像大小是我个人从未亲自尝试过的事情,但我认为你应该看看System.Drawing.Graphics命名空间。 找到了一个有关图片缩小的已接受答案的链接:ASP.Net MVC图片上传通过缩小或填充进行调整大小


嗨,感谢您的回复。您回答了我大部分的问题 :) 不幸的是,关于您发布的代码还有一个问题。您在foreach中使用provider。但是当您从提供程序加载数据时,文件已经保存在服务器上。因此,如果它是不受支持的格式,您会将错误发送回来,但文件仍然存储在服务器上。 - Stepan Sanda
嗨,Sandak。我刚刚阅读了你链接的网站上的代码,看起来 files.Add 是保存文件的部分,但在保存文件之前抛出错误是值得推荐的,正如你所提到的那样。在创建和读取数据到提供程序之前,您可能需要检查 Request.Content,以避免保存文件。 - Binke

1

所有的问题都与Web API或REST无关。

  1. 如果您使用的是SQL Server 2008或更新版本,则答案是使用FILESTREAM列。这看起来像是数据库中的一列,具有其所有优点(例如备份、复制、事务),但实际上数据存储在文件系统中。因此,您可以得到每个世界的最佳效果,即不会发生某人意外删除文件,因此数据库将引用不存在的文件,或者反之,从数据库中删除记录但未删除文件,因此您最终会得到一堆孤立的文件。使用数据库有许多优点,例如可以将元数据与文件关联,并且权限更容易设置。
  2. 这取决于文件是如何上传的。例如,如果使用多部分表单,则在保存每个部分之前检查其内容类型。您甚至可以创建自己的MultipartStreamProvider类。作为API,也许上传方法具有流或字节数组参数和内容类型参数,在这种情况下,只需在保存内容之前测试内容类型参数的值即可。对于其他上传方法,请根据输入内容的不同执行类似的操作。
  3. 您可以使用.Net的内置类(例如Bitmap:SetResolution,RotateFlip,要调整大小,请使用接受大小的构造函数),或者如果您不熟悉图像处理,则选择图像处理库。

以上所有工作都是在Asp.Net、MVC、Web API 1和2、自定义HTTP处理程序中完成的,基本上在任何.Net代码中都可以实现。


-2
@Binke 不要对路径使用字符串操作。例如fileName.split('.')[1]将不会返回扩展名,如果文件名是像这样的:some.file.txt,并且如果文件没有扩展名,则会因为索引超出范围而失败。 始终使用文件API,即Path.GetExtension。
另外,仅凭扩展名获取内容类型并不安全,特别是涉及图片和视频时,想想AVI扩展名被许多视频格式所使用的情况。
files.Add(Path.GetFileName(file.LocalFileName)) 应该改为 files.Add(fileName)。

@noelicus 可能你忘了新用户在获得一定的声望之前是不允许评论的,他们唯一的选择是回答。 - user3285954
可能你忘了,当你意识到答案不相关时,可以删除它们。 :-D - noelicus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接