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": ""
}
 #

28 Eylül 2020

Asp.Net Core ile Kendi Captcha Kodunu Oluştur


Installed Packages 
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.1" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0010" />

TreeView
/Common
- Captcha.cs
- CaptchaManager.cs
/Controllers
- HomeController.cs
/Controllers/Api
- CaptchaController.cs
/ViewModels/Home
- IndexViewModel.cs
/Views/Home
- Index.cshtml

// Captcha.cs
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.IO;
using System.Text;

namespace ApsNetCoreCaptchaSample.Common
{
public class Captcha : IDisposable
{
private static char[] _charset = null;
private static char[] charset
{
get
{
if (_charset == null)
{
var sb = new StringBuilder();
for (int i = 2; i < 10; i++)
{
sb.Append(i.ToString());
}
for (int c = 'a'; c < 'z'; c++)
{
if (c == 'i' || c == 'x' || c == 'w'
|| c == 'o' || c == 'l' || c == 'u'
|| c == 'j' || c == 'z' || c == 'm'
|| c == 'c')
continue;
sb.Append((char)c);
}
for (int c = 'A'; c < 'Z'; c++)
{
if (c == 'I' || c == 'X' || c == 'W'
|| c == 'O' || c == 'U' || c == 'M'
|| c == 'J' || c == 'Z' || c == 'C')
continue;
sb.Append((char)c);
}
_charset = sb.ToString().ToCharArray();
}
return _charset;
}
}
public DateTimeOffset CreateDate { get; }
public Guid Id { get; }
private string Text { get; }
public byte[] Image { get; private set; }

public string ToBase64()
{
if (Image == null)
return string.Empty;
return Convert.ToBase64String(Image);
}

public bool Confirm(string text)
{
if (string.IsNullOrWhiteSpace(text))
return false;
return text == Text;
}


public Captcha()
{
Text = GenerateRandomText();
Image = DrawCaptcha(Text);
Id = Guid.NewGuid();
CreateDate = DateTimeOffset.UtcNow;
}
private readonly static string[] fonts = new string[3] {
"Arial", "Verdana", "Times New Roman" };
private byte[] DrawCaptcha(string text)
{
byte[] result = null;
float position = 0;
using (var img = new Image<Rgba32>(90, 40))
{
var x = 20;
var y = 8;
var backColor = Color.White;
img.Mutate(ctx => ctx.BackgroundColor(Color.White));
float maxX = 0;
for (int i = 0; i < text.Length; i++)
{
var c = text[i];
var random = new Random();

var font = SystemFonts.CreateFont(
fonts[random.Next(0, fonts.Length - 1)],
random.Next(24, 28),
random.Next(0, 1) == 0 ? FontStyle.Regular : FontStyle.Italic);
var location = new PointF(x + position, y + random.Next(0, 4));
img.Mutate(ctx => ctx.DrawText(c.ToString(), font, Color.Black, location));
position += TextMeasurer.Measure(c.ToString(), new RendererOptions(font, location)).Width - 4;
maxX = position;
var builder = new AffineTransformBuilder();
img.Mutate(ctx => ctx.Transform(
builder.PrependRotationDegrees((float)(random.NextDouble()), new PointF((float)2, (float)4))));
}
for (int i = 0; i < 2; i++)
{
var r = new Random();
img.Mutate(ctx => ctx.DrawLines(Color.Black, 2
, new PointF[] { new PointF(r.Next(20, 26), r.Next(8, 36)),
new PointF(r.Next(Convert.ToInt32(maxX+1),Convert.ToInt32(89)), r.Next(8, 36)) }));
}
using (var ms = new MemoryStream())
{
img.SaveAsPng(ms);
result = ms.ToArray();
}
}
return result;
}
private string GenerateRandomText()
{
var sb = new StringBuilder();
for (int i = 0; i < 5; i++)
{
var random = new Random();
var index = random.Next(0, charset.Length - 1);
sb.Append(charset[index]);
}
return sb.ToString();
}

public void Dispose()
{
Image = null;
}
}
}

