25 Aralık 2018 Salı

Copy Paste Trim and Only Numeric

import { OnInit, Directive, HostListener, EventEmitter, Output } from "@angular/core";

@Directive({
selector: "[copyPasteTrimAndOnlyNumeric]",
providers: []
})
export class CopyPasteTrimAndOnlyNumericDirective {

@Output() ngModelChange: EventEmitter<any> = new EventEmitter();
value: any;

constructor() { }

ngOnInit(): void { }

@HostListener('paste', ['$event']) onPaste(e: ClipboardEvent) {
debugger
e.preventDefault();
let pastedText = e.clipboardData.getData('text');
if (pastedText) {
pastedText = pastedText.replace(/[^0-9]+/g, '')
if (pastedText && pastedText.length > 11)
pastedText = pastedText.substring(0, 11);
this.ngModelChange.emit(pastedText);
}
}
}

3 Aralık 2018 Pazartesi

Enum Display Name'ini çekme

using System;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

public static class EnumExtensions
{
    public static string GetDisplayName(this Enum enu)
    {
        var attr = GetDisplayAttribute(enu);
        return attr != null ? attr.Name : enu.ToString();
    }

    public static string GetDescription(this Enum enu)
    {
        var attr = GetDisplayAttribute(enu);
        return attr != null ? attr.Description : enu.ToString();
    }

    private static DisplayAttribute GetDisplayAttribute(object value)
    {
        Type type = value.GetType();
        if (!type.IsEnum)
        {
            throw new ArgumentException(string.Format("Type {0} is not an enum", type));
        }

        // Get the enum field.
        var field = type.GetField(value.ToString());
        return field == null ? null : field.GetCustomAttribute<DisplayAttribute>();
    }
}

21 Kasım 2018 Çarşamba

Httpden dönen json datanın hepsini localStorage'e atma

var dataProperties = Object.getOwnPropertyNames(responseStart.data);
for(let i=0;i<datapProperties.length;i++){
localStorage.setItem(prefix+dataProperties[i],responseStart[dataProperties[i]])
}

12 Kasım 2018 Pazartesi

Angular Component değer alma, değer yollama/yayınlama

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
selector: 'ip-address',
templateUrl: './ip-address.component.html',
})
export class IpAddressComponent implements OnInit {

ipAddressParts: any[] = ["0", "0", "0", "0"];

tempValue;

@Input("value")
set IpAddressComponent(value: string) {
if (typeof value !== 'string' || value.indexOf('.') === -1) {
return;
}
else {
var parts = value.split(".");
for (let index in parts) {
this.ipAddressParts[index] = +parts[index];
}
}
}

get IpAddressComponent() {
return this.ipAddressParts.join(".");
}

@Output("value")
public ipAddressEmitter = new EventEmitter<string>();

constructor() { }

ngOnInit() {
}

}

Angular ngModel'in değerini directive içinde değiştirme

Çözüm bulduğum link:
@Directive({ 
  selector: '[ngModel][uppercase]',
  providers: [NgModel],
  host: {
    '(ngModelChange)' : 'onInputChange($event)'
  }
})
export class UppercaseDirective{
  constructor(private model:NgModel){}

