正在 ASP.NET 样板文件中上传图片

Uploading image in ASP.NET Boilerplate

发布图片时,HttpContext.Current.Requestnull

有什么简单的方法可以做到这一点吗?我在客户端使用 dropzone.js

项目 Angular 使用 Web API (ASP.NET Core 2.0) 模板。

[HttpPost]      
public HttpResponseMessage UploadJsonFile()
{
    HttpResponseMessage response = new HttpResponseMessage();           
    var httpRequest = HttpContext.Current.Request;
    if (httpRequest.Files.Count > 0)
    {
        foreach (string file in httpRequest.Files)
        {
            var postedFile = httpRequest.Files[file];
            var filePath = HttpContext.Current.Server.MapPath("~/UploadFile/" + postedFile.FileName);
            postedFile.SaveAs(filePath);
        }
    }
    return response;
}

您不能使用应用服务上传图片。

  • 只需创建一个新控制器并上传您的文件。
  • Return 向客户端发送您在服务器中生成的唯一文件名。
  • 当用户保存整个实体时,再次将唯一的文件名发送到服务器。

您可以从 AbpController 派生您的控制器。

这是我编写的代码,运行良好。

public void PostFile(IFormFile file)
{          
    var uploads = Path.Combine("ROOT PATH FOR THE FILES", "uploads");

    if (file.Length > 0)
    {
        var filePath = Path.Combine(uploads, file.FileName);

        using (var fileStream = new FileStream(filePath, FileMode.Create))
        {
            file.CopyTo(fileStream);
        }
    }
}

首先,我们需要使用 IOperationFilter 在 Swagger 中启用文件上传。创建一个继承自 IOperationFilter 的 class。有关详细信息,请阅读 this article

public class FormFileSwaggerFilter: IOperationFilter
{
    private const string formDataMimeType = "multipart/form-data";
    private static readonly string[] formFilePropertyNames =
        typeof(IFormFile).GetTypeInfo().DeclaredProperties.Select(p => p.Name).ToArray();

    public void Apply(Operation operation, OperationFilterContext context)
    {
        var parameters = operation.Parameters;
        if (parameters == null || parameters.Count == 0) return;

        var formFileParameterNames = new List<string>();
        var formFileSubParameterNames = new List<string>();

        foreach (var actionParameter in context.ApiDescription.ActionDescriptor.Parameters)
        {
            var properties =
                actionParameter.ParameterType.GetProperties()
                    .Where(p => p.PropertyType == typeof(IFormFile))
                    .Select(p => p.Name)
                    .ToArray();

            if (properties.Length != 0)
            {
                formFileParameterNames.AddRange(properties);
                formFileSubParameterNames.AddRange(properties);
                continue;
            }

            if (actionParameter.ParameterType != typeof(IFormFile)) continue;
            formFileParameterNames.Add(actionParameter.Name);
        }

        if (!formFileParameterNames.Any()) return;

        var consumes = operation.Consumes;
        consumes.Clear();
        consumes.Add(formDataMimeType);

        foreach (var parameter in parameters.ToArray())
        {
            if (!(parameter is NonBodyParameter) || parameter.In != "formData") continue;

            if (formFileSubParameterNames.Any(p => parameter.Name.StartsWith(p + "."))
                || formFilePropertyNames.Contains(parameter.Name))
                parameters.Remove(parameter);
        }

        foreach (var formFileParameter in formFileParameterNames)
        {
            parameters.Add(new NonBodyParameter()
            {
                Name = formFileParameter,
                Type = "file",
                In = "formData"
            });
        }
    }
}

然后在Startup.cs

中注册这个class
services.AddSwaggerGen(options =>
    {
        // Swagger Configuration

        // Register File Upload Operation Filter
        options.OperationFilter<FormFileSwaggerFilter>();
    });

现在在服务文件中定义如下方法,

public class ExampleAppService : // Inherit from required class/interface
{
    public RETURN_TYPE UploadFile([FromForm]IFormFile file)
    {
         // Save file here
    }
}

*** 上传文件的方法参数不要忘记使用[FromForm],否则swagger会多出6个参数ui.

现在,使用 NSwag 生成 angular 的服务文件将需要 ui 类型的参数 FileParameter。现在在组件中,

methodName = (file): void => {
    // file is the selected file
    this._service
      .uploadDocument({ data: file, fileName: file.name } as FileParameter)
      .subscribe((res) => {
          // Handle Response
      });
  };

首先注入IHostingEnvironment获取服务器路径 私有 IHostingEnvironment _environment;

然后在函数中使用它

[HttpPost]
    public void PostFile(IFormFile file)
    {
        string uploads = Path.Combine(_environment.WebRootPath, "uploads");            
        
        if (file.Length > 0)
        {
            var filePath = Path.Combine(uploads, file.FileName);

            using (var fileStream = new FileStream(filePath, FileMode.Create))
            {
                file.CopyTo(fileStream);
            }
        }
    }