【问题标题】:How to create html offline application manifest in ASP.NET Core如何在 ASP.NET Core 中创建 html 离线应用程序清单
【发布时间】:2021-11-04 04:52:19
【问题描述】:

尝试将 ASP.NET MVC4 HTML 离线应用程序移植到 .NET 5。 它应该允许在没有互联网连接的情况下输入订单,并在存在连接时通过互联网将其发送到 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-core asp.net-core-mvc


    【解决方案1】:

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

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

    对于编码,您可以使用以下 sn-p:

    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);
    

    【讨论】:

    • 对于 cacing,我将 [ResponseCache(NoStore = true, Duration = 0)] 属性添加到 Manifest 控制器。它会产生与 MVC4 代码响应 cahce 设置相同的结果吗?
    • @Andrus 确保 MediaTypeHeaderValue 来自 Microsoft.Net.Http.Headers 程序集。我认为这个属性也应该可以解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    相关资源
    最近更新 更多