  onInputChange(event){
    this.model.valueAccessor.writeValue(event.toUpperCase());
  }
}
Benim çözümüm
import { OnInit, Directive, HostListener, HostBinding, ElementRef } from "@angular/core";
import { NgModel } from "@angular/forms";
@Directive({
selector: "[ngModel][ipAddressMask]",
providers: [NgModel]
})
export class IpAddressMaskDirective implements OnInit {
navKeys = [39, 37, 8, 46, 65, 97] // Delete, Backspace, <- , ->, ctrl+a tuşlarını çıkarıyoruz
ipMaskChars = ["_", ".", "_", ".", "_", ".", "_"];
ipMask = "_._._._"
@HostBinding('attr.value') _value;
constructor(private elem: ElementRef, private model: NgModel) { }
@HostListener("keyup", ['$event']) hostKeyUpEvent($event: KeyboardEvent) {
let key = $event.key;
let code = +$event.keyCode;
debugger
if (!key) return;
let val = this.elem.nativeElement.value;
if (this.navKeys.indexOf(code) > -1) return;
let numReg = new RegExp("[0-9]");
let parts = val.split(".");
for (let i in parts)
parts[i] = parts[i].replace(/[^0-9\.]+/g, '');;
let outPut = parts.filter(c => Number(c));
if (!outPut) return;
let newValue = this.format(outPut);
this.elem.nativeElement.value = newValue;
this.model.viewToModelUpdate(newValue);
let SelectionPosition = this.getSelectionPosition(newValue);
this.elem.nativeElement.selectionStart = SelectionPosition;
this.elem.nativeElement.selectionEnd = SelectionPosition;
}
private getSelectionPosition(inputVal: string): number {
let position = 0;
if (inputVal) {
let parts = inputVal.split(".");
let outPut = parts.filter(c => Number(c));
if (parts && outPut) {
position += outPut.length;
for (let i = 0; i < outPut.length; i++) {
position += (outPut[i] + "").length > 3 ? 3 : (outPut[i] + "").length;
}
position--;
}
}
return position;
}
private format(outPut: string[]) {
let ipAddressChars = [];
let outPutLength = outPut && outPut.length;
debugger;
for (let i = 0; i < 4; i++) {
if (outPutLength > i) {
if ((outPut[i] + "").length > 3) {
if (i + 1 < 4) {
if (outPut[i + 1]) {
outPut[i + 1] = (outPut[i] + "").slice(3) + outPut[i + 1]
} else {
outPut[i + 1] = (outPut[i] + "").slice(3);
outPutLength = outPut.length;
}
outPut[i] = (outPut[i] + "").slice(0, 3);
} else {
outPut[i] = (outPut[i] + "").slice(0, 3);
}
}
if (+outPut[i] < 0) outPut[i] = "0";
else if (+outPut[i] > 255) outPut[i] = "255";
ipAddressChars.push(outPut[i]);
} else {
ipAddressChars.push("___");
}
}
return ipAddressChars.join(".");
}
ngOnInit(): void {
this._value = this.ipMask;
}
}

2 Kasım 2018 Cuma

Observable dummy data döndürme

public getCustomFunc(): Observable<any> {
let dummyData = {
                       //...
};

return Observable.create(observer => { observer.next(dummyData); });
}

30 Ekim 2018 Salı

OpenIddict

https://github.com/openiddict/openiddict-core

OpenIddict nedir?

OpenIddict herhangi bir ASP.NET Core 1.x veya 2.x uygulamasında OpenID Connect sunucusunu uygulamak için basit ve kullanımı kolay bir çözüm sunmayı amaçlamaktadır.

OpenIddict, OpenID Connect kimlik doğrulaması akışını kontrol etmek için AspNet.Security.OpenIdConnect.Server (ASOS) temel alır ve ASP.NET Core Identity dahil olmak üzere herhangi bir üyelik yığınıyla kullanılabilir.

OpenIddict, kod / örtülü / karma akışları ve istemci kimlik bilgilerini / kaynak sahibi parolalarını tam olarak destekler. Kendi özel onay türlerinizi de oluşturabilirsiniz.

Not: OpenIddict, Entity Framework Core, Entity Framework 6 ve MongoDB'yi kullanıma hazır olarak destekler ama kendi depolarınızı da sağlayabilirsiniz.


Neden bir OpenID Connect sunucusu?

Bir OpenID Connect sunucusunun uygulamanıza eklenmesi, token kimlik doğrulamasını desteklemenizi sağlar. Ayrıca API'nize kimin erişebileceğini ve her bir müşteriye verilen bilgileri kontrol etme gücü ile tüm kullanıcılarınızın tek bir merkezi yerde yerel şifrenizi veya harici bir kimlik sağlayıcısı (ör. Facebook veya Google) kullanarak yönetebilmelerini sağlar.


26 Ekim 2018 Cuma

Stateless

https://github.com/dotnet-state-machine/stateless

Stateless (Durum Bilgisiz / Durumsuz )

Doğrudan .NET kodunda durum makineleri ve hafif durum tabanlı makine tabanlı iş akışları oluşturun:

var phoneCall = new StateMachine<State, Trigger>(State.OffHook);

phoneCall.Configure(State.OffHook)
    .Permit(Trigger.CallDialled, State.Ringing);
 
phoneCall.Configure(State.Ringing)
    .Permit(Trigger.CallConnected, State.Connected);
 
phoneCall.Configure(State.Connected)
    .OnEntry(() => StartCallTimer())
    .OnExit(() => StopCallTimer())
    .Permit(Trigger.LeftMessage, State.OffHook)
    .Permit(Trigger.PlacedOnHold, State.OnHold);

