(MVC) MVC (2021)

AuctionClient site future

This was a my huge job in 2021 year. Some Ukrainian company buy site/project from another company and I was hired to repair project, rebuild frontend of old project and expand functions of old project. Below is initial state of this site. In purchase moment site don't working correctly, even login and registration to purchased site need to do in another site.

And this site has about 3,000 various JS scripts.

Below you can something key future of this my job. Common environment of this site ASP.NET Classic and jQuery.

1. Unlock ASP.NET.

Firstly this site so named "ASP.NET Classic" has full blocked ASP.NET. This was possible because tag FORMS was be placed outside site content. As you can see below tab form was be placed in line 75, however all content was be placed in line 196, so ASP.NET was be full blocked in this site.

Another way to block ASP.NET was a create one dummy server page and all WebForm use this empty server page.

Unlock ASP.NET allow me use ordinary ASP.NET server technology instead JavaScript only. However ASP.NET has big trouble in this site and I need more efforts to restore normal ASP.NET workflow without JavaScript at all.

Extremely simple solution,

and with full intellisense, of course.

And this is replacement of read huge JSON file from server and than replace template to real data from server JSON.

2. Replace jQuery Post to jQuery Get.

All EST API in this site, even a simple one value, was use jQuery POST, of course this not be working in ASP.NET because ASP.NET use Post request.

3. WebMethod - native alternatives of Jquery Get/Post and REST API in Classic ASP.NET.

At common, best and natural way in Classic ASP.NET is using WebMethod. Read more about WebMethod in this page - SPA-page на Classic ASP.NET та jQuery.

4. Create ASP.NET Postback by own code.

Unfortunately, when I turn on ASP.NET, it still don't working in all WebForms. Some WebForms has a thousands INPUT fields,

as I understand this is too match for ASP.NET. I try to use various options in WebForm_DoPostBackWithOptions, but failed.

My finally solution is collect parameters manually by this way (I need 5 Postbask in this huge form).

 120:          function ProposalPostback() {
 121:              $.ajax({
 122:                  type: 'POST',
 123:                  url: '/PositionForm.aspx',
 124:                  data: {
 125:                      '__EVENTTARGET': 'btnProposal',
 126:                      'jGetPositionDebug': $('#jGetPositionDebug').val(),
 127:                      'curUserDebug': $('#curUserDebug').val(),
 128:                      'PMTDebug': $('#PMTDebug').val(),
 129:                      'PMTMetaDebug': $('#PMTMetaDebug').val(),
 130:                      'PMTSchemaDebug': $('#PMTSchemaDebug').val(),
 131:                      'StatusDebug': $('#StatusDebug').val()
 132:                  },
 133:                  success: function (ret) {
 134:                      if (ret != "") {
 135:                          location = ret;
 136:                      }
 137:                  }
 138:              }
 139:              )
 140:          }

And than handles postback parameters correctly in server side and create redirect with correct parameters.

5. Cancel bubbling.

In fact, to make ASP.NET workable, we can finist each JS-function with the same ritual.

   459:      if (!e) var e = window.event;
   460:      e.stopPropagation();
   461:      e.cancelBubble = true;
   462:      e.returnValue = false;
   463:      return false;

6. Move JavaScript string to server.

All of this site was made as jQuery widget.

This make impossible to change any HTML-markup stored as JavaScript-string.

So. to make possible changing HTML-markup I prepared HTML-template like this

and prepare handlers like this

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Web;
   6:  namespace UUEfgv.Handlers
   7:  {
   8:      public class GetOrganizationTemplate : IHttpHandler
   9:      {
  10:          public void ProcessRequest(HttpContext context)
  11:          {
  12:              context.Response.ContentType = "text/html";
  13:              try
  14:              {
  15:                  string PrefixId = context.Request.QueryString["PrefixId"];
  16:                  string Name = context.Request.QueryString["Name"];
  17:                  string Title = context.Request.QueryString["Title"];
  19:                  string Base = HttpContext.Current.Server.MapPath("~/");
  20:                  string HTML = System.IO.File.ReadAllText(System.IO.Path.Combine(Base, "OrganizationTemplate.html"));
  21:                  string Res1 = HTML.Replace("@", PrefixId).Replace("$", Name).Replace("~", Title);
  22:                  context.Response.Write(Res1);
  23:              }
  24:              catch (Exception ex)
  25:              {
  26:                  context.Response.Write(ex.Message);
  27:              }
  28:          }
  29:          public bool IsReusable
  30:          {
  31:              get
  32:              {
  33:                  return false;
  34:              }
  35:          }
  36:      }
  37:  }

