14 Ekim 2021

6 Karakterli Unique Key Üretme

 using System;

using System.Collections.Generic;
using System.Text;

namespace ConsoleApp14
{
    class Program
    {
       
        static void Main(string[] args)
        {
            var generatedKeys = new List<string>();
            for (int i = 0; i < 100000; i++)
            {
                var key = KeyGenerator.Generate(i);
                if (generatedKeys.Contains(key))
                    throw new Exception("Tekrar eden numaralar var");
                Console.WriteLine(key);
                generatedKeys.Add(key);
            }
        }
    }

    public static class KeyGenerator
    {
        // chars count must be prime number
        // (mine are 31 i also shuffled them you can re shuffle your letters)
        private static readonly char[] chars = {
                'C', 'V', 'M', 'J', '4', 'E', 'Y','L','R','N','9','5','Z','3','X',
                'D','8','G','T','6','K','W','P','B','S','U','F','H','A','2','7'
            };
        private static int Mod(int a, int b)
           => ((a % b) + b) % b;

        /// <summary>
        /// Generates Unique 6 Character Key By Id
        /// </summary>
        /// <param name="index"> Min 0 Max 887,503,680</param>
        /// <returns></returns>
        public static string Generate(int index)
        {
            // I am calculating 6 digit which means 31^6 = 887503681 possible number
            // I multiplied with 2 different very big prime numbers to prevent similar generated keys
            var number = Mod((index * 8969 * 10457), 887503681);
            var sb = new StringBuilder();
            while (number > 30)
            {
                var letter = chars[(number % 31)];
                sb.Append(letter);
                number = number / 31;
            }
            sb.Append(chars[number]);
            // if it's shorter than 6 character we add last character example (1 =>001)
            while (sb.Length < 6)
            {
                sb.Insert(0, chars[30]);
            }

            return sb.ToString();
        }
    } 
}


SQL User Defined Function

create function [dbo].[udf_GenerateSixCharacterKey] 
(@index int)
returns varchar(6)  as
begin 
declare @a int, 
@b int
set @a = @index * 8969 * 10457
set @b = 887503681

declare @number int
set @number = ((@a % @b) + @b) % @b

declare @chars varchar(31)
set @chars = 'CVMJ4EYLRN95Z3XD8GT6KWPBSUFHA27'

declare @key varchar(6)
set @key = ''

while @number > 30
begin 
set @key = @key + substring(@chars, (@number % 31) + 1, 1)
set @number = @number / 31
end

set @key = @key + substring(@chars, @number + 1, 1)

while len(@key) < 6
begin
set @key = substring(@chars, 31, 1) + @key
end

return @key

end

2 Eylül 2021

AES Encryption Quick Code

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace AesSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //appsettings üzerinden okunduğunu varsayalım.
            var encryptSettings = new EncryptSettings()
            {
                IV = "LoremIpsum",
                Key = "DolorSitAmet",
            };

            IEncryptTools encryptTools = new EncryptTools(encryptSettings);

            var sampleText = "Knowing is not enough; we must apply. Willing is not enough; we must do";

            var encrypted = encryptTools.AesEncrypt(sampleText);

            Console.WriteLine("Encrypted:");
            Console.WriteLine(encrypted);
            Console.WriteLine();

            var decrypted = encryptTools.AesDecrypt(encrypted);
            Console.WriteLine("Decrypted");
            Console.WriteLine(decrypted);

        }
    }

    public interface IEncryptTools
    {
        string AesEncrypt(string plainText);
        string AesDecrypt(string encryptedText);
        byte[] Sha256Byte(string plainText);
        string Sha256String(string plainText);
        string Sha256String(byte[] bytes);
    }

    public class EncryptSettings
    {
        public string Key { get; set; }
        public string IV { get; set; }

    }

    public class EncryptTools : IEncryptTools
    {
        private readonly EncryptSettings encryptSettings;

        public EncryptTools(EncryptSettings encryptSettings)
        {
            this.encryptSettings = encryptSettings;
        }


        private byte[] key => Sha256Byte(encryptSettings.Key);
        private byte[] iv => new List<byte>(Sha256Byte(encryptSettings.IV))
            .GetRange(0, 16).ToArray();
        public string AesEncrypt(string plainText)
        {
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (key == null || key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (iv == null || iv.Length <= 0)
                throw new ArgumentNullException("IV");
            byte[] encrypted;

            using (var aes = Aes.Create())
            {
                aes.Key = key;
                aes.IV = iv;

                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                using (var ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(cs))
                        {
                            swEncrypt.Write(plainText);
                        }
                        encrypted = ms.ToArray();
                    }
                }
            }
            return Convert.ToBase64String(encrypted);
        }

        public string AesDecrypt(string encryptedText)
        {
            var cipherText = Convert.FromBase64String(encryptedText);

            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (key == null || key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (iv == null || iv.Length <= 0)
                throw new ArgumentNullException("IV");

            string plaintext = null;

            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = key;
                aesAlg.IV = iv;

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }

            return plaintext;
        }

        public byte[] Sha256Byte(string plainText)
        {
            byte[] bytes = null;
            using (SHA256 sha256Hash = SHA256.Create())
            {
                bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(plainText));
            }
            return bytes;
        }

        public string Sha256String(byte[] bytes)
        {
            var builder = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                builder.Append(bytes[i].ToString("x2"));
            }
            return builder.ToString();
        }

        public string Sha256String(string plainText)
        {
            var bytes = Sha256Byte(plainText);
            return Sha256String(bytes);
        }
    }
}
 

