/// <summary> /// Checks that the content page does not contain invalid content. /// </summary> private List <Content> GetChildPageContents(DotvvmView childPage, List <ContentPlaceHolder> parentPlaceHolders) { // make sure that the body contains only whitespace and Content controls var nonContentElements = childPage.Children.Where(c => !((c is RawLiteral && ((RawLiteral)c).IsWhitespace) || (c is Content))); if (nonContentElements.Any()) { // show all error lines var innerExceptions = nonContentElements.Select(s => new Exception($"Error occurred near line: {(s.GetValue(Internal.MarkupLineNumberProperty)?.ToString() ?? "")}.")).ToList(); // the message cannot be specifically to the line, because MarkupLineNumber shows the last character position which is a line under the error in some cases. var corruptedFile = childPage.GetValue(Internal.MarkupFileNameProperty)?.ToString(); throw new AggregateException("If the page contains @masterpage directive, it can only contain white space and <dot:Content /> controls! \r\n" + (string.IsNullOrWhiteSpace(corruptedFile) ? "" : $"Corrupted file name: {corruptedFile}"), innerExceptions); } // make sure that the Content controls are not nested in other elements var contents = childPage.GetAllDescendants().OfType <Content>() .Where(c => !(bool)c.GetValue(Internal.IsMasterPageCompositionFinishedProperty)) .ToList(); if (contents.Any(c => c.Parent != childPage)) { throw new Exception("The control <dot:Content /> cannot be placed inside any control!"); // TODO: exception handling } return(contents); }
/// <summary> /// If the request is SPA request, we need to verify that the page contains the same SpaContentPlaceHolder. /// Also we need to check that the placeholder is the same. /// </summary> protected void VerifySpaRequest(IDotvvmRequestContext context, DotvvmView page) { if (context.IsSpaRequest) { var spaContentPlaceHolders = page.GetAllDescendants().OfType <SpaContentPlaceHolder>().ToList(); if (spaContentPlaceHolders.Count > 1) { throw new Exception("Multiple controls of type <dot:SpaContentPlaceHolder /> found on the page! This control can be used only once!"); // TODO: exception handling } if (spaContentPlaceHolders.Count == 0 || spaContentPlaceHolders[0].GetSpaContentPlaceHolderUniqueId() != context.GetSpaContentPlaceHolderUniqueId()) { // the client has loaded different page which does not contain current SpaContentPlaceHolder - he needs to be redirected context.RedirectToUrl(context.HttpContext.Request.Url.AbsoluteUri.Replace("/" + HostingConstants.SpaUrlIdentifier, "")); } } }
/// <summary> /// Checks that the content page does not contain invalid content. /// </summary> private List <Content> GetChildPageContents(DotvvmView childPage, List <ContentPlaceHolder> parentPlaceHolders) { // make sure that the body contains only whitespace and Content controls if (!childPage.Children.All(c => (c is RawLiteral && ((RawLiteral)c).IsWhitespace) || (c is Content))) { throw new Exception("If the page contains @masterpage directive, it can only contain white space and <dot:Content /> controls!"); // TODO: exception handling } // make sure that the Content controls are not nested in other elements var contents = childPage.GetAllDescendants().OfType <Content>() .Where(c => !(bool)c.GetValue(Internal.IsMasterPageCompositionFinishedProperty)) .ToList(); if (contents.Any(c => c.Parent != childPage)) { throw new Exception("The control <dot:Content /> cannot be placed inside any control!"); // TODO: exception handling } return(contents); }