首页 > 解决方案 > 如何在 ASP.NET Core 中创建 html 离线应用程序清单

问题描述

尝试将 ASP.NET MVC4 HTML 离线应用程序移植到 .NET 5。它应该允许在没有 Internet 连接的情况下输入订单,并在存在连接的情况下通过 Internet 将其发送到 MVC 5 控制器。

它有清单控制器

namespace Store.Controllers
{
    public class MobileOrderController : ControllerBase
        {

        public async Task<IActionResult> Manifest()
        {
            return new AppCacheResult(new[] {
                BundleTable.Bundles.ResolveBundleUrl("~/bundles/jquery")
            },
           fingerprint: BundleTable.Bundles
                           .FingerprintsOf("~/bundles/jquery"));
        }
    }
     }

        public class AppCacheResult : IActionResult
        {
            public AppCacheResult(
                IEnumerable<string> cacheAssets,
                IEnumerable<string> networkAssets = null,
                IDictionary<string, string> fallbackAssets = null,
                string fingerprint = null)
            {
                if (cacheAssets == null)
                {
                    throw new ArgumentNullException("cacheAssets");
                }
    
                CacheAssets = cacheAssets.ToList();
    
                if (!CacheAssets.Any())
                {
                    throw new ArgumentException(
                        "Cached url cannot be empty.", "cacheAssets");
                }
    
                NetworkAssets = networkAssets ?? new List<string>();
                FallbackAssets = fallbackAssets ?? new Dictionary<string, string>();
                Fingerprint = fingerprint;
            }
    
            protected IEnumerable<string> CacheAssets { get; private set; }
    
            protected IEnumerable<string> NetworkAssets { get; private set; }
    
            protected IDictionary<string, string> FallbackAssets
            {
                get;
                private set;
            }
    
            protected string Fingerprint { get; private set; }
    
            public async Task ExecuteResultAsync(ActionContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }
    
                var response = context.HttpContext.Response;
    
                response.Cache.SetMaxAge(TimeSpan.Zero);
                response.ContentType = "text/cache-manifest";
                response.ContentEncoding = Encoding.UTF8; //  needs to be utf-8
                response.Write(GenerateContent());
            }
    
            protected virtual string GenerateHeader()
            {
                return "CACHE MANIFEST" + Environment.NewLine;
            }
    
            protected virtual string GenerateFingerprint()
            {
                return string.IsNullOrWhiteSpace(Fingerprint) ?
                    string.Empty :
                    Environment.NewLine +
                    "# " + Fingerprint +
                    Environment.NewLine;
            }
    
            protected virtual string GenerateCache()
            {
                var result = new StringBuilder();
    
                result.AppendLine();
                result.AppendLine("CACHE:");
                CacheAssets.ToList().ForEach(a => result.AppendLine(a));
    
                return result.ToString();
            }
    
            protected virtual string GenerateNetwork()
            {
                var result = new StringBuilder();
    
                result.AppendLine();
                result.AppendLine("NETWORK:");
    
                var networkAssets = NetworkAssets.ToList();
    
                if (networkAssets.Any())
                {
                    networkAssets.ForEach(a => result.AppendLine(a));
                }
                else
                {
                    result.AppendLine("*");
                }
    
                return result.ToString();
            }
    
            protected virtual string GenerateFallback()
            {
                if (!FallbackAssets.Any())
                {
                    return string.Empty;
                }
    
                var result = new StringBuilder();
    
                result.AppendLine();
                result.AppendLine("FALLBACK:");
    
                foreach (var pair in FallbackAssets)
                {
                    result.AppendLine(pair.Key + " " + pair.Value);
                }
    
                return result.ToString();
            }
    
            private string GenerateContent()
            {
                var content = new StringBuilder();
    
                content.Append(GenerateHeader());
                content.Append(GenerateFingerprint());
                content.Append(GenerateCache());
                content.Append(GenerateNetwork());
                content.Append(GenerateFallback());
    
                var result = content.ToString();
    
                return result;
            }
        }

这会导致 .NET 5 中的编译错误,因为 response.Cache 和 response.ContentEncoding 不存在于行中

response.Cache.SetMaxAge(TimeSpan.Zero);
response.ContentEncoding = Encoding.UTF8; 

也 response.Write 不存在于行中

response.Write(GenerateContent());

并且 .NET 5 中不存在 BundleTable.Bundles

如何将其转换为 .NET 5 ?或者有没有更好的方法使用 ASP.NET MVC Core 在 .NET 5 中创建 HTML 离线应用程序。

标签: c#asp.net-core.net-coreasp.net-core-mvc

解决方案


您可以在 startup.cs ConfigureServices 方法中处理的缓存设置:

        services.AddMvc(options =>
        {
            options.CacheProfiles.Add("Default30",
                new CacheProfile()
                {
                    Duration = 30
                });
        });

对于编码,您可以使用以下代码段:

var mediaType = new MediaTypeHeaderValue("application/json");
mediaType.Encoding = Encoding.UTF8;
httpContext.Response.ContentType = mediaType.ToString();

responce.Write 可以替换为:

byte[] bytes = Encoding.ASCII.GetBytes(GenerateContent());        
await HttpContext.Response.Body.WriteAsync(bytes);

推荐阅读