23 Ağustos 2021

ASP.NET Core Middleware Response Body Değiştirme

using Sample.Settings;
using Microsoft.AspNetCore.Http;
using System.IO;
using System.Threading.Tasks;

namespace Sample.Middlewares
{
    public class ContentModifyMiddleware
    {
        private readonly RequestDelegate next;
        private readonly MySettings mySettings;
        public ContentModifyMiddleware(RequestDelegate next,
            MySettings mySettings)
        {
            this.next = next;
            this.mySettings = mySettings;
        }

        public async Task Invoke(HttpContext context)
        {
            // Başlangıç: Hangi Koşullarda Değiştireceğim (Opsiyonel)
            var modifyBody = false;
            object controllerName = null;
            modifyBody = (context.Request.RouteValues != null
                && context.Request.RouteValues.TryGetValue("controller", out controllerName)
                && mySettings.ReplaceTexts != null
                && mySettings.ReplaceTexts.Count > 0);
            modifyBody &= (controllerName != null && controllerName.ToString() == "Home");
            // Bitiş: Hangi Koşullarda Değiştireceğim (Opsiyonel)
          
            // Başlangıç: İçerik Değiştirilsin
            if (modifyBody)
            {
                // Orjinal Body Yedekle
                var originalBody = context.Response.Body;
               
                // Değişikliklerin Yapılacağı Yeni Body
                var newBody = new MemoryStream();
                context.Response.Body = newBody;

                // Response'u al
                await next(context);

                // Responsu string olarak oku
                newBody.Position = 0;
                var newContent = await new StreamReader(newBody).ReadToEndAsync();

                // Başlangıç: Response Üzerinde Değişiklikeri Yap
                // (Replace alanlarını appsettings.json dan okuyorum - siz gömülü kod kullanabilirsiniz.)
                foreach (var item in mySettings.ReplaceTexts)
                {
                    newContent = newContent.Replace(item.Old, item.New);
                }
                // Başlangıç: Response Üzerinde Değişiklikeri Bitiş
               
                //String üzerinde yapılan değişiklikler tekrar stream'a dönüştürülüyor. Ve değiştirilmiş stream original body ile değiştiriliyor.
                using (var stream = new MemoryStream())
                {
                    var writer = new StreamWriter(stream);
                    writer.Write(newContent);
                    writer.Flush();
                    stream.Position = 0;
                    await stream.CopyToAsync(originalBody);
                }
                newBody.DisposeAsync();
                context.Response.Body = originalBody;
            }
            // Bitiş: İçerik Değiştirilsin
            // Başlangıç: İçerik Değiştirilmeden Geç
            else
            {
                await next(context);
            }
            // Bitiş: İçerik Değiştirilmeden Geç
        }
    }
}
 

26 Mayıs 2021

MVC JQuery Validate Unobtrusive Boostrap Class

<script src="jquery.js"></script> 

<script src="jquery.validate.js"></script> 