I have reading this HTML-template from server by my handler and this allow me changing HTML-markup by simple way.

7. Emulate ASP.NET MVC in ASP.NET Classic.

This is also simplest way to emulate ASP.NET MVC in ASP.NET Classic.

   1:  <script type="text/javascript">
   2:      $.ajax({
   3:          type: "GET",
   4:          url: "/Handlers/GetControl.ashx",
   5:          data: {
   6:              Filter: "Status", //"Status","KeyWord","AuctionType","Region","Seller","LotNumber","AuctionDate","Price","PropertyType"
   7:              id: 1
   8:          },
   9:          dataType: "Html",
  10:          success: function (response) {
  11:              var SF = $("#pnFilterContent");
  12:              SF.append(response);
  13:          }
  14:      });
  15:  </script>

8. Style changing inside JS.

Unfortunately, this is not solve app problem, that site has about 3,000 various scripts, most of is was huge, more than 5,000 line of code and each scripts always manipulate design and HTML DOM model.

9. Create dynamic SQL request without LINQ.

This site don't use LINQ. It create SQL request dynamically, and request string was huge, hundreds of SQL lines.

To allow using REST API from server code I split huge API layer (with thousands code line in one function) to many layer - semantic layer and layer to push parameters from Request, and other service function. For example in this screen - external function GetPosition start in line 560. Internal function for build SQL string for SQL-request start on line 696.

This solution allow me to call existing REST API from server.

Also, because database of this project was unstable and has low performance I add to this project test JSON to debug this site.

10. Various YML (JSON Schema) with dynamic changing nodes.

All site and database based was on JSON.

JSON was different types and I have to classify YML and JSON-types.

And even each nodes in particular JSON-types and each attributes was optional, not mandatory.

So, even I have rebuild this code to ASP.NET I have to processing each JSON type separately and each time check if node is exist.

Also, after recognizing JSON-type I add debug panel with download current YML.

However ASP.NET allow directly use on WebForm function from code behind and this ASP.NET future allow me create a lot of various function in codebehind and parse JSON correctly.

11. Authentication with sessionId stored in DB.

Site stored all SessionID to database and create user authentication not by ordinary way (cookies), and detect UserID by database. Also site used temporary sessionID to Database for anonymous user.

This decision create huge problem to site performance.

12. Store data in Cookies instead database (js.cookie.js).

I have replaced workflow (AJAX request to server than request to SQL-server, than response to JavaScript and processing response by JavaScript in one place - HandleViewForm) to normal workflow - simple store data to cookie.

For this goal I have add to project https://github.com/js-cookie/js-cookie

I use this library in many case, firstly to set up authentication cookie and check authentication cookie in client side.

   1:  <script type="text/javascript">
   2:      function checkAu(e, auId) {
   3:          //alert(e.id + "\n" + auId);
   4:          if (typeof Cookies.get("Login") != "undefined") {
   5:              ShowFrame("auction/" + auId);
   6:          }
   7:          else {
   8:              ShowFrame("Login.aspx");
   9:          }
  10:          if (!x) var x = window.event;
  11:          x.cancelBubble = true;
  12:          if (x.stopPropagation) x.stopPropagation();
  13:          return false;
  14:      }
  15:  </script>

