Andrus
Andrus

Reputation: 27921

How to create html offline application manifest in ASP.NET Core

Trying to port ASP.NET MVC4 HTML offline application to .NET 5. It should allow to enter order without internet connenction and send it to MVC 5 controller over internet if connection is present.

It has manifest controller

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

This causes compile error in .NET 5 since response.Cache and response.ContentEncoding does not exis in lines

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

also response.Write does not exist in line

response.Write(GenerateContent());

and BundleTable.Bundles does not exist in .NET 5

How to convert it to .NET 5 ? Or is there better way to create HTML offline application in .NET 5 using ASP.NET MVC Core.

Upvotes: 1

Views: 281

Answers (1)

fatherOfWine
fatherOfWine

Reputation: 1251

Cache settings you could handle in startup.cs ConfigureServices method:

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

For the encoding you could use following snippet:

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

responce.Write could be replaced with this:

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

Upvotes: 2

Related Questions