<script src="jquery.validate.min.js"></script> 

 <script>
        var validationSettings = {
            validClass: "is-valid",
            errorClass: "is-invalid"
        };
        $.validator.setDefaults(validationSettings);
        $.validator.unobtrusive.options = validationSettings;
    </script>

22 Nisan 2021

Javascript ile HTML i PDF'e çevirme (html-to-pdfmake, pdfmake)

jsPDF düzgün bir görüntü vermediği için pdfmake ve html-to-pdfmake kullanılmıştır.

Eğer bu kütüphaneleri kullanacaksanız iki kütüphaneye de github üzerinden yıldız vermeyi unutmayın. 

Kullanılan Kütüphaneler

https://pdfmake.github.io/docs/0.1/

https://github.com/Aymkdn/html-to-pdfmake

<!doctype html>
<html lang='en'>
    <head>
        <meta charset='utf-8'>
        <title>my example</title>
        <style>
        /*Hide style for print screen*/
        
            @media print {
            .noPrint {
                display: none;
            }
        }
        </style>
    </head>
    <body>
        <div class="noPrint">
            <button type="button" onclick="downloadPdf()">PDF(HtmlToPdfMaker)</button>
            <!--Print doesn't come with pdf download option on mobile phones, but it has save as pdf option on web browsers in Windows-->
            <button type="button" onclick="window.print()">Print(Vanilla JS)</button>
        </div>
        <div id="pdfContent">
            <h1>Some Html Codes</h1>
        </div>

        <script src='https://cdn.jsdelivr.net/npm/pdfmake@latest/build/pdfmake.min.js'></script>
        <script src='https://cdn.jsdelivr.net/npm/pdfmake@latest/build/vfs_fonts.min.js'></script>
        <script src="https://cdn.jsdelivr.net/npm/html-to-pdfmake/browser.js"></script>
        <script>
            function downloadPdf() {
                var val = new htmlToPdfmake(document.getElementById('pdfContent').innerHTML);
                var dd = { content: val };
                pdfMake.createPdf(dd).download('FileName.pdf');                
            }
        </script>
    </body>
</html>

 

4 Mart 2021

Image Resize For Javascript

 //index.html

 <!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <form>
        <button id="addNewImage" type="button">Yeni Resim Ekle</button>
        <img id="preview" width="100">
    </form>

    <script src="index.js"></script>
</body>
</html>

 

// index.js 

var btnAddNewImage = document.getElementById('addNewImage');
var imgPreview = document.getElementById('preview');
var inputInvoicePhoto = document.getElementById('invoicePhoto');

var MaxSize = 1024;

function dataURLToBlob(dataURL) {
    var BASE64_MARKER = ';base64,';
    if (dataURL.indexOf(BASE64_MARKER) == -1) {
        var parts = dataURL.split(',');
        var contentType = parts[0].split(':')[1];
        var raw = parts[1];

        return new Blob([raw], {type: contentType});
    }

    var parts = dataURL.split(BASE64_MARKER);
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;

    var uInt8Array = new Uint8Array(rawLength);

    for (var i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }

    return new Blob([uInt8Array], {type: contentType});
}

// func delegateAfterResizedImage(imageName, blob)
function resizeImage(file, delegateAfterResizedImage){
    if(file.type=="image/jpeg"){
        var reader = new FileReader();
        reader.onload = function(readerEvent){
            var image = new Image();
            image.onload = function(imageEvent){
                var canvas = document.createElement('canvas'),
                width = image.width,
                height = image.height;
                if (width > height) {
                    if (width > MaxSize) {
                        height *= MaxSize / width;
                        width = MaxSize;
                    }
                } else {
                    if (height > MaxSize) {
                        width *= MaxSize / height;
                        height = MaxSize;
                    }
                }
                canvas.width = width;
                canvas.height = height;
                canvas.getContext('2d').drawImage(image, 0, 0, width, height);
                var dataUrl = canvas.toDataURL('image/jpeg');
                console.log('dataUrl '+ dataUrl );
                var resizedImage = dataURLToBlob(dataUrl);    
                delegateAfterResizedImage(resizedImage, file.name)            
                
            }
            image.src = readerEvent.target.result;
        }
        reader.readAsDataURL(file);
    }
}