Secondary, I use this library to add a favorite item, before my refactoring this function is working only through server instead cookie as I mention.

   1:  <script type="text/javascript">
   2:  function AddToFavorite(AucId) {
   3:      var FavArr = Cookies.get("Favorite");
   4:      if (FavArr == null && typeof FavArr == "undefined") {
   5:          Cookies.set('Favorite', AucId + ",");
   6:      }
   7:      else {
   8:          let Arr1 = FavArr.split(",");
   9:          for (i = 0; i < Arr1.length; i++) {
  10:              if (Arr1[i] == AucId) {
  11:                  return;
  12:              }
  13:          }
  14:          Cookies.set('Favorite', FavArr + AucId + ",");
  15:      }
  16:  }
  17:  function ArrIsNotEmpty(value) {
  18:      if (value == null && typeof value == "undefined") {
  19:          return false;
  20:      }
  21:      else if (value == "") {
  22:          return false;
  23:      }
  24:      else {
  25:          return true;
  26:      }
  27:  }
  28:  function RemoveFromFavorite(AucId) {
  29:      var FavArr = Cookies.get("Favorite");
  30:      if (!(FavArr == null && typeof FavArr == "undefined")) {
  31:          let Arr1 = FavArr.split(",");
  32:          for (i = 0; i < Arr1.length; i++) {
  33:              if (Arr1[i] == AucId) {
  34:                  delete Arr1[i];
  35:                  if (Arr1.filter(ArrIsNotEmpty).length == 0) {
  36:                      Cookies.remove("Favorite")
  37:                  }
  38:                  else {
  39:                      Cookies.set('Favorite', Arr1.filter(ArrIsNotEmpty).toString() + ",");
  40:                  }
  41:              }
  42:          }
  43:      }
  44:  }
  45:  </script>

And many other case.

13. ContactForm - Div with Fixed CSS position.

In this site customer want to add some of HTML element with Fixed CSS position and Absolute CSS position from bottom. Pay attention that Fixed DIV has only left,top,right,bottom position and no more. And fixed position is not scrollable, however Absolute position is alvays scrollable.

14. Header - Div with Fixed CSS position, fadeIn/fadeOut jQuery effect and Z-index.

Second interesting HTML-element was Header - with fadeIn/fadeOut jQuery effect, fixed CSS position, Z-index CSS and many other future. This is full code of Header control - Header.htm.

FadeIn/fadeOut jQuery effect I have to add because Bootsrap data-toggle="tooltip" data-html="true" does not fit to customer requirements. Third method of dropdown menu you can see in IconSlider - Div with Scrolling Icon, overflow:hidden CSS and complex button with fall out menu.

15. Footer - Div with color changing from server and Generic function depends from MasterPage hierarchy.

This is a way to setup header from various page. Pay attention why generic in this function is have to - because page can be incuded in different level of MasterPage.

   1:  namespace UUEfgv
   2:  {
   3:      public class Common
   4:      {
   5:          public static void SetFooterWhite<T>(T Me) where T : System.Web.UI.Page
   6:          {
   7:              var ClosestMaster = Me.Page.Controls[0];
   8:              SiteMaster siteMaster = null;
  10:              if (Me.Page.Controls[0].GetType().Name == "member_master")
  11:              {
  12:                  siteMaster = (SiteMaster)ClosestMaster.Controls[0];
  13:              }
  14:              else if (Me.Page.Controls[0].GetType().Name == "site_master")
  15:              {
  16:                  siteMaster = (SiteMaster)ClosestMaster;
  18:              }
  20:              var Footer = (Footer)siteMaster.FindControl("Footer1");
  21:              Footer.FooterBgColor = "#ffffff";
  22:          }
  23:      }
  24:  }

   1:  using System;
   3:  namespace UUEfgv
   4:  {
   5:      public partial class Footer : System.Web.UI.UserControl
   6:      {
   8:          public string FooterBgColor
   9:          {
  10:              get { return (string)ViewState["FooterBgColor"]; }
  11:              set { ViewState["FooterBgColor"] = value; }
  12:          }
  14:          protected void Page_Load(object sender, EventArgs e)
  15:          {
  16:              if (!IsPostBack) {
  17:                  if (FooterBgColor == null) FooterBgColor = "white";
  18:              }
  19:          }
  20:      }
  21:  }

   1:  <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="~/Controls/Footer.ascx.cs" Inherits="UUEfgv.Footer" %>
   3:  <footer class="container-fluid bg-light justify-content-center">
   4:      <div class="row justify-content-center" style="background-color:<%: FooterBgColor %>">
   5:          <div class="row col-12" style="max-width: 75%;">
  27:  </footer>

