This approach does not parse html like php, razer, but generates markup on the fly. That affects very well on performance. Does this approach have a place to be? After all, if you write everything in this, for me, so comfortable style, as far as I understand you can fly to StackOverflow

Page Code

public AdminLoginPageWrong() { Add( new HeadTag { new MetaTag(new NameAtt("description"), new ContentAtt("Вход в админ панель")), new MetaTag(new NameAtt("author"), new ContentAtt("Alay")), new MetaTag(new NameAtt("viewport"), new ContentAtt("width=device-width, initial-scale=1.0")), new TitleTag{new Svt("Вход в админ панель") }, //new BaseTag(new HrefAtt("http://localhost:8080/")) }, new BodyTag(new ClassAtt("gray-bg")) { new DivTag(new ClassAtt("middle-box text-center loginscreen animated fadeInDown")) { new DivTag { new DivTag().Add(new H2Tag(new ClassAtt("logo-name")).Add(new Svt("WGS"))) }, new H3Tag().Add(new Svt("Добро пожаловать на форму авторизации администратора WGS")), new PTag { new Svt("WGS - Лучшая CMS полностью написаная на C# без использования .net asp."), new BrTag(), new Svt("Скорость реакции в десятки раз превосходит остальные веб серверы и сам asp"), }, new PTag().Add(new Svt("Авторизуйтесь, чтобы пороникнуться возможностями WGS")), new DivTag(new ClassAtt("alert alert-danger")) { new Svt("Пользователь или пароль не верны.") }, new FormTag(new ClassAtt("mt"), new RoleAtt(RoleAtt.Mark.Form), new MethodAtt(MethodAtt.Mark.Post), new ActionAtt("adminAuth")) { new DivTag(_classFormGroup) { new InputTag(new NameAtt("login"), new InputTypeAtt(InputTypeAtt.Mark.Email), _classFormControl, new PlaceHolderAtt("Login"), new RequiredAtt()) }, new DivTag(_classFormGroup) { new InputTag(new NameAtt("pass"), new InputTypeAtt(InputTypeAtt.Mark.Password), _classFormControl, new PlaceHolderAtt("Pwd"), new RequiredAtt()) }, new ButtonTag(new InputTypeAtt(InputTypeAtt.Mark.Submit), new ClassAtt("btn btn-primary block full-width mb")).Add(new Svt("Вход")) }, new PTag(new ClassAtt("mt")).Add(new SmalTag().Add(new Svt("WGS - World Global Sharper based on Bootstrap 3 and .net framework 4.6.1 © 2017"))) }, new LinkTag(new RelAtt("stylesheet"), new HrefAtt("admin/css/bootstrap.min.css")), new LinkTag(new RelAtt("stylesheet"), new HrefAtt("admin/font-awesome/css/font-awesome.min.css")), new LinkTag(new RelAtt("stylesheet"), new HrefAtt("admin/css/animate.css")), new LinkTag(new RelAtt("stylesheet"), new HrefAtt("admin/css/style.css")), new ScriptTag(new SrcAtt("admin/js/jquery-3.1.1.min.js")), new ScriptTag(new SrcAtt("admin/js/bootstrap.min.js"), new AsyncAtt()) } ); Render(null); } 

Abstract tag code

  private bool _isRendered; private string _data; private readonly string _name; private readonly List<AbstractAtt> _attributes; private readonly List<IHtmlRendable> _innerTags; private readonly bool _needToBeClosed; private readonly bool _hasAttributes; private bool _hasInnerTags; public delegate IHtmlRendable[] EntryFunc(); protected AbstractTag(string name, bool needToBeClosed, params AbstractAtt[] attributes) { _name = name; _needToBeClosed = needToBeClosed; _attributes = new List<AbstractAtt>(attributes); _innerTags = new List<IHtmlRendable>(); if (attributes.Length > 0) _hasAttributes = true; } public IHtmlRendable Add(params IHtmlRendable[] tags) { if (!_needToBeClosed) return this;//Если тег не закрывающийся, то и контент в него добавить нельзя. _innerTags.AddRange(tags); _hasInnerTags = true; return this; } public IHtmlRendable Add(EntryFunc func) { if (!_needToBeClosed) return this;//Если тег не закрывающийся, то и контент в него добавить нельзя. _innerTags.AddRange(func()); _hasInnerTags = true; return this; } public void Render(StringBuilder sb) { if (!_isRendered) { var enterPoint = sb.Length; sb.Append("<").Append(_name); if (_hasAttributes) { sb.Append(" "); foreach (var att in _attributes) { att.Render(sb); sb.Append(" "); } sb.Remove(sb.Length - 1, 1); //Удаляем последний пробел } if (!_needToBeClosed && !_hasInnerTags) { sb.Append("/>"); } else { sb.Append(">"); foreach (var tag in _innerTags) tag.Render(sb); sb.Append("</").Append(_name).Append(">"); } var exitPoint = sb.Length; var length = exitPoint - enterPoint; _data = sb.ToString(enterPoint, length); _isRendered = true; } else sb.Append(_data); } public IEnumerator<IHtmlRendable> GetEnumerator() => _innerTags.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => _innerTags.GetEnumerator(); 

Abstract attribute

  protected AbstractAtt(string name, string value) { _name = name; _value = value; _hasValue = true; } protected AbstractAtt(string name) { _name = name; } public void Render(StringBuilder sb) { if (_hasValue) sb.Append(_name).Append("=\"").Append(_value).Append("\""); else sb.Append(_name); } 

Well, the whole thing turns into Html rendered

  • one
    And you are not looking for easy ways :) - MihailPw
  • To get overflow, you need to 1. find out the size of your stack. 2. find out the size of the data you want to put on the stack. Most likely, you can hardly fill it up so easily, except that you will have more than 1000 objects per call. The stack is considered approximately by the number of arguments in one procedure, where the reference to the object is 4 or 8 bytes. - nick_n_a
  • Stack overflow can be caused by 1. looped recursion (there is no such thing here). 2. If you are in depth (in this example in width) you call several procedures / functions with a large amount of parameters (or structures without a link / pointer are used as a parameter) or similar local variables. I don’t know if this happens with c # because the required stack size is known in advance when calling a function, and the VM can afford to take more space under the stack, i.e. 1-2 Gb. You do not go to these numbers. - nick_n_a
  • My recursion of x86 to 50000 int skips. 100 000 no, it says that you should have more than 50 000 parameters with stack variables and other offal, what would call Stackoverflow. - nick_n_a
  • Thank you for the answers. I will continue to develop in this direction. - Gregory Novikov

0