btnAddNewImage.addEventListener('click', function () {
    console.log('clicked');
    var inputSelectFile = document.createElement('input');
    inputSelectFile.type = "file";
    inputSelectFile.accept = "image/jpeg";

    inputSelectFile.addEventListener('change', function(e){
        var files = e.target.files;
        if(files!=null && files.length > 0){
            for(var i = 0; i < files.length; i++){
                var file = files[i];
                resizeImage(file, (blob, name)=>{
                    console.log(name);
                    var objectURL = URL.createObjectURL(blob);
                    imgPreview.src = objectURL;
                });
            }
        }
        inputSelectFile = null;
    })
    inputSelectFile.click();       
}, false);

7 Şubat 2021

Sudoku Çözme Algoritması

AMS de yazılan sudoku çözme algoritmasının C# a uyarlanmasıdır.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SudokuSolver
{
class Program
{
static void Main(string[] args)
{
var game = SudokuGame.NewGame();
Console.WriteLine(game.ToString());
game.Crook();
Console.WriteLine(game.ToString());
}
}

public class SudokuGame
{
public List<Cell> Cells { get; set; }
public SudokuGame()
{
Cells = new List<Cell>();
for (int m = 1; m <= 9; m++)
{
for (int n = 1; n <= 9; n++)
{
Cells.Add(new Cell(m, n));
}
}

}
public Cell this[int m, int n]
{
get { return Cells.SingleOrDefault(q => q.M == m && q.N == n); }
set
{
var cell = Cells.SingleOrDefault(q => q.M == m && q.N == n);
cell = value;
}
}

public static SudokuGame NewGame()
{
var game = new SudokuGame();
game[1, 2].Value = 9;
game[1, 4].Value = 7;
game[1, 7].Value = 8;
game[1, 8].Value = 6;
game[2, 2].Value = 3;
game[2, 3].Value = 1;
game[2, 6].Value = 5;
game[2, 8].Value = 2;
game[3, 1].Value = 8;
game[3, 3].Value = 6;
game[4, 3].Value = 7;
game[4, 5].Value = 5;
game[4, 9].Value = 6;
game[5, 4].Value = 3;
game[5, 6].Value = 7;
game[6, 1].Value = 5;
game[6, 5].Value = 1;
game[6, 7].Value = 7;
game[7, 7].Value = 1;
game[7, 9].Value = 9;
game[8, 2].Value = 2;
game[8, 4].Value = 6;
game[8, 7].Value = 3;
game[8, 8].Value = 5;
game[9, 2].Value = 5;
game[9, 3].Value = 4;
game[9, 6].Value = 8;
game[9, 8].Value = 7;
return game;
}

public override string ToString()
{
var sb = new StringBuilder();
sb.AppendLine();
sb.AppendLine(new string('-', 19));
for (int m = 1; m <= 9; m++)
{
sb.Append('|');
for (int n = 1; n <= 9; n++)
{
sb.Append(this[m, n].Value == 0 ? " " : this[m, n].Value.ToString());
sb.Append('|');
}
sb.AppendLine();
sb.AppendLine(new string('-', 19));
}

return sb.ToString();

}

public void RemovePossibilities()
{
var firstText = this.ToString();
for (int m = 1; m <= 9; m++)
{
for (int n = 1; n <= 9; n++)
{
var cell = this[m, n];

if (cell.Value == 0)
{
// remove row
for (int i = 1; i <= 9; i++)
{
if (cell == this[m, i])
continue;
var r = this[m, i].Value;
cell.Possibilities.RemoveAll(q => q == r);
}
// remove column
for (int i = 1; i <= 9; i++)
{
if (cell == this[i, n])
continue;
var c = this[i, n].Value;
cell.Possibilities.RemoveAll(q => q == c);
}

// remove small square
var startM = 1;
if (m > 6)
startM = 7;
else if (m > 3)
startM = 4;

var startN = 1;
if (n > 6)
startN = 7;
else if (n > 3)
startN = 4;

for (int i = startM; i < startM + 3; i++)
{
for (int j = startN; j < startN + 3; j++)
{
if (cell == this[i, j])
continue;
if (this[i, j].Value > 0)
cell.Possibilities.RemoveAll(q => q == this[i, j].Value);
}
}

if (cell.Possibilities.Count == 1)
cell.Value = cell.Possibilities[0];
}
}
}
if (firstText != ToString())
RemovePossibilities();
}

public void Crook()
{
var firstText = this.ToString();
RemovePossibilities();
for (int m = 1; m <= 9; m++)
{
for (int n = 1; n <= 9; n++)
{
var cell = this[m, n];

if (cell.Value == 0)
{
for (int p = 0; p < cell.Possibilities.Count; p++)
{
var possibility = cell.Possibilities[p];

var possibilityCount = 0;
// row
for (int i = 1; i <= 9; i++)
{
if (this[m, i] != cell && this[i, n].Possibilities.Exists(q => q == possibility))
possibilityCount++;
}
if (possibilityCount == 1)
{
cell.Value = possibility;
Crook();
}
possibilityCount = 0;
// column
for (int i = 1; i <= 9; i++)
{
if (this[i, n] != cell && this[i, n].Possibilities.Exists(q => q == possibility))
possibilityCount++;
}
if (possibilityCount == 1)
{
cell.Value = possibility;
Crook(); ;
}

var startM = 1;
if (m > 6)
startM = 7;
else if (m > 3)
startM = 4;

var startN = 1;
if (n > 6)
startN = 7;
else if (n > 3)
startN = 4;
possibilityCount = 0;
for (int i = startM; i < startM + 3; i++)
{
for (int j = startN; j < startN + 3; j++)
{
if (cell == this[i, j])
continue;
if (this[i, j].Possibilities.Exists(q => q == possibility))
possibilityCount++;
}
}

if (possibilityCount == 1)
{
cell.Value = possibility;
Crook(); ;
}
}

}
}
}
if (firstText != ToString())
RemovePossibilities();
}
}

public class Cell
{
public Cell(int m, int n, int value = 0)
{
M = m;
N = n;
Value = value;
Possibilities = new List<int>();
if (Value == 0)
{
for (int i = 1; i <= 9; i++)
{
Possibilities.Add(i);
}
}
}
public int M { get; set; }
public int N { get; set; }
private int value = 0;
public int Value
{
get
{
return value;
}
set
{
this.value = value;
if (value != 0)
Possibilities.Clear();
}
}
public List<int> Possibilities { get; set; }
}

}

 

 

 

 Kaynak: https://www.ams.org/notices/200904/rtx090400460p.pdf

