public void DoubleDisposeTest() { var sb = new ZStringWriter(); sb.Dispose(); sb.Dispose(); // call more than once }
public async Task <string> RenderViewToStringAsync(string viewName, object model, IViewEngine viewEngine) { var actionContext = await GetActionContextAsync(); var view = FindView(actionContext, viewName, viewEngine); using var output = new ZStringWriter(); var viewContext = new ViewContext( actionContext, view, new ViewDataDictionary( metadataProvider: new EmptyModelMetadataProvider(), modelState: new ModelStateDictionary()) { Model = model }, new TempDataDictionary( actionContext.HttpContext, _tempDataProvider), output, new HtmlHelperOptions()); await view.RenderAsync(viewContext); return(output.ToString()); }
public override string Write(object?value, Type type) { using var stringWriter = new ZStringWriter(); using var writer = new JsonTextWriter(stringWriter) { Formatting = _jsonSerializer.Formatting }; // ReSharper disable once HeapView.BoxingAllocation _jsonSerializer.Serialize(writer, value, type); return(stringWriter.ToString()); }
public override Task GetContentItemAspectAsync(ContentItemAspectContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); if (contentTypeDefinition == null) { return(Task.CompletedTask); } return(context.ForAsync <FullTextAspect>(async fullTextAspect => { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); var settings = contentTypeDefinition.GetSettings <FullTextAspectSettings>(); if (settings.IncludeDisplayText) { fullTextAspect.Segments.Add(context.ContentItem.DisplayText); } if (settings.IncludeBodyAspect) { // Lazy resolution to prevent cyclic dependency of content handlers var contentManager = _serviceProvider.GetRequiredService <IContentManager>(); var bodyAspect = await contentManager.PopulateAspectAsync <BodyAspect>(context.ContentItem); if (bodyAspect != null && bodyAspect.Body != null) { using var sw = new ZStringWriter(); // Don't encode the body bodyAspect.Body.WriteTo(sw, NullHtmlEncoder.Default); fullTextAspect.Segments.Add(sw.ToString()); } } if (settings.IncludeFullTextTemplate && !String.IsNullOrEmpty(settings.FullTextTemplate)) { var result = await _liquidTemplateManager.RenderStringAsync(settings.FullTextTemplate, NullEncoder.Default, context.ContentItem, new Dictionary <string, FluidValue>() { ["ContentItem"] = new ObjectValue(context.ContentItem) }); fullTextAspect.Segments.Add(result); } })); }
public void BasicWrites() { using (var writer = new ZStringWriter()) { writer.Write("text1".AsSpan()); writer.Write("text2"); writer.Write('c'); writer.Write(true); writer.Write(123); writer.Write(456f); writer.Write(789d); writer.Write("end".AsMemory()); writer.WriteLine(); var expected = "text1text2cTrue123456789end" + Environment.NewLine; Assert.Equal(expected, writer.ToString()); } }
public ContentItemType(IOptions <GraphQLContentOptions> optionsAccessor) { _options = optionsAccessor.Value; Name = "ContentItemType"; Field(ci => ci.ContentItemId).Description("Content item id"); Field(ci => ci.ContentItemVersionId).Description("The content item version id"); Field(ci => ci.ContentType).Description("Type of content"); Field(ci => ci.DisplayText, nullable: true).Description("The display text of the content item"); Field(ci => ci.Published).Description("Is the published version"); Field(ci => ci.Latest).Description("Is the latest version"); Field <DateTimeGraphType>("modifiedUtc", resolve: ci => ci.Source.ModifiedUtc, description: "The date and time of modification"); Field <DateTimeGraphType>("publishedUtc", resolve: ci => ci.Source.PublishedUtc, description: "The date and time of publication"); Field <DateTimeGraphType>("createdUtc", resolve: ci => ci.Source.CreatedUtc, description: "The date and time of creation"); Field(ci => ci.Owner).Description("The owner of the content item"); Field(ci => ci.Author).Description("The author of the content item"); Field <StringGraphType, string>() .Name("render") .ResolveLockedAsync(async context => { var userContext = (GraphQLContext)context.UserContext; var serviceProvider = userContext.ServiceProvider; // Build shape var displayManager = serviceProvider.GetRequiredService <IContentItemDisplayManager>(); var updateModelAccessor = serviceProvider.GetRequiredService <IUpdateModelAccessor>(); var model = await displayManager.BuildDisplayAsync(context.Source, updateModelAccessor.ModelUpdater); var displayHelper = serviceProvider.GetRequiredService <IDisplayHelper>(); var htmlEncoder = serviceProvider.GetRequiredService <HtmlEncoder>(); using var sw = new ZStringWriter(); var htmlContent = await displayHelper.ShapeExecuteAsync(model); htmlContent.WriteTo(sw, htmlEncoder); return(sw.ToString()); }); Interface <ContentItemInterface>(); IsTypeOf = IsContentType; }
public async Task ExecuteAsync(RecipeExecutionContext context) { if (!String.Equals(context.Name, "Command", StringComparison.OrdinalIgnoreCase)) { return; } var step = context.Step.ToObject <CommandStepModel>(); foreach (var command in step.Commands) { using (var output = new ZStringWriter()) { _logger.LogInformation("Executing command: {Command}", command); var commandParameters = _commandParameterParser.Parse(_commandParser.Parse(command)); commandParameters.Output = output; await _commandManager.ExecuteAsync(commandParameters); _logger.LogInformation("Command executed with output: {CommandOutput}", output); } _logger.LogInformation("Executed command: {Command}", command); } }
public async Task DisplayedAsync(ShapeDisplayContext context) { var cacheContext = context.Shape.Metadata.Cache(); // If the shape is not configured to be cached, continue as usual if (cacheContext == null) { if (context.ChildContent == null) { context.ChildContent = HtmlString.Empty; } return; } // If we have got this far, then this shape is configured to be cached. // We need to determine whether or not the ChildContent of this shape was retrieved from the cache by the DisplayingAsync method above, as opposed to generated by the View Engine. // ChildContent will be generated by the View Engine if it was not available in the cache when we rendered the shape. // In this instance, we need insert the ChildContent into the cache so that subsequent attempt to render this shape can take advantage of the cached content. // If the ChildContent was retrieved form the cache, then the Cache Context will be present in the _cached collection (see the DisplayingAsync method in this class). // So, if the cache context is not present in the _cached collection, we need to insert the ChildContent value into the cache: if (!_cached.ContainsKey(cacheContext.CacheId) && context.ChildContent != null) { // The content is pre-encoded in the cache so we don't have to do it every time it's rendered using var sw = new ZStringWriter(); // 'ChildContent' may be a 'ViewBufferTextWriterContent' on which we can't // call 'WriteTo()' twice, so here we update it with a new 'HtmlString()'. context.ChildContent.WriteTo(sw, _htmlEncoder); var contentHtmlString = new HtmlString(sw.ToString()); context.ChildContent = contentHtmlString; await _dynamicCacheService.SetCachedValueAsync(cacheContext, contentHtmlString.Value); } }
public async Task <IHtmlContent> ProcessContentAsync(TagHelperOutput output, CacheContext cacheContext) { IHtmlContent content = null; while (content == null) { Task <IHtmlContent> result; // Is there any request already processing the value? if (!_dynamicCacheTagHelperService.Workers.TryGetValue(CacheId, out result)) { // There is a small race condition here between TryGetValue and TryAdd that might cause the // content to be computed more than once. We don't care about this race as the probability of // happening is very small and the impact is not critical. var tcs = new TaskCompletionSource <IHtmlContent>(); _dynamicCacheTagHelperService.Workers.TryAdd(CacheId, tcs.Task); try { var value = await _dynamicCacheService.GetCachedValueAsync(cacheContext); if (value == null) { // The value is not cached, we need to render the tag helper output var processedContent = await output.GetChildContentAsync(); using var writer = new ZStringWriter(); // Write the start of a cache debug block. if (_cacheOptions.DebugMode) { // No need to optimize this code as it will be used for debugging purpose. writer.WriteLine(); writer.WriteLine($"<!-- CACHE BLOCK: {cacheContext.CacheId} ({Guid.NewGuid()})"); writer.WriteLine($" VARY BY: {String.Join(", ", cacheContext.Contexts)}"); writer.WriteLine($" DEPENDENCIES: {String.Join(", ", cacheContext.Tags)}"); writer.WriteLine($" EXPIRES ON: {cacheContext.ExpiresOn}"); writer.WriteLine($" EXPIRES AFTER: {cacheContext.ExpiresAfter}"); writer.WriteLine($" EXPIRES SLIDING: {cacheContext.ExpiresSliding}"); writer.WriteLine("-->"); } // Always write the content regardless of debug mode. processedContent.WriteTo(writer, HtmlEncoder); // Write the end of a cache debug block. if (_cacheOptions.DebugMode) { writer.WriteLine(); writer.WriteLine($"<!-- END CACHE BLOCK: {cacheContext.CacheId} -->"); } await writer.FlushAsync(); var html = writer.ToString(); var formattingContext = new DistributedCacheTagHelperFormattingContext { Html = new HtmlString(html) }; await _dynamicCacheService.SetCachedValueAsync(cacheContext, html); content = formattingContext.Html; } else { content = new HtmlString(value); } } catch { content = null; throw; } finally { // Remove the worker task before setting the result. // If the result is null, other threads would potentially // acquire it otherwise. _dynamicCacheTagHelperService.Workers.TryRemove(CacheId, out result); // Notify all other awaiters to render the content tcs.TrySetResult(content); } } else { content = await result; } } return(content); }
static async ValueTask <FluidValue> Awaited(Task <IHtmlContent> task) { using var writer = new ZStringWriter(); (await task).WriteTo(writer, NullHtmlEncoder.Default); return(new StringValue(writer.ToString(), false)); }