This methow allow changing color from server without thinking about MasterPage, alternative method is jQuery.

16. LeftMenu - Div with state stored by js.cookie.js, Fixed CSS position, button with Absolute CSS pos from bottom, Z-index and control from Web.Config.

This is main code of my LeftMenu - LeftMenu.htm. Most interesting in this code is CSS I have developed.

17. IconSlider - Div with Scrolling Icon, overflow:hidden CSS and complex button with fall out menu.

This is main code of my IconSlider - IconSlider.htm. Most interesting in this code is CSS I have developed and JS-scripts.

18. Fit various Div to one/two column with different width and Various TabControl Div.

Site contais a lot of other interesting HTML future, I do not describe it, for example various TabControl and various DIV with different width fit to one or two column. Alternative method to create two colunm is server mode Compress data to multiple columns table.

19. SqlFormatter script.

As I mention before Create dynamic SQL request without LINQ., this site create SQL request with dozens lines depends on filters. Therefore site debugging is impossible without checking SQL.

So, I have installed SQL formatter script from there https://www.npmjs.com/package/sql-formatter. (Function exported from sql-formatter by webpack).

Than I pass SQL request string to JSON returning to page.

And createded debug panel activated from Web.Config.

So, when AjaxDone (if dubugging require in web.config) function ShowDebugInfo is calling. And preformated field iSqlRequest in control SqlAndRequestDebugPanel can be formatted by sql-formatter script.

Try to compare formatted and unformatted view of SQL request in the screen above!

20. JsonFormatter script.

As I mention before Various YML (JSON Schema) with dynamic changing nodes this site use different JSON as show auction data and for create new auction. This JSON has many types and has no mandatory nodes. So, debugging that site is difficult therefore I add show current JSON we show/create on each forms.

So, for this purposes I use https://github.com/MHeironimus/jsonFormatter. I define hidden field jGetPositionDebug (line 303) and store Json string to jGetPositionDebug.Value (line 137), rebuild JSON to native JS format by jQuery.parseJSON/JSON.stringify than store JS Json to line 5805 and than format it by script jsonFormatter.min.js.

ASP.NET variable PosHiddenField I use to show data from this JSON.

21. Add Static Google Map.

This is static (fixed) Google map. This map need to create once than simple upload this point to site.

In Html this is only one iframe.

And all we need is uploading needed point to Google. This is workflow to uploading.

22. Add Google Map dynamically.

To show GoogleMap dynamically from DB

we need to add library (anonymously or with personal key).

Than perform Google script.

23. Google Font Awesome Icon.

This site use a couple of Google Font/Icon technology. Firstly site use ordinary font like

<link href='https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,300,400,700' rel='stylesheet' type='text/css'>

that finally downloaded from Google:


And secondary all site use FontAweson Icon https://fontawesome.com/v5.15/how-to-use/on-the-web/setup/hosting-font-awesome-yourself. Therefore I simple write in any place :

<i class="fa fa-fw fa-home" style="margin-right: 10px;"></i>

And Google script replace this mnemonic to real SVG path:

24. Custom Svg Icon.

In some case we need to embed SVG icon directly to HTML. for example if we want to protect company logo from unauthorized changing company logo in external file. In this case we need to open SVG file by notepad and directly embed SVG to site HTML.

We can automatically resize SVG directly in HTML, however if we need more deep handle of Icon we can handle it by Inkscape.

25. Checkbox.

Browser has a couple of HTML-element can not changing be CSS styles. Checkbox is one of them. However site designer draw crazy-style checkbox and customer require to realize it in frontend. To fit crazy design programmer need to realize custom checkbox from span or div.