10 Aralık 2020

Pdf Türünde Dosya Kontrolü İçin Attribute

public class IsPdfFileAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
try
{
if (value != null)
{
var files = (List<IFormFile>)value;
if (files.Count > 0)
{
var areAllFilesZip = true;
foreach (var file in files)
{
if (file.FileName.EndsWith(".pdf") && file.ContentType == "application/pdf"
)
{
using (var ms = new MemoryStream())
{
file.CopyTo(ms);
var byteArray = ms.ToArray();
var content = System.Text.Encoding.UTF8.GetString(byteArray);
if (Regex.IsMatch(content, @"<script|<html|<head|<title|<body|<pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline))
{
areAllFilesZip = false;
break;
}

if (!content.StartsWith("%PDF"))
{
areAllFilesZip = false;
break;
}
}
}
else
{
areAllFilesZip = false;
break;
}
}
if (areAllFilesZip)
return ValidationResult.Success;
}
}
}
catch (Exception ex)
{

}
return new ValidationResult("Sadece PDF dosya yükleyebilirsiniz!");
}

public class SampleModel
{
[IsPdfFile]
public List<IFormFile> SamplePdfFile { get; set; }
}

// HomeController.cs
   public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}

[HttpPost]
[Consumes("multipart/form-data")]
public IActionResult Index([FromForm] SampleModel model)
{
return View(model);
}


//Index.cshtml
@{
@model WebApplication1.Models.SampleModel
}

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="SamplePdfFile" accept="application/pdf" required>
<input type="submit" />
if (!Html.ViewData.ModelState.IsValid)
{
<hr />
<div asp-validation-summary="All"></div>
}

Babel kullanarak Javascript ECMAScript 6 Kodlarını ECMAScript 5'e Çevirme

 Gereksinimler

Node.js ve NPM nin kurulu olması gerekiyor.

Adımlar

1. Proje Oluşturmak

Önce projemiz için bir klasör açacağız.

 Projenin Klasör Yapısı

