如何使用Asp.Net core 2.0 Webapi写入wwwroot中的文件

时间:2018-01-02 13:48:32

标签: asp.net-core asp.net-core-2.0 asp.net-core-webapi

我需要一个非常简单的API来允许发布某些键。 这个密钥应该写在一个文件上,但是我在部署应用程序后遇到了麻烦,因为我可以在GET请求中读取该文件但是发布不起作用。

它给我的信息是

  

“detail”:“拒绝访问路径'.... \ Keys \ Keys.json'。”,

我用来写文件的代码:

        var path = "wwwroot/Keys/Keys.json";

        var result = new List <FireBaseKeysModel> ( );

        if (System.IO.File.Exists (path)) {
            var initialJson = System.IO.File.ReadAllText (path);
            var convertedJson =
                JsonConvert.DeserializeObject <List <FireBaseKeysModel>> (initialJson);
            try {
                result.AddRange (convertedJson);
            }
            catch  {
                //
            }

        }

        result.Add(new FireBaseKeysModel() {
            AccountId = accountId,
            AditionalInfo = addicionalInfo,
            DeviceInfo = deviceInfo,
            RegistrationKey = registrationKey,
            ClientId = clientId
        });

        var json = JsonConvert.SerializeObject (result.ToArray ( ));

        System.IO.File.WriteAllText (path, json);

无论如何,我可以在不需要更改服务器本身权限的情况下修复此问题吗?

2 个答案:

答案 0 :(得分:1)

如果不修改该文件夹的权限,就不应该有办法修复它。 (因为您正在使用System.IO我假设这是Windows和IIS)。工作进程通常使用运行应用程序池的帐户。

默认情况下,此帐户应该只具有该文件夹的读取权限。没有给他,至少是写作许可,就没有办法解决它。

小偏离主题评论:我不会对wwwroot文件夹进行硬编码,因为该文件夹的名称是配置的对象,并且可以很好地更改,我将使用内置的IHostingEnvironment和依赖注入来获取路径:

private IHostingEnvironment _env;
public FooController(IHostingEnvironment env) {
    _env = env;
}

var webrootFolder = _env.WebRootPath

答案 1 :(得分:0)

我有类似的任务,我需要登录用户&#39;上传文件并将其存储在服务器上。我选择将它们存储在文件夹结构wwwroot/uploads/{ environment }/{ username }/{ YYYY }/{ MM }/{ DD }/下。

我没有给出您问题的确切答案,但这些是您可能想要尝试的步骤。

  1. 启用静态文件使用

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        ......
    
        // With the usage of static file extensions, you shouldn't need to
        // set permissions to folders, if you decide to go with wwwroot.
        app.UseStaticFiles();
    
        ......
    }
    
  2. 存储服务

    public interface IStorageService
    {
        Task<string> UploadAsync(string path, IFormFile content, string nameWithoutExtension = null);
    }
    
    public class LocalFileStorageService : IStorageService
    {
        private readonly IHostingEnvironment _env;
    
        public LocalFileStorageService(IHostingEnvironment env)
        {
            _env = env;
        }
    
        public async Task<string> UploadAsync(string path, IFormFile content, string nameWithoutExtension = null)
        {
            if (content != null && content.Length > 0)
            {
                string extension = Path.GetExtension(content.FileName);
    
                // Never trust user's provided file name
                string fileName = $"{ nameWithoutExtension ?? Guid.NewGuid().ToString() }{ extension }";
    
                // Combine the path with web root and my folder of choice, 
                // "uploads" 
                path = Path.Combine(_env.WebRootPath, "uploads", path).ToLower();
    
                // If the path doesn't exist, create it.
                // In your case, you might not need it if you're going 
                // to make sure your `keys.json` file is always there.
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
    
                // Combine the path with the file name
                string fullFileLocation = Path.Combine(path, fileName).ToLower();
    
                // If your case, you might just need to open your 
                // `keys.json` and append text on it.
                // Note that there is FileMode.Append too you might want to
                // take a look.
                using (var fileStream = new FileStream(fullFileLocation, FileMode.Create))
                {
                   await Content.CopyToAsync(fileStream);
                }
    
                // I only want to get its relative path
                return fullFileLocation.Replace(_env.WebRootPath, 
                    String.Empty, StringComparison.OrdinalIgnoreCase);
            }
    
            return String.Empty;
        }
    }