Czego nauczyłem się w 19 tygodniu pracy?

W tym tygodniu było trochę problemów z kodowaniem(Angular 7, ASP .NET Core) i trochę nauki z narzędziami(KeePass)

Hosting bez obsługi DELETE i innyh

Do swoich asp .net „pet project” używam hostingu na webio.pl. Za 135zł rocznie można mieć dostęp do dobrze działającego hostingu (asp .net, asp .net core, ms sql) z w miarę szybką pomocą w razie problemów. Nie jest to co prawda tak fajne jak w nazwa.pl ale o wiele tańsze.

Stworzyłem pewne api w asp .net core i gdy włączyłem możliwość obsługi CORS. POST-y i GET-y oczywiście mogłem zrobić i działały super. Jednak gdy doszedłem do DELETE to okazało się, że:

  • ASP .NET 2.1 nie wspiera obsługi żądań OPTIONS z automatu (czyli nie generuje ich odpowiedzi automatycznie)
  • Angular 7 (właściwie to przeglądarka) podczas wysłania żądania DELETE najpierw robi żądanie typu OPTIONS (preflight) a potem DELETE.

Te dwie rzeczy sprawiły, że w żadnej sposób kombinując z middleware do obsługi CORS nie mogłem przejść przez problem wykonania DELETE-a. W końcu jednak się udało:

  • Aktualizacja ASP .NET do wersji 2.2 wtedy żądanie OPTIONS zaczęło działać z automatu (jednak i tak zwracało tylko GET)
  • Mail do supportu hostingu o to dlaczego to nie działa. Okazało się, że oni po swojej stronie wyłączali opcję żądań innych niż POST i GET. Po wykonaniu tej instrukcji, wszystko zaczęło śmigać.
  • Ostateczna wersja po stronie backend-u poniżej:
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
       
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            
            app.UseCors(builder =>  
            {
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            });

            app.UseMvc();
        }

Pisze o tym aby pamiętać, że gdy coś dziwnego się dzieje z konfiguracją a jesteśmy pewni, że u Nas jest ok. to pewnie tak właśnie jest, że my mamy ok. a coś nawala trzecia strona, która może coś popsuć czyli hosting i jego konfiguracja w tym przypadku.

Angular 7 – atrybut hidden

Prosta rzecz a cieszy. Gdy chcemy jakiś element na stronie ukryć i sterować tym ukryciem z poziomu componentu to możemy zrobić „data-binding” z użyciem atrybutu hidden. Wygląda to tak:

<div *ngFor="let item of Favorites" class="text-center"  [hidden]="item.isDeleted">

W nawiasach kwadratowych wpisujemy hidden i parametr. Jak łatwo się domyślić przyjmuje wartość true/false. Po stronie komponentu możemy już sterować przypisaną zmienną w tym przypadku „item.isDeleted”.

Może też użyć polecenia *ngIf:

<div *ngFor="let item of Favorites" class="text-center"  *ngIf="item.isDeleted">

KeePass – auto complete

Używam KeePass-a i jego funkcjonalności do automatycznego wpisywania haseł do okienek itd. Ostatnio dowiedziałem się, że istnieje taka opcja jak {DELAY czas}. Czyli KeePass czeka jakiś czas w milisekundach jak coś się stanie i po tym czasie kontynuuje sekwencje klawiszy.

Dodatkowo okazało się, że jeśli okienko, gdzie wpisujemy hasło, otwiera jakiś inne okienko ,to wtedy gdy fokus po otwarciu tego drugiego okienka jest na tym okienku to możemy kontynuować sekwencje. To pozwala na przechodzenie pomiędzy oknami.

Kolejne pola z dokumentacji to:

Standard Fields:
{Title} {UserName} {Password} {URL} {Notes}Other Placeholders:
{GROUP} {GROUP_PATH} {GROUP_NOTES} {GROUP_SEL} {GROUP_SEL_PATH} {GROUP_SEL_NOTES} {PASSWORD_ENC} {URL:RMVSCM} {URL:SCM} {URL:HOST} {URL:PORT} {URL:PATH} {URL:QUERY} {URL:USERINFO} {URL:USERNAME} {URL:PASSWORD} {T-REPLACE-RX:/T/S/R/} {T-CONV:/T/C/} {C:Comment}

{DELAY 1000} {DELAY=200} {VKEY 13} {VKEY-NX 13} {VKEY-EX 13} {PICKCHARS} {PICKCHARS:Password:C=3} {PICKFIELD} {NEWPASSWORD} {NEWPASSWORD:/Profile/} {HMACOTP} {CLEARFIELD} {APPACTIVATE Title} {BEEP 800 200} {CMD:/C/O/}

{APPDIR} {DB_PATH} {DB_DIR} {DB_NAME} {DB_BASENAME} {DB_EXT} {ENV_DIRSEP} {ENV_PROGRAMFILES_X86}

{DT_SIMPLE} {DT_YEAR} {DT_MONTH} {DT_DAY} {DT_HOUR} {DT_MINUTE} {DT_SECOND} {DT_UTC_SIMPLE} {DT_UTC_YEAR} {DT_UTC_MONTH} {DT_UTC_DAY} {DT_UTC_HOUR} {DT_UTC_MINUTE} {DT_UTC_SECOND}