/babeldemo (Proje Klasörü)

    /src           (ES6 ile yazılan JS kodları src altında tutulacak)

 komut satırı ile proje klasörüne girip npm init komutuyla package.json oluşturalım.

 

Bu aşamanın komut satırında yazılışı örnek




D:\>mkdir babeldemo

D:\>cd babeldemo

D:\babeldemo>mkdir src

D:\babeldemo>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (babeldemo)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\babeldemo\package.json:

{
"name": "babeldemo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}


Is this OK? (yes)

D:\babeldemo>

2.Babel Modüllerini Kurmak

Aşağıda ki komutu kullanarak babel-cli ve babel-preset-env kurulur


npm install babel-cli babel-preset-env

Babel, kaynak js sürümünü belirlemek için .babelrc diye bir dosya arar, bu yüzden proje klasörüne .babelrc dosyası oluşturarak içine aşağıda ki değerleri yazıyoruz.

{
  "presets": ["env"]
}

Yukarıda ki durumda "env" ES6 ve sonrası için tüm kodları dönüştürmesi talimatını verir.

3. Babel'i çalıştırmak için pacakage.json da scripts isimli alana babeli çalıştırması için gereken komutun kısaltılışını yazacağız. Burada biz "build" olarak verdik.

"scripts": { 
  "test": "echo \"Error: no test specified\" && exit 1",  
  "build": "babel src -d lib"
}
komutu açıklarsak babel src klasöründe ki ES6+ kodlarını ES5 e dönüştürerek lib klasörüne taşı.

4. Örnek ES6 Javascript Kodu Oluşturalım. src klasörümüzün içine eğer elinizde varsa ES6 kodları ekleyin yoksa benim örnekte oluşturduğum javascript dosyasını src klasörünün altında example.js ismiyle ekleyebilirsiniz.

//src/example.js

const add = (x, y) => { return x + y };

const num1 = 1;
const num2 = 2;

let sum = add(num1, num2);

console.log(`The sum of ${num1} and ${num2} is ${sum}.`); 

Şimdi Babel'i çalıştıralım. Tekrar komut satırından aşağıda ki satırı yazarak kodu çalıştıralım.

npm run build

Babel bizim için src içinde ki tüm ES6 kodlarını ES5 e çevirerek lib klasörü altına taşıdı.

example.js nin ES5 formatında çıktısı aşağıda ki gibidir.

 

 

"use strict";

var add = function add(x, y) {
  return x + y;
};

var num1 = 1;
var num2 = 2;

var sum = add(num1, num2);

console.log("The sum of " + num1 + " and " + num2 + " is " + sum + ".");

12 Ekim 2020

Asp Net Core ile ModelState Validation için Custom Yanıt Dönen Middleware

ASP.Net Core Web Api de DataAnnotations attribute ile uymayan durumlarda dönen yanıt örnek User.cs için aşağıdaki gibidir. 

 { "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", 

 "title": "One or more validation errors occurred.",

 "status": 400, 

 "traceId": "|c591e8b8-46918ec46443b7d8.", 

"errors": { 

"Username": [ "The Username field is required.", "En az sekiz karakterli bir kullanıcı adı giriniz." ] 

    } 

 }

 Bizim tüm uygulama boyunca generic api responseda formatı aşağıda ki gibi istediğimizi varsayalım 

{ "Status": 400,

 "IsSuccess": false,

 "Result": null,

 "Errors":

 "The Username field is required. \r\n En az sekiz karakterli bir kullanıcı adı giriniz."

  }

 Bunun için yapılan adımlar aşağıdaki gibidir.

#
// ApiResponse.cs //

using System;
using Microsoft.Extensions.Logging;

namespace CustomMiddlewareForModelState.Models
{
public class ApiResponse<TResult>
{
public int Status { get; set; }
public bool IsSuccess { get; set; }
public TResult Result { get; set; }
public string Errors { get; set; }

public ApiResponse<TResult> Invoke(Func<TResult> func, ILogger _logger)
{
try
{
Result = func.Invoke();
Status = 200;
IsSuccess = true;
Errors = string.Empty;
}
catch (Exception ex)
{
Guid? exceptionId = Guid.NewGuid();
Result = default(TResult);
IsSuccess = false;
Errors = $"Genel bir hata meydana geldi. Lütfen {exceptionId} takip numarası ile geri dönüşte bulunun. ";

_logger?.LogError("ExceptionId : " + exceptionId.ToString()
+ " , Exception: " + ex.ToString());
}
return this;
}
}
}

// ModelStateFeature.cs //

using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace CustomMiddlewareForModelState.Models
{
public class ModelStateFeature
{
public ModelStateDictionary ModelState { get; set; }

public ModelStateFeature(ModelStateDictionary state)
{
ModelState = state;
}
}

}

// ModelStateFeatureFilter.cs //


using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;
using CustomMiddlewareForModelState.Models;

namespace CustomMiddlewareForModelState.Filters
{
public class ModelStateFeatureFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var state = context.ModelState;
context.HttpContext.Features.Set(new ModelStateFeature(state));
await next();
}
}
}