// ...

phoneCall.Fire(Trigger.CallDialled);
Assert.AreEqual(State.Ringing, phoneCall.State);

Yukarıdaki projenin yanı sıra bu proje de Basit Durum Makinesi'nden esinlenmiştir.


Özellikler

Çoğu standart durum makinesi yapıları desteklenir:

  • Herhangi bir .NET türünün durumları ve tetikleyicileri için genel destek (sayılar, dizeler, numaralar vb.)
  • Hiyerarşik durumlar
  • Durumlar için giriş / çıkış olayları
  • Koşullu geçişleri desteklemek için koruma maddeleri
  • İçgözlem
Bazı faydalı uzantılar da sağlanmıştır:
  • Durumu harici olarak depolayabilme (örneğin, bir ORM tarafından izlenen bir özellik)
  • Parametreli tetikleyiciler
  • Yeniden girişli durum
  • DOT grafiğine aktarma

Hiyerarşik Durumlar

Aşağıdaki örnekte, OnHold durumu, Connected durumun bir alt-durumudur. Bu, bir OnHold çağrısının hala bağlı olduğu anlamına gelir.

phoneCall.Configure(State.OnHold)
    .SubstateOf(State.Connected)
    .Permit(Trigger.TakenOffHold, State.Connected)
    .Permit(Trigger.PhoneHurledAgainstWall, State.PhoneDestroyed);

StateMachine.State özelliğine ek olarak, kesin mevcut durumu bildirecek olan bir IsInState (State) yöntemi sağlanmıştır. IsInState (State) alt durumları dikkate alacaktır, böylece yukarıdaki örnek OnHold durumundaysa, IsInState (State.Connected) da true olarak değerlendirilecektir.


Durumlar İçin Giriş/Çıkış Olayları

Örnekte, bir çağrı bağlandığında StartCallTimer () metotu çalıştırılacaktır. Çağrı tamamlandığında StopCallTimer () çalıştırılacaktır.

Çağrı, OnHold durumunun Connected durumun bir durumu olduğu için tekrar tekrar çağrılan StartCallTimer () ve StopCallTimer () metotları kullanılmadan Connected ve OnHold durumları arasında hareket edebilir.

Giriş / Çıkış olay işleyicileri, tetikleyici, kaynak ve hedef durumları açıklayan bir Transition türü parametresi ile birlikte sağlanabilir.

Dış Durum Depolama

Durum Bilgisiz, çeşitli uygulama modellerine gömülecek şekilde tasarlanmıştır. Örneğin, bazı ORM'ler eşlenmiş verilerin nerede depolanabileceğine dair gereksinimleri yerine getirir ve UI çerçeveler genellikle özel "bağlanabilir" özelliklerinde depolanmak üzere durum gerektirir.Bu amaçla, StateMachine yapıcısı, durum değerlerini okumak ve yazmak için kullanılacak işlev argümanlarını kabul edebilir:

var stateMachine = new StateMachine<State, Trigger>(
    () => myState.Value,
    s => myState.Value = s);

Bu örnekte durum makinesi, durum depolama için myState nesnesini kullanacaktır.

Başka bir örnek, örnek klasörde bulunan JsonExample çözümünde bulunabilir.

İçgözlem

Durum makinesi, tetikleyicilerin bir listesini, StateMachine.PermittedTriggers özelliği aracılığıyla geçerli durumda başarılı bir şekilde tetiklenebilen bir liste sağlayabilir. Durum yapılandırması hakkında bilgi almak için StateMachine.GetInfo () metotudunu kullanın.

Güvenlik maddeleri

Durum makinesi, koruma maddelerine dayalı çoklu geçişler arasında seçim yapar;
phoneCall.Configure(State.OffHook)
    .PermitIf(Trigger.CallDialled, State.Ringing, () => IsValidNumber)
    .PermitIf(Trigger.CallDialled, State.Beeping, () => !IsValidNumber);

Bir durum içindeki güvenlik maddelerinin karşılıklı olarak özel olması şarttır (aynı anda birden fazla güvenlik maddesi geçerli olamaz). Alt durumlar bunları tekrar belirterek geçişleri geçersiz kılar, ancak alt durumlar, üst-durumlar (superstate) tarafından izin verilerin geçişlere izin veremez.