This is my way to hide real checkbox (< input type="checkbox" >) and draw above it something from div/span have to fit designer fantasy.

   1:      <style>
   2:          .checkboxcontainer {
   3:              display: block;
   4:              position: relative;
   5:              padding-left: 35px;
   6:              margin-bottom: 12px;
   7:              cursor: pointer;
   8:              font-size: 1em;
   9:              -webkit-user-select: none;
  10:              -moz-user-select: none;
  11:              -ms-user-select: none;
  12:              user-select: none;
  13:          }
  16:          /* Hide the browser's default checkbox */
  17:          .checkboxcontainer input {
  18:              position: absolute;
  19:              opacity: 0;
  20:              cursor: pointer;
  21:              height: 0;
  22:              width: 0;
  23:              visibility: hidden !important;
  24:          }
  26:          /* Create a custom checkbox */
  27:          .dark-checkbox {
  28:              display: inline-block;
  29:              background-color: #002B4E !important;
  30:              color: white;
  31:              height: 14px;
  32:              width: 14px;
  33:              background-color: #fff;
  34:              border: 2px black solid;
  35:          }
  37:          /* On mouse-over, add a grey background color */
  38:          .checkboxcontainer:hover input ~ .dark-checkbox {
  39:              background-color: #ccc;
  40:          }
  42:          /* When the checkbox is checked, add a blue background */
  43:          .checkboxcontainer input:checked ~ .dark-checkbox {
  44:              background-color: #002B4E;
  45:          }
  47:          /* Create the dark-checkbox/indicator (hidden when not checked) */
  48:          .dark-checkbox:after {
  49:              content: "";
  50:              background-color: #002B4E;
  51:              display: none;
  52:          }
  54:          /* Show the dark-checkbox when checked */
  55:          .checkboxcontainer input:checked ~ .dark-checkbox:after {
  56:              display: block;
  57:          }
  59:          /* Style the dark-checkbox/indicator */
  60:          .checkboxcontainer .dark-checkbox:after {
  61:              left: 6px;
  62:              top: 3px;
  63:              width: 5px;
  64:              height: 8px;
  65:              border: solid white;
  66:              border-width: 0 2px 2px 0;
  67:              -webkit-transform: rotate(35deg);
  68:              -ms-transform: rotate(35deg);
  69:              transform: rotate(35deg);
  70:          }
  71:      </style>

26. UploadButton.

This site uses script https://github.com/andreyfedoseev/jquery-ocupload to upload documents with additional document parameters as type, date and so on. This script use interesting technic to mask real browser upload button to another button <input type=submit>.

This is sohisticated and complex technique - more advanced as technique in previous point Checkbox. In the screen below I'm unhide real Browse button and colorize it as red color.

With ASP.NET this script working only out of main ASP.NET <Form tag. Its possible this option made nessesary block ASP.NET in first developers of this site Unlock ASP.NET..

I have to a little bit rebuilded this strong script to make it workable in my project.

Uploader widget allow a number of additional parameters for uploaded file.

This script has a couple of event handlers (onSubmit, onComplete, onError, onSelect, params, options) created strong workflow to upload documents. In my case these event handlers has more than 500 lines of JS-code.

27. Custom Image slider.

This site has cool image slider before I start working.

However designer decide to full change idea of existing ImageSlider and I need full especially rewrite slider and all closure around it.

Result is fine, designer and customer was satisfied.

28. Different site view in different browser.

Professional developers very ofter faced with different site vire in different Browsers. In the screen below you can see typical issue. Button of my custom IconSlider working perfectly in Firefox but control button don't showing in Chrme at all.

In this case I have fix this issue by this way:

29. Various JS questions.

30. Bootsrtap main css-class I used in this project.

31. Changing in SQL server.

This site has broken SQL Layer and I need to develop new SQL procedures, for example:

32. Debugging and Test zone.

For test zone I have installed server and wirking with it by VPN.

Some future was be different with my developer computer I need to install remote debugger.

Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21>  <22>  <23
Link to this page: http://www.vb-net.com/ProzorroFuture/Index.htm