// ModelStateResponseMiddleware.cs //

using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using CustomMiddlewareForModelState.Models;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace CustomMiddlewareForModelState.Middlewares{
public class ModelStateResponseMiddleware{
private readonly RequestDelegate next;
public ModelStateResponseMiddleware(RequestDelegate next)
{
this.next = next;
}

public async Task Invoke(HttpContext context)
{
Stream originalBody = context.Response.Body;
try
{
using (var ms = new MemoryStream())
{
context.Response.Body = ms;
await next(context);
ms.Position = 0;
string responseBody = new StreamReader(ms).ReadToEnd();

if (context.Response.StatusCode == 400)
{
var modelState = context.Features.Get<ModelStateFeature>()?.ModelState;
if (modelState != null
&& !modelState.IsValid
&& modelState.Count > 0)
{
var errors = modelState.Values.Where(v => v.Errors.Count > 0)
.SelectMany(v => v.Errors)
.Select(v => v.ErrorMessage)
.ToList();

var apiResponse = new ApiResponse<object>(){
IsSuccess = false,
Result = null,
Status = 400,
Errors = string.Join(" \r\n ", errors)
};

context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
context.Response.ContentType = "application/json";
string strApiResponse = JsonConvert.SerializeObject(apiResponse);
var data = System.Text.Encoding.UTF8.GetBytes(strApiResponse);
ms.Position = 0;
await ms.WriteAsync(data);
ms.SetLength(data.Length);
}
}
ms.Position = 0;
await ms.CopyToAsync(originalBody);
}
}
finally
{
context.Response.Body = originalBody;
}
}
}
}

// Startup.cs //
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CustomMiddlewareForModelState.Filters;
using CustomMiddlewareForModelState.Middlewares;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace CustomMiddlewareForModelState
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(opts => {
opts.Filters.Add(typeof(ModelStateFeatureFilter),int.MinValue);
});
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthorization();

app.UseMiddleware<ModelStateResponseMiddleware>();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

// User.cs //

using System.ComponentModel.DataAnnotations;

namespace CustomMiddlewareForModelState.Models
{
public class User
{
[Required]
[StringLength(int.MaxValue, MinimumLength = 1, ErrorMessage = "En az sekiz karakterli bir kullanıcı adı giriniz.")]
public string Username { get; set; }

[Required]
[StringLength(int.MaxValue, MinimumLength = 1, ErrorMessage = "En az sekiz karakterli bir şifre giriniz.")]
public string Password { get; set; }
}
}

// TestController.cs //


using System;
using Microsoft.AspNetCore.Mvc;
using CustomMiddlewareForModelState.Models;

namespace CustomMiddlewareForModelState.Controllers{
[Route("api/[controller]")]
[ApiController]
public class TestController : Controller
{
[HttpPost]
public IActionResult Post(User user)
{
var resp = new ApiResponse<Guid>().Invoke(() =>
{
if (ModelState.IsValid)
{
return Guid.NewGuid();
}
throw new Exception("Validasyon hatası!");
}, null);

if (resp.Status == 200)
return Ok(resp);
else return BadRequest(resp);
}
}
}

ModelState Başarısızsa dönen yanıt

{
"Status": 400,
"IsSuccess": false,
"Result": null,
"Errors": "The Username field is required. \r\n En az sekiz karakterli bir kullanıcı adı giriniz."
}

Başarılıysa Dönen Yanıt

{
"status": 200,
"isSuccess": true,
"result": "fdc56d1b-1ee8-43ce-b7d8-46ba36bee668",
"errors": ""
}
 #