// CaptchaManager

using System;
using System.Collections.Generic;
using System.Linq;

namespace ApsNetCoreCaptchaSample.Common
{
public static class CaptchaManager
{
private static readonly List<Captcha> captchas = new List<Captcha>();
public static (Guid Id, string Image) New()
{
using (var captcha = new Captcha())
{
captchas.Add(captcha);
return (captcha.Id, captcha.ToBase64());
}
}

public static bool Confirm(Guid id, string text)
{
captchas.RemoveAll(q => q.CreateDate < DateTimeOffset.UtcNow.AddMinutes(-2));
var captcha = captchas.SingleOrDefault(q => q.Id == id);
if (captcha != null && captcha.Confirm(text))
{
captchas.Remove(captcha);
return true;
}
return false;
}
}
}

// CaptchaController.cs

using ApsNetCoreCaptchaSample.Common;
using Microsoft.AspNetCore.Mvc;

namespace ApsNetCoreCaptchaSample.Controllers.Api
{
[Route("api/[controller]")]
[ApiController]
public class CaptchaController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
var captcha = CaptchaManager.New();
var response = new
{
id = captcha.Id,
image = captcha.Image
};
return Ok(response);
}
}
}

// HomeController.cs

using ApsNetCoreCaptchaSample.Common;
using ApsNetCoreCaptchaSample.ViewModels.Home;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace ApsNetCoreCaptchaSample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;

public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}

public IActionResult Index()
{
return View();
}

[HttpPost]
public string Index(IndexViewModel model)
{
return CaptchaManager.Confirm(model.CaptchaId, model.Captcha).ToString();
}
}
}


// IndexViewModel.cs

using System;

namespace ApsNetCoreCaptchaSample.ViewModels.Home
{
public class IndexViewModel
{
public string Captcha { get; set; }
public Guid CaptchaId { get; set; }
}
}

// Index.cshtml

@model ApsNetCoreCaptchaSample.ViewModels.Home.IndexViewModel
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Captcha Sample</title>
</head>
<body>
<form method="post">
<img id="captchaImage"/>
@Html.TextBoxFor(q => q.Captcha, new { placeholder = "Captcha" })
<br>
<input type="submit" id="send" name="send" value="Send">
@Html.HiddenFor(q => q.CaptchaId)
</form>

<script>
var captchaImage = document.getElementById('captchaImage');
var captchaId = document.getElementById('CaptchaId');

function newCaptcha() {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/captcha', true)
xhr.onreadystatechange = function () {
if (this.readyState != 4) return;
if (this.status == 200) {
var resp = JSON.parse(this.responseText);
captchaId.value = resp.id;
captchaImage.src = 'data:image/png;base64, ' + resp.image;
}
}
xhr.send();
}
captchaImage.addEventListener('click', function () {
newCaptcha();
});

newCaptcha();

</script>
</body>
</html>

30 Nisan 2020

HTML Tablo da Genişletilebilir Satır

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

    <style>
        .btnExp {
            border: 0px;
            background: transparent;
            font-weight: bold;
        }

        .hide {
            display: none;
        }

        .expBody {
            background-color: #f8f9fa;
            ;
        }
    </style>
</head>