Bir tetikleyici tetiklendiğinde koruma maddeleri değerlendirilecektir. Güvenlikler, yan etkisiz hale getirilmelidir.


Parametreli tetikleyiciler

Güçlü yazılan(Strongly-typed) parametreler tetikleyicilere atanabilir:

var assignTrigger = stateMachine.SetTriggerParameters<string>(Trigger.Assign);

stateMachine.Configure(State.Assigned)
    .OnEntryFrom(assignTrigger, email => OnAssigned(email));

stateMachine.Fire(assignTrigger, "joe@example.com");

Tetik parametreleri, PermitDynamic () yapılandırma metodunu kullanarak hedef durumu dinamik olarak seçmek için kullanılabilir.


Gözardı Edilen Geçişler ve Yeniden Girişli Durumlar

Bununla ilişkili izin verilen bir geçişi olmayan bir tetikleyici tetiklemek, bir istisnanın atılmasına neden olur.

Belirli durumlar içinde tetikleyicileri yok saymak için Ignore(TTrigger) direktifini kullanın:

phoneCall.Configure(State.Connected)
    .Ignore(Trigger.CallDialled);

Alternatif olarak, bir durum, yeniden girişli olarak işaretlenebilir, böylece giriş ve çıkış olayları, kendisinden / kendisinden geçerken bile tetiklenecektir:

stateMachine.Configure(State.Assigned)
    .PermitReentry(Trigger.Assigned)
    .OnEntry(() => SendEmailToAssignee());

Varsayılan olarak, tetikleyiciler açıkça göz ardı edilmelidir. İşlenmemiş bir tetikleyici tetiklendiğinde, Durumsuz'un varsayılan bir istisna fırlatma davranışını geçersiz kılmak için, OnUnhandledTrigger yöntemini kullanarak durum makinesini yapılandırın:

stateMachine.OnUnhandledTrigger((state, trigger) => { });


DOT grafiğine aktarma

Durum makinelerini çalışma zamanında görselleştirmek faydalı olabilir. Bu yaklaşımla, kod yetkili kaynak ve durum diyagramları her zaman güncel olan yan ürünlerdir.

phoneCall.Configure(State.OffHook)
    .PermitIf(Trigger.CallDialled, State.Ringing, IsValidNumber);
    
string graph = UmlDotGraph.Format(phoneCall.GetInfo());

UmlDotGraph.Format () metodu, DOT grafiği dilinde durum makinesinin dize temsilini döndürür, örn .:

digraph {
  OffHook -> Ringing [label="CallDialled [IsValidNumber]"];
}

PDF dosyası oluşturmak için komut satırı örneği: dot -T pdf -o phoneCall.pdf phoneCall.dot.


Asenkron Tetikleyiciler

Task<T>  sağlayan platformlarda, StateMachine, async giriş/çıkış eylemlerini ve benzerlerini destekler:

stateMachine.Configure(State.Assigned)
    .OnEntryAsync(async () => await SendEmailToAssignee());

Eşzamansız/Asenkron işleyiciler bu durumlarda * Async () metodları kullanılarak kaydedilmelidir.
Eşzamansız/Asenkron eylemleri tetikleyen bir tetikleyiciyi çalıştırmak için, FireAsync () meotdu kullanılmalıdır:

await stateMachine.FireAsync(Trigger.Assigned);

Not: StateMachine eşzamansız olarak kullanılabilirken, tek iş parçacıklı olarak kalır ve aynı anda birden çok iş parçacığı tarafından eşzamanlı kullanılamaz.


Yapı

Durumsuz, .NET 4.0 + 'da ve hemen hemen tüm modern .NET platformlarında .NET Standard 1.0'ı hedefleyerek çalışır. Visual Studio 2017, çözümü kurmak için gereklidir.


Proje hedefleri

Bu sayfa Durumsuz'un (Stateless) neredeyse tamamlanmış bir tanımlamasıdır ve açık amacı asgari düzeyde kalmaktır.

30 Temmuz 2018 Pazartesi