<body>
    <table class="table expandableTable">
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">First</th>
                <th scope="col">Last</th>
                <th scope="col">Handle</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th scope="row">
                    <button type="button" class="btnExp">+</button>
                </th>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr class="expBody hide">
                <td colspan="4">XXX</td>
            </tr>
            <tr>
                <th scope="row">
                    <button class="btnExp">+</button>
                </th>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr class="expBody hide">
                <td colspan="4">ZZZ</td>
            </tr>
            <tr>
                <th scope="row">
                    <button class="btnExp">+</button>
                </th>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
            <tr class="expBody hide">
                <td colspan="4">YYY</td>
            </tr>
        </tbody>
    </table>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
        crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>

    <script>
        function hasClass(ele, cls) {
            return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
        }

        function addClass(ele, cls) {
            if (!hasClass(ele, cls)) ele.className += " " + cls;
        }

        function removeClass(ele, cls) {
            if (hasClass(ele, cls)) {
                var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
                ele.className = ele.className.replace(reg, ' ');
            }
        }

        function expandableTable() {
            var expandableTables = document.getElementsByClassName('expandableTable');
            if (expandableTables != null) {
                for (var t = 0; t < expandableTables.length; t++) {
                    tt = expandableTables[t];
                    var expBtns = tt.getElementsByClassName('btnExp');
                    if (expBtns != null) {
                        for (var b = 0; b < expBtns.length; b++) {
                            var expBtn = expBtns[b];
                            expBtn.addEventListener('click', function (e) {
                                var btn = e.srcElement;
                                var _tr = btn.parentElement.parentElement.nextElementSibling;
                                if (btn.innerText == '-') {
                                    btn.innerText = '+';
                                    addClass(_tr,'hide');
                                } else {
                                    btn.innerText = '-';
                                    removeClass(_tr,'hide');
                                }
                            }, false);
                        }
                    }
                }
            }
        }
        expandableTable();
    </script>
</body>
</html>
//

7 Ocak 2020

Javascript Table To CSV

function isTable(element) {
    return (element.tagName == 'TABLE' || element.tagName == 'table')
}
function downloadCsv(csv, filename) {
    if (window.Blob == undefined
        || window.URL == undefined
        || window.URL.createObjectURL == undefined) {
        alert("Your browser doesn't support Blobs");
        return;
    }
    var BOM = "\uFEFF";
    var csvFile = new Blob([ BOM + csv], { type: "text/csv;" });
    var downloadLink = document.createElement("a");
    downloadLink.download = filename;
    downloadLink.href = window.URL.createObjectURL(csvFile);
    downloadLink.style.display = "none";
    document.body.appendChild(downloadLink);
    downloadLink.click();
}

function exportToCsv(id, filename, delimiter = ';') {
    tbl = document.getElementById(id);
    if (tbl != null && isTable(tbl)) {
        var rowArr = [];
        for (var j = 0; j < tbl.rows.length; j++) {
            var r = tbl.rows[j];
            var colArr = [];
            for (i = 0; i < r.cells.length; i++) {
                var c = r.cells[i];
                colArr.push(c.innerText);
            }
            rowArr.push(colArr.join(delimiter))
        }
    }
    downloadCsv(rowArr.join('\n'), filename);
}

2 Ocak 2020

Javascript DateTime To Formatted String

function dateToFormat(date, template) { var t = template; var day = date.getDate(); if (t.indexOf('dd') > -1) { if (day < 10) day = `0${day}`; t = t.replace('dd', day); } else t = t.replace('d', day); var month = date.getMonth() + 1; if (t.indexOf('MM') > -1) { if (month < 10) month = `0${month}`; t = t.replace('MM', month); } else t = t.replace('M', month); var year = date.getFullYear(); if (t.indexOf('yyyy') > -1) t = t.replace('yyyy', year); else if (t.indexOf('yyy') > -1) t = t.replace('yyy', `${year}`.substring(1, 4)); else if (t.indexOf('yy') > -1) t = t.replace('yy', `${year}`.substring(2, 4)); else if (t.indexOf('y') > -1) t = t.replace('y', `${year}`.substring(3, 4)); var hour = date.getHours(); if (t.indexOf('HH') > -1) { if (hour < 10) hour = `0${hour}`; t = t.replace('HH', hour); } else t = t.replace('H', hour); var min = date.getMinutes(); if (t.indexOf('mm') > -1) { if (min < 10) min = `0${min}`; t = t.replace('mm', min); } else t = t.replace('m', min); var sec = date.getSeconds(); if (t.indexOf('ss') > -1) { if (sec < 10) sec = `0${sec}`; t = t.replace('ss', sec); } else t = t.replace('s', sec); return t; }