Tüm TimeZone'ları çekip veritabanına ekleme

            var tzCollection = TimeZoneInfo.GetSystemTimeZones();
            var timeZoneTypes = new List<TimeZoneType>();
            foreach (var timeZoneInfo in tzCollection)
            {
                var timeZoneType = new TimeZoneType
                {
                    TimeZoneInfoId = timeZoneInfo.Id,
                    DaylightName = timeZoneInfo.DaylightName,
                    DisplayName = timeZoneInfo.DisplayName,
                    StandardName = timeZoneInfo.StandardName,
                    SupportsDaylightSavingTime = timeZoneInfo.SupportsDaylightSavingTime,
                    Ticks = timeZoneInfo.BaseUtcOffset.Ticks
                };
                timeZoneTypes.Add(timeZoneType);
            }
            foreach (var timeZoneType in timeZoneTypes)
            {
                db.TimeZoneTypes.Add(timeZoneType);

                db.Commit();
            }


2 Haziran 2018 Cumartesi

Veritabanı Collation Değiştirme

USE master;
GO
ALTER DATABASE [DatabaseName]
COLLATE SQL_Latin1_General_CP1_CI_AS ;
GO

--Verify the collation setting.
SELECT name, collation_name
FROM sys.databases
WHERE name = N'[DatabaseName]';
GO

Tüm tablo kolonların 'Collation'ları SQL_Latin1_General_CP1_CI_AS yapma

DECLARE @collate nvarchar(100);
DECLARE @table nvarchar(255);
DECLARE @column_name nvarchar(255);
DECLARE @column_id int;
DECLARE @data_type nvarchar(255);
DECLARE @max_length int;
DECLARE @row_id int;
DECLARE @sql nvarchar(max);
DECLARE @sql_column nvarchar(max);

SET @collate = 'SQL_Latin1_General_CP1_CI_AS';

DECLARE local_table_cursor CURSOR FOR

SELECT [name]
FROM sysobjects
WHERE OBJECTPROPERTY(id, N'IsUserTable') = 1

OPEN local_table_cursor
FETCH NEXT FROM local_table_cursor
INTO @table

WHILE @@FETCH_STATUS = 0
BEGIN

    DECLARE local_change_cursor CURSOR FOR

    SELECT ROW_NUMBER() OVER (ORDER BY c.column_id) AS row_id
        , c.name column_name
        , t.Name data_type
        , c.max_length
        , c.column_id
    FROM sys.columns c
    JOIN sys.types t ON c.system_type_id = t.system_type_id
    LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
    LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
    WHERE c.object_id = OBJECT_ID(@table)
    ORDER BY c.column_id

    OPEN local_change_cursor
    FETCH NEXT FROM local_change_cursor
    INTO @row_id, @column_name, @data_type, @max_length, @column_id

    WHILE @@FETCH_STATUS = 0
    BEGIN

        IF (@max_length = -1) OR (@max_length > 4000) SET @max_length = 4000;

        IF (@data_type LIKE '%char%')
        BEGIN TRY
            SET @sql = 'ALTER TABLE ' + @table + ' ALTER COLUMN ' + @column_name + ' ' + @data_type + '(' + CAST(@max_length AS nvarchar(100)) + ') COLLATE ' + @collate
            PRINT @sql
            EXEC sp_executesql @sql
        END TRY
        BEGIN CATCH
          PRINT 'ERROR: Some index or constraint rely on the column' + @column_name + '. No conversion possible.'
          PRINT @sql
        END CATCH

        FETCH NEXT FROM local_change_cursor
        INTO @row_id, @column_name, @data_type, @max_length, @column_id

    END

    CLOSE local_change_cursor
    DEALLOCATE local_change_cursor

    FETCH NEXT FROM local_table_cursor
    INTO @table

END

CLOSE local_table_cursor
DEALLOCATE local_table_cursor

GO

16 Mayıs 2018 Çarşamba

SQL'de Tüm Tabloların Geçerli "Identity Seed" değerini bulma

SELECT
    TABLE_NAME AS [Table],
    IDENT_CURRENT(TABLE_SCHEMA + '.' + TABLE_NAME) AS Id,
    IDENT_SEED(TABLE_SCHEMA + '.' + TABLE_NAME) AS Seed,
    IDENT_INCR(TABLE_SCHEMA + '.' + TABLE_NAME) AS Increment
FROM
    INFORMATION_SCHEMA.TABLES
WHERE
    OBJECTPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME), 'TableHasIdentity') = 1
AND
    TABLE_TYPE = 'BASE TABLE'
    order by Seed

.net 6 mapget kullanımı

 app.UseEndpoints(endpoints => {     endpoints.MapGet("/", async context =>     {         var response = JsonConvert.Seriali...