This commit is contained in:
2026-02-08 12:26:02 +03:30
commit 3732b9c0b8
51 changed files with 2503 additions and 0 deletions
+407
View File
@@ -0,0 +1,407 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
*.props
*.db
*.db-shm
*.db-wal
AsilCore/[Oo]bj/
AsilCore/[Oo]bj/
AsilCore/[Oo]bj/
BlazorWasm/[Oo]bj/
SubAsil.Api/[Oo]bj/
SubAsil.ConsoleApp/[Oo]bj/
SubAsil.Core/[Oo]bj/
SubAsil.DataLayer/[Oo]bj/
SubAsil.Models/[Oo]bj/
TelBot_Music.Console/[Oo]bj/
AsilCore/obj/
AsilCore/obj/
AsilCore/obj/
BlazorWasm/obj/
SubAsil.Api/obj/
SubAsil.ConsoleApp/obj/
SubAsil.Core/obj/
SubAsil.DataLayer/obj/
SubAsil.Models/obj/
TelBot_Music.Console/obj/
/SubAsil.Api/appsettings.json
/SubAsil.Api/appsettings.json
/SubAsil.Api/appsettings.json
.vscode
/SubAsil.Api/internal-nlog.txt
.idea/
**/obj
**/bin
+26
View File
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Mf.Core.Interfaces
{
public interface ICommand
{
}
public interface ICreateCommand<TEntity>: ICommand
{
}
public interface IUpdateCommand<TEntity> : ICommand
{
}
public interface IDeleteCommand<TEntity> : ICommand
{
}
}
+20
View File
@@ -0,0 +1,20 @@
using Mf.Core.SubEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mf.Core.Interfaces
{
public interface IContextCore
{
public IGenericService<TEntity> GetService<TEntity>() where TEntity : class, IEntity;
public object GetService(Type type);
public void Dispose();
public void Migrate();
}
}
+23
View File
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Mf.Core.Interfaces
{
public interface IEmailSender
{
string SendEmail(string subject, string address, string body);
string SendDataBaseEmail(string subject, string address, string body, string filePath);
}
public class EmailConfig
{
public string FromAddress { get; set; }
public string Password { get; set; }
public int Port { get; set; }
public string SmtAddress { get; set; }
}
}
+33
View File
@@ -0,0 +1,33 @@
using Mf.Core.SubEntities;
using Mf.Core.SubEntities.QueryModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mf.Core.Interfaces
{
public interface IGenericService<out TEntity> where TEntity : class, IEntity
{
public IEnumerable<TEntity> GetAll();
public IEnumerable<TEntity> GetList(QueryRequest? query = null);
#region Async MotimatDatabaseCore
public Task<IEntity> GetByIdAsync(CancellationToken cancellationToken, params object[] ids);
public Task<IEnumerable<IEntity>> AddRangeAsync(IEnumerable<IEntity> entities, CancellationToken cancellationToken, bool saveNow = true);
public Task<IEntity> UpdateAsync(object entity, CancellationToken cancellationToken, bool saveNow = true);
public Task<IEntity> DeleteAsync(object entity, CancellationToken cancellationToken, bool saveNow = true);
public Task<IEntity> AddAsync(object entity, CancellationToken cancellationToken, bool saveNow = true);
#endregion
}
}
+9
View File
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
@@ -0,0 +1,50 @@
namespace Mf.Core.OperationSystem
{
public static class OperationSystemService
{
public static OperationSystemType OS
{
get
{
PlatformID platform = Environment.OSVersion.Platform;
// Check if the operating system is Windows
if (platform == PlatformID.Win32NT || platform == PlatformID.Win32Windows)
{
Version version = Environment.OSVersion.Version;
return OperationSystemType.Windows;
// Retrieve and display the Windows version
}
else if (platform == PlatformID.Unix)
{
// Retrieve and display the Linux/Unix version
//string versionInfo = ExecuteCommand("uname -a");
//Console.WriteLine($"Version: {versionInfo}");
return OperationSystemType.Linux;
}
else
{
return OperationSystemType.Unknown;
}
}
}
public static string OperationSystemVersion
{
get
{
return System.Runtime.InteropServices.RuntimeInformation.OSDescription;
}
}
}
public enum OperationSystemType
{
Windows,
Linux,
Unknown
}
}
+151
View File
@@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mf.Core.Services
{
public static class DateService
{
public static DateTime GetStartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
{
int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
return dt.AddDays(-1 * diff).Date;
}
public static string ToShamsi(this DateTime DateTime1)
{
try
{
PersianCalendar PersianCalendar1 = new PersianCalendar();
return string.Format(@"{0}/{1}/{2} {3}:{4}:{5}",
PersianCalendar1.GetYear(DateTime1),
PersianCalendar1.GetMonth(DateTime1).ToString("00"),
PersianCalendar1.GetDayOfMonth(DateTime1).ToString("00"),
PersianCalendar1.GetHour(DateTime1).ToString("00"),
PersianCalendar1.GetMinute(DateTime1).ToString("00"),
PersianCalendar1.GetSecond(DateTime1).ToString("00")
);
}
catch (Exception ex)
{
return "Error";
}
}
public static string ToShamsiDate(this DateTime DateTime1)
{
PersianCalendar PersianCalendar1 = new PersianCalendar();
return string.Format(@"{0}/{1}/{2}",
PersianCalendar1.GetYear(DateTime1),
PersianCalendar1.GetMonth(DateTime1).ToString("00"),
PersianCalendar1.GetDayOfMonth(DateTime1).ToString("00"));
}
public static string ToShamsiClock(this DateTime dateTime)
{
PersianCalendar PersianCalendar1 = new PersianCalendar();
return string.Format(@"{0}:{1}",
PersianCalendar1.GetHour(dateTime).ToString("00"),
PersianCalendar1.GetMinute(dateTime).ToString("00"));
}
public static DateTime StringToDateTime(this string value)
{
string[] dateTmp = value.Split(' ');
string[] date = dateTmp[0].Split('/');
string[] time;
if (dateTmp.Length == 2)
{
time = dateTmp[1].Split(':');
}
else
time = new string[2] { "0", "0" };
//date = value.Split('/');
PersianCalendar persianCal = new PersianCalendar();
return persianCal.ToDateTime(Convert.ToInt16(date[0]), Convert.ToInt16(date[1]), Convert.ToInt16(date[2]), int.Parse(time[0]), int.Parse(time[1]), int.Parse(time[2]), 0);
return new DateTime(Convert.ToInt16(date[0]), Convert.ToInt16(date[1]), Convert.ToInt16(date[2]));
// return new JalaliDate(Convert.ToInt16(date[0]), Convert.ToByte(date[1]), Convert.ToByte(date[2])).ToDateTime().AddHours(double.Parse(time[0])).AddMinutes(double.Parse(time[1]));
}
public static DateTime StringDateToDateTime(this string value)
{
string[] dateTmp = value.Split(' ');
string[] date = dateTmp[0].Split('/');
string[] time;
if (dateTmp.Length == 2)
{
time = dateTmp[1].Split(':');
}
else
time = new string[2] { "0", "0" };
//date = value.Split('/');
PersianCalendar persianCal = new PersianCalendar();
return persianCal.ToDateTime(Convert.ToInt16(date[0]), Convert.ToInt16(date[1]), Convert.ToInt16(date[2]), int.Parse(time[0]), int.Parse(time[1]), 0, 0);
return new DateTime(Convert.ToInt16(date[0]), Convert.ToInt16(date[1]), Convert.ToInt16(date[2]));
// return new JalaliDate(Convert.ToInt16(date[0]), Convert.ToByte(date[1]), Convert.ToByte(date[2])).ToDateTime().AddHours(double.Parse(time[0])).AddMinutes(double.Parse(time[1]));
}
public static TimeSpan StringToTimeSpan(this string value)
{
try
{
var split = value.Split(":");
return new TimeSpan(int.Parse(split[0]), int.Parse(split[1]), int.Parse(split[2]));
}
catch (Exception ex)
{
//Console.WriteLine(ex);
return new TimeSpan();
}
}
public static string DayOfWeekShamsi(this DayOfWeek day)
{
switch (day)
{
case (DayOfWeek.Saturday):
return "شنبه";
break;
case (DayOfWeek.Sunday):
return "یک شنبه";
break;
case (DayOfWeek.Monday):
return "دو شنبه";
case (DayOfWeek.Tuesday):
return "سه شنبه";
case (DayOfWeek.Wednesday):
return "چهار شنبه";
case (DayOfWeek.Thursday):
return "پنج شنبه";
case (DayOfWeek.Friday):
return "جمعه";
default:
return "";
}
}
}
//public static class DateConvertor
//{
// public static string ToShamsi(this DateTime date)
// {
// PersianCalendar persian = new PersianCalendar();
// return persian.GetYear(date) + "/" + persian.GetMonth(date).ToString("00") + "/" + persian.GetDayOfMonth(date).ToString("00");
// }
//}
}
+72
View File
@@ -0,0 +1,72 @@
using Mf.Core.Interfaces;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Mail;
using System.Text;
namespace Mf.Core.Services
{
public class EmailSender : IEmailSender
{
public EmailConfig _config;
public EmailSender(EmailConfig config)
{
_config = config;
}
public string SendEmail(string subject, string address, string body)
{
try
{
SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
client.EnableSsl = true;
client.Credentials = new NetworkCredential(_config.FromAddress, _config.Password);
MailAddress from = new MailAddress(_config.FromAddress);
MailAddress to = new MailAddress(address);
MailMessage message = new MailMessage(from, to);
message.Body = body;
message.BodyEncoding = Encoding.UTF8;
message.Subject = subject;
message.SubjectEncoding = Encoding.UTF8;
client.Send(message);
message.Dispose();
return "Success";
}
catch (Exception ex)
{
return ex.Message.ToString();
}
}
public string SendDataBaseEmail(string subject, string address, string body, string filePath)
{
try
{
SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
client.EnableSsl = true;
client.Credentials = new NetworkCredential(_config.FromAddress, _config.Password);
MailAddress from = new MailAddress(_config.FromAddress);
MailAddress to = new MailAddress(address);
MailMessage message = new MailMessage(from, to);
message.Body = body;
message.BodyEncoding = Encoding.UTF8;
message.Subject = subject;
message.SubjectEncoding = Encoding.UTF8;
if (File.Exists(filePath))
{
Attachment attachment = new Attachment(filePath);
message.Attachments.Add(attachment);
}
client.Send(message);
message.Dispose();
return "Success";
}
catch (Exception ex)
{
return ex.Message.ToString();
}
}
}
}
+77
View File
@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Mf.Core.SubEntities
{
public abstract class BaseEntity<T> : IEntity
{
[Key]
[Display(Name = "شماره")]
public T Id { get; set; }
}
public abstract class BaseEntity : BaseEntity<long>
{
}
public static class BaseEntityService
{
public static IEnumerable<Type> GetModelsByAttribute(Type attribute)
{
Assembly assembly = Assembly.GetExecutingAssembly();
// همه‌ی تایپ‌های موجود در Assembly را دریافت می‌کنیم
Type[] types = assembly.GetTypes();
// لیستی برای نگهداری تایپ‌هایی که دارای Custom Attribute مورد نظر هستند
List<Type> typesWithCustomAttribute = new List<Type>();
var typess = from assemblyy in AppDomain.CurrentDomain.GetAssemblies()
from type in assemblyy.GetTypes()
where type.IsDefined(attribute)
select type;
// بررسی Custom Attribute هر تایپ
foreach (Type type in typess)
{
// بررسی Custom Attribute هر تایپ
var attributes = type.GetCustomAttributes(attribute, false);
if (attributes.Length > 0)
{
// این تایپ دارای Custom Attribute مورد نظر است
typesWithCustomAttribute.Add(type);
}
}
// چاپ نتیجه‌ی تایپ‌های دارای Custom Attribute مورد نظر
//-----------------------------------------------------------------------
//var types = from assembly in AppDomain.CurrentDomain.GetAssemblies()
// from type in assembly.GetTypes()
// where type.IsDefined(typeof(TableAttribute))
// select type;
return typesWithCustomAttribute;
var ass = typeof(BaseEntity).Assembly;
var all = ass.GetExportedTypes().Where(c => typeof(BaseEntity).IsAssignableFrom(c));
var aa = ass.GetExportedTypes().Where(c => c.IsClass && c.IsPublic && !c.IsAbstract && typeof(BaseEntity).IsAssignableFrom(c));
return aa;
// Assembly فعلی را دریافت می‌کنیم
}
}
}
+12
View File
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mf.Core.SubEntities
{
public interface IEntity
{
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace Mf.Core.SubEntities.QueryModel
{
public class Filter
{
public string Field { get; set; }
public string Operator { get; set; }
public string Value { get; set; }
}
}
@@ -0,0 +1,19 @@
namespace Mf.Core.SubEntities.QueryModel
{
public class QueryRequest
{
public string? ObjectType { get; set; }
public List<Filter> Filters { get; set; } = new();
public List<string> Includes { get; set; } = new();
public int? Skip { get; set; }
public int? Take { get; set; }
}
public class AlterRequest
{
public string? ObjectType { get; set; }
public object? Model { get; set; }
}
}
+17
View File
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mf.Core\Mf.Core.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,326 @@
using Microsoft.EntityFrameworkCore;
using Mf.Core.Interfaces;
using Mf.Core.SubEntities;
using Mf.Core.SubEntities.QueryModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace Mf.EfCore.Services
{
public class EntityFrameworkCoreServices<TEntity> : IGenericService<TEntity>, IDisposable
where TEntity : class, IEntity
{
protected readonly DbContext DbContext;
public DbSet<TEntity> Entities { get; }
public virtual IQueryable<TEntity> Table => Entities;
public virtual IQueryable<TEntity> TableNoTracking => Entities.AsNoTracking();
public EntityFrameworkCoreServices(DbContext dbContext)
{
DbContext = dbContext;
Entities = DbContext.Set<TEntity>(); // City => Cities
}
#region Async Method
public virtual async Task<TEntity> GetByIdAsync(CancellationToken cancellationToken, params object[] ids)
{
return await Entities.FindAsync(ids, cancellationToken).AsTask();
}
public virtual async Task<TEntity> AddAsync(TEntity entity, CancellationToken cancellationToken, bool saveNow = true)
{
var entityFull = await DbContext.AddAsync(entity, cancellationToken).ConfigureAwait(false);
if (saveNow)
{
try
{
await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
return null;
}
finally
{
entityFull.State = EntityState.Detached;
}
}
return entityFull.Entity;
}
public virtual async Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken, bool saveNow = true)
{
await Entities.AddRangeAsync(entities, cancellationToken).ConfigureAwait(false);
if (saveNow)
await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
return entities;
}
public virtual async Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken, bool saveNow = true)
{
var EntityState = Entities.Update(entity);
if (saveNow)
{
await DbContext.SaveChangesAsync(cancellationToken);
EntityState.State = Microsoft.EntityFrameworkCore.EntityState.Detached;
}
return entity;
}
public virtual async Task<IEnumerable<TEntity>> UpdateRangeAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken, bool saveNow = true)
{
Entities.UpdateRange(entities);
if (saveNow)
await DbContext.SaveChangesAsync(cancellationToken);
return entities;
}
public virtual async Task<TEntity> DeleteAsync(TEntity entity, CancellationToken cancellationToken, bool saveNow = true)
{
try
{
Entities.Remove(entity);
}
catch (Exception ex)
{
throw;
}
if (saveNow)
await DbContext.SaveChangesAsync(cancellationToken);
return entity;
}
public virtual async Task<IEnumerable<TEntity>> DeleteRangeAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken, bool saveNow = true)
{
Entities.RemoveRange(entities);
if (saveNow)
await DbContext.SaveChangesAsync(cancellationToken);
return entities;
}
#endregion
#region Sync Methods
public virtual TEntity GetById(params object[] ids)
{
return Entities.Find(ids);
}
public virtual void Add(TEntity entity, bool saveNow = true)
{
Entities.Add(entity);
if (saveNow)
DbContext.SaveChanges();
}
public virtual void AddRange(IEnumerable<TEntity> entities, bool saveNow = true)
{
Entities.AddRange(entities);
if (saveNow)
DbContext.SaveChanges();
}
public virtual void Update(TEntity entity, bool saveNow = true)
{
Entities.Update(entity);
DbContext.SaveChanges();
}
public virtual void UpdateRange(IEnumerable<TEntity> entities, bool saveNow = true)
{
Entities.UpdateRange(entities);
if (saveNow)
DbContext.SaveChanges();
}
public virtual void Delete(TEntity entity, bool saveNow = true)
{
Entities.Remove(entity);
if (saveNow)
DbContext.SaveChanges();
}
public virtual void DeleteRange(IEnumerable<TEntity> entities, bool saveNow = true)
{
Entities.RemoveRange(entities);
if (saveNow)
DbContext.SaveChanges();
}
#endregion
#region Attach & Detach
public virtual void Detach(TEntity entity)
{
var entry = DbContext.Entry(entity);
if (entry != null)
entry.State = EntityState.Detached;
}
public virtual void Attach(TEntity entity)
{
if (DbContext.Entry(entity).State == EntityState.Detached)
Entities.Attach(entity);
}
#endregion
#region Explicit Loading
public virtual async Task LoadCollectionAsync<TProperty>(TEntity entity, Expression<Func<TEntity, IEnumerable<TProperty>>> collectionProperty, CancellationToken cancellationToken)
where TProperty : class
{
Attach(entity);
var collection = DbContext.Entry(entity).Collection(collectionProperty);
if (!collection.IsLoaded)
await collection.LoadAsync(cancellationToken).ConfigureAwait(false);
}
public virtual void LoadCollection<TProperty>(TEntity entity, Expression<Func<TEntity, IEnumerable<TProperty>>> collectionProperty)
where TProperty : class
{
Attach(entity);
var collection = DbContext.Entry(entity).Collection(collectionProperty);
if (!collection.IsLoaded)
collection.Load();
}
public virtual async Task LoadReferenceAsync<TProperty>(TEntity entity, Expression<Func<TEntity, TProperty>> referenceProperty, CancellationToken cancellationToken)
where TProperty : class
{
Attach(entity);
var reference = DbContext.Entry(entity).Reference(referenceProperty);
if (!reference.IsLoaded)
await reference.LoadAsync(cancellationToken).ConfigureAwait(false);
}
public virtual void LoadReference<TProperty>(TEntity entity, Expression<Func<TEntity, TProperty>> referenceProperty)
where TProperty : class
{
Attach(entity);
var reference = DbContext.Entry(entity).Reference(referenceProperty);
if (!reference.IsLoaded)
reference.Load();
}
public void SaveChange()
{
DbContext.SaveChanges();
}
public async Task<bool> SaveChangeAsync()
{
await DbContext.SaveChangesAsync();
return true;
}
#endregion
public void Dispose()
{
DbContext.Dispose();
}
//TODO: Complte there
public IEnumerable<TEntity> GetAll()
{
return TableNoTracking;
}
async Task<IEntity> IGenericService<TEntity>.GetByIdAsync(CancellationToken cancellationToken, params object[] ids)
{
var res = await GetByIdAsync(cancellationToken, ids);
return (IEntity)res;
}
public Task<IEnumerable<IEntity>> AddRangeAsync(IEnumerable<IEntity> entities, CancellationToken cancellationToken, bool saveNow = true)
{
throw new NotImplementedException();
}
public async Task<IEntity> UpdateAsync(object entity, CancellationToken cancellationToken, bool saveNow = true)
{
var en = (TEntity)entity;
var result = await UpdateAsync(en, cancellationToken, saveNow);
return result;
}
public async Task<IEntity> AddAsync(object entity, CancellationToken cancellationToken, bool saveNow = true)
{
var b = (TEntity)entity;
var res = await AddAsync(b, cancellationToken, saveNow);
return res;
}
public async Task<IEntity> DeleteAsync(object entity, CancellationToken cancellationToken, bool saveNow = true)
{
var en = (TEntity)entity;
var result = await DeleteAsync(en, cancellationToken, saveNow);
return result;
}
public IEnumerable<TEntity> GetList(QueryRequest? query = null)
{
var products = TableNoTracking.AsQueryable();
if (query == null)
{
return products;
}
foreach (var include in query.Includes)
{
products = products.Include(include);
}
// 2. Apply Filters
foreach (var filter in query.Filters)
{
products = ApplyFilter(products, filter);
}
// 3. Apply Skip and Take
if (query.Skip.HasValue)
products = products.Skip(query.Skip.Value);
if (query.Take.HasValue)
products = products.Take(query.Take.Value);
return products;
}
private IQueryable<TEntity> ApplyFilter(IQueryable<TEntity> query, Filter filter)
{
var parameter = Expression.Parameter(typeof(TEntity), "x");
var property = Expression.Property(parameter, filter.Field);
var constant = Expression.Constant(Convert.ChangeType(filter.Value, property.Type));
Expression body = filter.Operator switch
{
"=" => Expression.Equal(property, constant),
">" => Expression.GreaterThan(property, constant),
">=" => Expression.GreaterThanOrEqual(property, constant),
"<" => Expression.LessThan(property, constant),
"<=" => Expression.LessThanOrEqual(property, constant),
"!=" => Expression.NotEqual(property, constant),
"Contains" => Expression.Call(property, nameof(string.Contains), Type.EmptyTypes, constant),
"StartsWith" => Expression.Call(property, nameof(string.Contains), Type.EmptyTypes, constant),
"EndsWith" => Expression.Call(property, nameof(string.Contains), Type.EmptyTypes, constant),
_ => throw new NotSupportedException($"Operator {filter.Operator} not supported.")
};
var lambda = Expression.Lambda<Func<TEntity, bool>>(body, parameter);
return query.Where(lambda);
}
}
}
+127
View File
@@ -0,0 +1,127 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Mf.Core.Interfaces;
using Mf.Core.SubEntities;
using System;
using System.Collections.Generic;
using System.Text;
namespace Mf.EfCore.Services
{
public class PostgresqlContextCore : DbContext, IContextCore
{
public PostgresqlContextCore(DbContextOptions optinos) : base(optinos) { }
public List<Type>? Entities { get; set; }
public IGenericService<TypeModel> GetService<TypeModel>() where TypeModel : class, IEntity
{
var telBotServiceType = typeof(EntityFrameworkCoreServices<>).MakeGenericType(typeof(TypeModel));
var constructor = telBotServiceType.GetConstructor(new[] { typeof(SqlServerContextCore) });
if (constructor != null)
{
var telBotServiceInstance = constructor.Invoke(new object[] { this });
return (EntityFrameworkCoreServices<TypeModel>)telBotServiceInstance;
}
else
{
var telBotServiceInstance = Activator.CreateInstance(telBotServiceType);
return (EntityFrameworkCoreServices<TypeModel>)telBotServiceInstance!;
}
}
public object GetService(Type type)
{
var telBotServiceType = typeof(EntityFrameworkCoreServices<>).MakeGenericType(type);
var constructor = telBotServiceType.GetConstructor(new[] { typeof(SqlServerContextCore) });
if (constructor != null)
{
var telBotServiceInstance = constructor.Invoke(new object[] { this });
return telBotServiceInstance;
}
else
{
var telBotServiceInstance = Activator.CreateInstance(telBotServiceType);
return telBotServiceInstance!;
}
}
public List<object> GetGenericServices(List<Type> entities)
{
List<object> services = new List<object>();
foreach (var type in entities)
{
var telBotServiceType = typeof(EntityFrameworkCoreServices<>).MakeGenericType(type);
// Get the constructor of the TelBot_Service<T> type
var constructor = telBotServiceType.GetConstructor(new[] { typeof(SqlServerContextCore) });
if (constructor != null)
{
// If constructor exists, create an instance with a parameter
var telBotServiceInstance = constructor.Invoke(new object[] { this }); // Provide the parameter value here
//var ssss = (IGenericService<IEntity>)telBotServiceInstance;
//var sss = (EntityFrameworkCoreServices<IEntity>)telBotServiceInstance;
services.Add(telBotServiceInstance);
}
else
{
// If no constructor exists, create an instance without parameters
var telBotServiceInstance = Activator.CreateInstance(telBotServiceType);
//var sss = (EntityFrameworkCoreServices<IEntity>)telBotServiceInstance;
services.Add(telBotServiceInstance);
}
}
return services;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
if (Entities != null)
{
foreach (var s in Entities)
{
var entity = modelBuilder.Entity(s);
}
//for postgres db
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
foreach (var property in entityType.GetProperties())
{
if (property.ClrType == typeof(DateTime))
{
property.SetValueConverter(new ValueConverter<DateTime, DateTime>(
v => v.Kind == DateTimeKind.Utc ? v : v.ToUniversalTime(), // ذخیره
v => DateTime.SpecifyKind(v, DateTimeKind.Utc) // بازیابی
));
}
else if (property.ClrType == typeof(DateTime?))
{
property.SetValueConverter(new ValueConverter<DateTime?, DateTime?>(
v => v.HasValue ? (v.Value.Kind == DateTimeKind.Utc ? v : v.Value.ToUniversalTime()) : v, // ذخیره
v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : v // بازیابی
));
}
}
}
}
}
void IContextCore.Dispose()
{
this.Dispose();
}
public void Migrate()
{
this.Migrate();
}
}
}
+129
View File
@@ -0,0 +1,129 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Mf.Core.Interfaces;
using Mf.Core.SubEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mf.EfCore.Services
{
public class SqlServerContextCore : DbContext, IContextCore
{
public SqlServerContextCore(DbContextOptions optinos) : base(optinos) { }
public List<Type>? Entities { get; set; }
public IGenericService<TypeModel> GetService<TypeModel>() where TypeModel : class, IEntity
{
var telBotServiceType = typeof(EntityFrameworkCoreServices<>).MakeGenericType(typeof(TypeModel));
var constructor = telBotServiceType.GetConstructor(new[] { typeof(SqlServerContextCore) });
if (constructor != null)
{
var telBotServiceInstance = constructor.Invoke(new object[] { this });
return (EntityFrameworkCoreServices<TypeModel>)telBotServiceInstance;
}
else
{
var telBotServiceInstance = Activator.CreateInstance(telBotServiceType);
return (EntityFrameworkCoreServices<TypeModel>)telBotServiceInstance!;
}
}
public object GetService(Type type)
{
var telBotServiceType = typeof(EntityFrameworkCoreServices<>).MakeGenericType(type);
var constructor = telBotServiceType.GetConstructor(new[] { typeof(SqlServerContextCore) });
if (constructor != null)
{
var telBotServiceInstance = constructor.Invoke(new object[] { this });
return telBotServiceInstance;
}
else
{
var telBotServiceInstance = Activator.CreateInstance(telBotServiceType);
return telBotServiceInstance!;
}
}
public List<object> GetGenericServices(List<Type> entities)
{
List<object> services = new List<object>();
foreach (var type in entities)
{
var telBotServiceType = typeof(EntityFrameworkCoreServices<>).MakeGenericType(type);
// Get the constructor of the TelBot_Service<T> type
var constructor = telBotServiceType.GetConstructor(new[] { typeof(SqlServerContextCore) });
if (constructor != null)
{
// If constructor exists, create an instance with a parameter
var telBotServiceInstance = constructor.Invoke(new object[] { this }); // Provide the parameter value here
//var ssss = (IGenericService<IEntity>)telBotServiceInstance;
//var sss = (EntityFrameworkCoreServices<IEntity>)telBotServiceInstance;
services.Add(telBotServiceInstance);
}
else
{
// If no constructor exists, create an instance without parameters
var telBotServiceInstance = Activator.CreateInstance(telBotServiceType);
//var sss = (EntityFrameworkCoreServices<IEntity>)telBotServiceInstance;
services.Add(telBotServiceInstance);
}
}
return services;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
if (Entities != null)
{
foreach (var s in Entities)
{
var entity = modelBuilder.Entity(s);
}
//for postgres db
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
foreach (var property in entityType.GetProperties())
{
if (property.ClrType == typeof(DateTime))
{
property.SetValueConverter(new ValueConverter<DateTime, DateTime>(
v => v.Kind == DateTimeKind.Utc ? v : v.ToUniversalTime(), // ذخیره
v => DateTime.SpecifyKind(v, DateTimeKind.Utc) // بازیابی
));
}
else if (property.ClrType == typeof(DateTime?))
{
property.SetValueConverter(new ValueConverter<DateTime?, DateTime?>(
v => v.HasValue ? (v.Value.Kind == DateTimeKind.Utc ? v : v.Value.ToUniversalTime()) : v, // ذخیره
v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : v // بازیابی
));
}
}
}
}
}
void IContextCore.Dispose()
{
this.Dispose();
}
public void Migrate()
{
this.Migrate();
}
}
}
+145
View File
@@ -0,0 +1,145 @@
using Microsoft.EntityFrameworkCore;
using Mf.Core.Interfaces;
using Mf.Core.SubEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mf.EfCore.Services
{
public abstract class SqliteContextCore : DbContext, IContextCore
{
public string DbName { get; set; }
public string DbPath { get; set; }
public List<Type> Entities { get; set; }
public void SetDefaultConfig()
{
DbName = "defualt-database-name.db";
DbPath = "";
}
public SqliteContextCore(bool setDefaultConfig = true)
{
if (setDefaultConfig)
{
SetDefaultConfig();
CreateDB();
}
}
public void CreateDB()
{
//TODO clean this
//var strDestination = "copy.db";
//string dir = Directory.GetCurrentDirectory();
//dir = Path.Combine(dir, strDestination);
//string orgDir = Path.Combine(Directory.GetCurrentDirectory(), DbPath, DbName);
//if (!Path.Exists(Path.Combine(Directory.GetCurrentDirectory(), DbPath)))
//{
// Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), DbPath));
//}
//if (!File.Exists(orgDir))
//{
// System.Data.SQLite.SQLiteConnection.CreateFile(orgDir);
//}
//if (!File.Exists(dir))
//{
// System.Data.SQLite.SQLiteConnection.CreateFile(dir);
//}
//using (var location = new System.Data.SQLite.SQLiteConnection(string.Format(@"Data Source={0};", orgDir)))
////using (var destination = new System.Data.SQLite.SQLiteConnection(string.Format(@"Data Source={0}", dir)))
//{
// location.Open();
// //destination.Open();
// //location.BackupDatabase(destination, "main", "main", -1, null, 0);
// //destination.Close();
//}
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite($"Data Source={DbPath}{DbName}");
}
public IGenericService<TypeModel> GetService<TypeModel>() where TypeModel : class, IEntity
{
var telBotServiceType = typeof(EntityFrameworkCoreServices<>).MakeGenericType(typeof(TypeModel));
var constructor = telBotServiceType.GetConstructor(new[] { typeof(SqliteContextCore) });
if (constructor != null)
{
var telBotServiceInstance = constructor.Invoke(new object[] { this });
return (EntityFrameworkCoreServices<TypeModel>)telBotServiceInstance;
}
else
{
var telBotServiceInstance = Activator.CreateInstance(telBotServiceType);
return (EntityFrameworkCoreServices<TypeModel>)telBotServiceInstance!;
}
}
public object GetService(Type type)
{
var telBotServiceType = typeof(EntityFrameworkCoreServices<>).MakeGenericType(type);
var constructor = telBotServiceType.GetConstructor(new[] { typeof(SqliteContextCore) });
if (constructor != null)
{
var telBotServiceInstance = constructor.Invoke(new object[] { this });
return telBotServiceInstance;
}
else
{
var telBotServiceInstance = Activator.CreateInstance(telBotServiceType);
return telBotServiceInstance!;
}
}
void IContextCore.Dispose()
{
this.Dispose();
}
public void Migrate()
{
try
{
this.Migrate();
}
catch
{
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
if (Entities != null)
{
foreach (var s in Entities)
{
var entity = modelBuilder.Entity(s);
}
}
}
}
}
+9
View File
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
+7
View File
@@ -0,0 +1,7 @@
namespace Mf.Entity.Tables;
public interface ITable
{
}
+21
View File
@@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
namespace Mf.Entity.Tables;
public abstract class TableBase<T>:ITable
{
[Key]
public T? Id { get; set; }
private List<TableBase<T>>? _seedData = null;
}
public abstract class Tablebase : TableBase<long>
{
public Tablebase()
{
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace Mf.Razor.Entity
{
public class Configuration
{
public int Radios { get; set; }
public Theme? Theme { get; set; }
}
}
@@ -0,0 +1,11 @@
using Mf.Razor.Entity.ViewModels;
namespace Mf.Razor.Entity.Interfaces;
public interface ICarouselService
{
public Task<CarouselVm> GetCarousel(int? carouselId = 0);
public Task<bool> ExecuteCarousel(CarouselVm carousel);
}
+36
View File
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mf.Razor.Entity.Interfaces
{
public interface IFrontLogger
{
void Log(string content, LogMode mode, TimeSpan time);
void Log(string content, LogMode mode);
void Log(string content);
List<LogModel> GetAllLogs();
void ClearLogs();
public static event EventHandler LogEvent;
}
public class LogModel
{
public string LogContent { get; set; }
public DateTime CreatedDate { get; set; }
public int index { get; set; }
public LogMode LogMode { get; set; }
public TimeSpan? Time { get; set; }
}
public enum LogMode
{
Info = 0,
Error = 1
}
}
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mf.Razor.Entity.Interfaces
{
public interface IServiceLocator
{
}
}
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Mf.Razor.Entity.Interfaces
{
public interface ITokenService
{
Task<string?> GetToken();
Task<bool> SetToken(string token);
Task<bool> RemoveToke();
}
}
+9
View File
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
+7
View File
@@ -0,0 +1,7 @@
namespace Mf.Razor.Entity
{
public class Theme
{
}
}
@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Mf.Razor.Entity.ViewModels;
[NotMapped]
public class CarouselItemVm
{
public int Index { get; set; }
public string? Title { get; set; }
public string? ImageAddress { get; set; }
public string? LinkAddress { get; set; }
public CarouselVm? Carousel{ get; set; }
}
@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Mf.Razor.Entity.ViewModels;
[NotMapped]
public class CarouselVm
{
public int Height { get; set; }
public int Width { get; set; }
public List<CarouselItemVm>? Items { get; set; }
}
+11
View File
@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Mf.Razor.Entity.ViewModels
{
[NotMapped]
public class Modal_Vm
{
public string? Title { get; set; }
public Guid Guid { get; set; }
}
}
@@ -0,0 +1,110 @@
using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using Mf.Razor.Entity.Interfaces;
using Mf.Razor.Services;
namespace Mf.Razor
{
public class CustomAuthStateProvider : AuthenticationStateProvider
{
private readonly ITokenService _tokenService;
private readonly LogService _logger;
public CustomAuthStateProvider(ITokenService tokenService,LogService logger)
{
_logger = logger;
_tokenService = tokenService;
}
public async Task SetToken(string tokenKey)
{
await _tokenService.SetToken(tokenKey);
}
public async Task<bool> RemoveToke()
{
try
{
await _tokenService.RemoveToke();
return true;
}
catch (Exception ex)
{
return false;
}
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
string token = await _tokenService.GetToken();
if (String.IsNullOrEmpty(token))
{
var state = new AuthenticationState(new ClaimsPrincipal());
NotifyAuthenticationStateChanged(Task.FromResult(state));
_logger.Log("Auth Is False");
return state;
}
var tokenHandler = new JwtSecurityTokenHandler();
try
{
tokenHandler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = false,
ValidateAudience = false,
RequireExpirationTime = true,
ValidateLifetime = true,
// Set clock skew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later by default)
ClockSkew = TimeSpan.Zero
}, out SecurityToken validatedToken);
var jwtToken = (JwtSecurityToken)validatedToken;
// Create ClaimsPrincipal from the token's claims
var claimsIdentity = new ClaimsIdentity(jwtToken.Claims, "jwt");
var user = new ClaimsPrincipal(claimsIdentity);
var state = new AuthenticationState(user);
NotifyAuthenticationStateChanged(Task.FromResult(state));
_logger.Log("Auth is ON");
return state;
}
catch (Exception)
{
// Token validation failed
var state = new AuthenticationState(new ClaimsPrincipal());
NotifyAuthenticationStateChanged(Task.FromResult(state));
_logger.Log("Auth Is False");
return state;
}
}
public static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
{
var payload = jwt.Split('.')[1];
var jsonBytes = ParseBase64WithoutPadding(payload);
var keyValuePairs = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonBytes);
return keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString()));
}
private static byte[] ParseBase64WithoutPadding(string base64)
{
switch (base64.Length % 4)
{
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
return Convert.FromBase64String(base64);
}
}
}
@@ -0,0 +1,51 @@
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace Mf.Razor
{
public static class JwtService
{
//static string securityAlgorithm = SecurityAlgorithms.HmacSha512Signature;
public static string CreateJwtToken(string securityKey, List<Claim> claims, TimeSpan? expireDate = null)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expires = new DateTime();
if(expireDate == null)
{
expires = DateTime.Now.AddDays(1);
}
else
{
expires = DateTime.Now.AddMinutes(expireDate.Value.TotalMinutes);
}
var token = new JwtSecurityToken(
"daliranpv.ir",
"your_audience",
claims,
expires: expires,
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
//var tokenHandler = new JwtSecurityTokenHandler();
//var key = Encoding.ASCII.GetBytes(Tokens.AuthenticaitonSystemOne.Key);
//var tokenDescriptor = new SecurityTokenDescriptor
//{
// Subject = new ClaimsIdentity(claims),
// Expires = DateTime.UtcNow.AddDays(7),
// SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
//};
//var token = tokenHandler.CreateToken(tokenDescriptor);
//return tokenHandler.WriteToken(token);
}
}
}
+3
View File
@@ -0,0 +1,3 @@
<div class="my-component">
This component is defined in the <strong>Mf.Razor</strong> library.
</div>
+6
View File
@@ -0,0 +1,6 @@
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
@@ -0,0 +1,24 @@
<div id="carouselExampleAutoplaying" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="carousel-content/felo.jpg" class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="carousel-content/ketabesal.jpg" class="d-block w-100" alt="...">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleAutoplaying" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleAutoplaying" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
@code{
}
@@ -0,0 +1,68 @@
/* GLOBAL STYLES
-------------------------------------------------- */
/* Padding below the footer and lighter body text */
/* CUSTOMIZE THE CAROUSEL
-------------------------------------------------- */
/* Carousel base class */
.carousel {
margin-top:1rem;
margin-bottom: 1rem;
}
/* Since positioning the image, we need to help out the caption */
.carousel-caption {
bottom: 3rem;
z-index: 10;
}
/* Declare heights because of positioning of img element */
.carousel-item {
}
/* MARKETING CONTENT
-------------------------------------------------- */
/* Center align the text within the three columns below the carousel */
.marketing .col-lg-4 {
margin-bottom: 1.5rem;
text-align: center;
}
.marketing .col-lg-4 p {
margin-right: .75rem;
margin-left: .75rem;
}
/* Featurettes
------------------------- */
.featurette-divider {
margin: 5rem 0; /* Space out the Bootstrap <hr> more */
}
/* Thin out the marketing headings */
/* RESPONSIVE CSS
-------------------------------------------------- */
@media (min-width: 40em) {
/* Bump up size of carousel content */
.carousel-caption p {
margin-bottom: 1.25rem;
font-size: 1.25rem;
line-height: 1.4;
}
.featurette-heading {
font-size: 50px;
}
}
@media (min-width: 62em) {
.featurette-heading {
margin-top: 7rem;
}
}
+99
View File
@@ -0,0 +1,99 @@
@using System.Globalization
@typeparam T
@* <input type="text"
inputmode="numeric"
pattern="[0-9\s]{13,19}"
autocomplete="cc-number"
maxlength="19"
placeholder="xxxx xxxx xxxx xxxx" />
*@
<input type="text" class="@Class"
inputmode="numeric"
value="@formattedValue"
onfocus="this.select()"
@oninput="OnInputChanged"
@onblur="OnBlur"
/>
@code {
[Parameter]
public T Value { get; set; }
[Parameter]
public EventCallback<T> ValueChanged { get; set; }
[Parameter]
public string? Class { get; set; }
[Parameter]
public string? Id { get; set; }
[Parameter]
public string? PlaceHolder { get; set; }
private string formattedValue = "";
protected override void OnParametersSet()
{
formattedValue = FormatValue(Value);
}
private void OnInputChanged(ChangeEventArgs e)
{
var raw = e.Value?.ToString()?.Replace(",", "").Trim() ?? "0";
var sss = new string(raw.Where(char.IsDigit).ToArray());
if (string.IsNullOrEmpty(sss))
{
formattedValue = "0";
return;
}
object? parsed = typeof(T) switch
{
var t when t == typeof(int) && int.TryParse(raw, out var intVal) => intVal,
var t when t == typeof(long) && long.TryParse(raw, out var longVal) => longVal,
var t when t == typeof(decimal) && decimal.TryParse(raw, out var decVal) => decVal,
_ => null
};
if (parsed is T tValue)
{
ValueChanged.InvokeAsync(tValue);
}
formattedValue = raw; // temporary display while editing
}
private void OnBlur()
{
formattedValue = FormatValue(Value);
}
private void OnFocus()
{
formattedValue = FormatValue(Value);
// formattedValue = Value?.ToString();
}
private string FormatValue(T val)
{
if (val == null) return "";
return val switch
{
int i => i.ToString("N0", CultureInfo.InvariantCulture),
long l => l.ToString("N0", CultureInfo.InvariantCulture),
decimal d => d.ToString("N0", CultureInfo.InvariantCulture),
_ => val.ToString() ?? ""
};
}
}
@@ -0,0 +1,4 @@
namespace Mf.Razor.Events
{
public delegate void ServiceLocatorDelegate();
}
+31
View File
@@ -0,0 +1,31 @@
using Microsoft.JSInterop;
namespace Mf.Razor;
// This class provides an example of how JavaScript functionality can be wrapped
// in a .NET class for easy consumption. The associated JavaScript module is
// loaded on demand when first needed.
//
// This class can be registered as scoped DI service and then injected into Blazor
// components for use.
public class ExampleJsInterop(IJSRuntime jsRuntime) : IAsyncDisposable
{
private readonly Lazy<Task<IJSObjectReference>> moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>(
"import", "./_content/Mf.Razor/exampleJsInterop.js").AsTask());
public async ValueTask<string> Prompt(string message)
{
var module = await moduleTask.Value;
return await module.InvokeAsync<string>("showPrompt", message);
}
public async ValueTask DisposeAsync()
{
if (moduleTask.IsValueCreated)
{
var module = await moduleTask.Value;
await module.DisposeAsync();
}
}
}
+11
View File
@@ -0,0 +1,11 @@
namespace Mf.Razor.Interfaces
{
public interface IModalService
{
public void Show();
public void Hide();
}
}
+6
View File
@@ -0,0 +1,6 @@
namespace Mf.Razor.Interfaces
{
public interface IServiceLocator
{
}
}
+27
View File
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.0"/>
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.15.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.15.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mf.Razor.Entity\Mf.Razor.Entity.csproj" />
</ItemGroup>
</Project>
+27
View File
@@ -0,0 +1,27 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Mf.Razor.Entity.Interfaces;
using Mf.Razor.Services;
namespace Mf.Razor
{
public static class RazorProvider
{
public static IServiceCollection AddBootstrap5(this IServiceCollection serviceCollection)
{
return serviceCollection;
}
public static IServiceCollection AddAuthentication(this IServiceCollection serviceCollection)
{
return serviceCollection;
}
public static IServiceCollection AddLogger(this IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<IFrontLogger, LogService>();
serviceCollection.AddSingleton<LogService>();
return serviceCollection;
}
}
}
+48
View File
@@ -0,0 +1,48 @@
using Mf.Razor.Entity.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace Mf.Razor.Services
{
public class LogService:IFrontLogger
{
private int indexer = 1;
public event EventHandler LogEvent;
private List<LogModel> LogComments { get; set; } = new List<LogModel>();
public virtual void Log(string content, LogMode mode, TimeSpan time)
{
LogComments.Add(new LogModel { CreatedDate = DateTime.Now,index = indexer,LogContent = content,LogMode = mode,Time = time});
indexer++;
LogEvent?.Invoke(null, EventArgs.Empty);
}
public virtual void Log(string content, LogMode mode)
{
LogComments.Add(new LogModel { CreatedDate = DateTime.Now, index = indexer, LogContent = content, LogMode = mode, Time = null });
indexer++;
LogEvent?.Invoke(null, EventArgs.Empty);
}
public virtual void Log(string content)
{
LogComments.Add(new LogModel { CreatedDate = DateTime.Now, index = indexer, LogContent = content, LogMode = LogMode.Info, Time = null });
indexer++;
LogEvent?.Invoke(null, EventArgs.Empty);
}
public virtual List<LogModel> GetAllLogs()
{
return LogComments.ToList();
}
public virtual void ClearLogs()
{
LogComments = new List<LogModel>();
indexer = 0;
Log("Clear Logs");
}
}
}
+55
View File
@@ -0,0 +1,55 @@
using Mf.Razor.Entity.Interfaces;
using Mf.Razor.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace Mf.Razor.Services
{
public class RequestService
{
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1); // دو درخواست همزمان
public async Task<T> ExecuteAsync<T>(Func<Task<T>> action)
{
await _semaphore.WaitAsync();
try
{
return await action();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
//ServiceLocator.Log($"Error Limiter : {ex.Message}");
return await action();
}
finally
{
//ServiceLocator.Log($"Relase : {DateTime.Now.ToString()}");
_semaphore.Release();
}
}
public async Task ExecuteAsync(Func<Task> action)
{
await _semaphore.WaitAsync();
try
{
await action();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
//ServiceLocator.Log($"Error Limiter : {ex.Message}");
await action();
}
finally
{
//ServiceLocator.Log($"Relase : {DateTime.Now.ToString()}");
_semaphore.Release();
}
}
}
}
+49
View File
@@ -0,0 +1,49 @@
using Mf.Razor.Events;
using Mf.Razor.Interfaces;
namespace Mf.Razor.Services
{
internal abstract class ServiceLocator : IServiceLocator
{
internal IServiceProvider _serviceProvider;
protected ServiceLocator(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
private event ServiceLocatorDelegate? Update;
public int EventNumbers { get; private set; } = 0;
public virtual Task InvokeUpdate()
{
Update?.Invoke();
return Task.CompletedTask;
}
public virtual void AddEvent(ServiceLocatorDelegate input)
{
try
{
Update += input;
EventNumbers++;
}
catch (Exception ex)
{
}
}
public virtual void RemoveEvent(ServiceLocatorDelegate input)
{
try
{
Update -= input;
EventNumbers--;
}
catch (Exception ex)
{
}
}
}
}
+1
View File
@@ -0,0 +1 @@
@using Microsoft.AspNetCore.Components.Web
Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

+6
View File
@@ -0,0 +1,6 @@
// This is a JavaScript module that is loaded on demand. It can export any number of
// functions, and may import other JavaScript modules if required.
export function showPrompt(message) {
return prompt(message, 'Type anything here');
}
+49
View File
@@ -0,0 +1,49 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mf.Core", "Mf.Core\Mf.Core.csproj", "{365652A1-EDFD-4102-B9FD-117EACFCCCC6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mf.Entity", "Mf.Entity\Mf.Entity.csproj", "{BE3FD258-BC5E-45F5-831C-7EAFB37D398C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mf.Ef", "Mf.Ef\Mf.Ef.csproj", "{9D5D4C17-9C3E-4104-8A87-7AB660B71762}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Razors", "Razors", "{5493F5AB-AEC8-4D51-AC9E-513C1505D8A2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{ED63E99B-0EF8-4CEB-B4B5-BE795DE9FF78}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mf.Razor", "Mf.Razor\Mf.Razor.csproj", "{09763D74-4477-47A8-AE59-B9E90D9AD64F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mf.Razor.Entity", "Mf.Razor.Entity\Mf.Razor.Entity.csproj", "{9FADD8A4-A17E-4F24-96D6-E58D66471324}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{365652A1-EDFD-4102-B9FD-117EACFCCCC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{365652A1-EDFD-4102-B9FD-117EACFCCCC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{365652A1-EDFD-4102-B9FD-117EACFCCCC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{365652A1-EDFD-4102-B9FD-117EACFCCCC6}.Release|Any CPU.Build.0 = Release|Any CPU
{BE3FD258-BC5E-45F5-831C-7EAFB37D398C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE3FD258-BC5E-45F5-831C-7EAFB37D398C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE3FD258-BC5E-45F5-831C-7EAFB37D398C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE3FD258-BC5E-45F5-831C-7EAFB37D398C}.Release|Any CPU.Build.0 = Release|Any CPU
{9D5D4C17-9C3E-4104-8A87-7AB660B71762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D5D4C17-9C3E-4104-8A87-7AB660B71762}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D5D4C17-9C3E-4104-8A87-7AB660B71762}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D5D4C17-9C3E-4104-8A87-7AB660B71762}.Release|Any CPU.Build.0 = Release|Any CPU
{09763D74-4477-47A8-AE59-B9E90D9AD64F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09763D74-4477-47A8-AE59-B9E90D9AD64F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09763D74-4477-47A8-AE59-B9E90D9AD64F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09763D74-4477-47A8-AE59-B9E90D9AD64F}.Release|Any CPU.Build.0 = Release|Any CPU
{9FADD8A4-A17E-4F24-96D6-E58D66471324}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FADD8A4-A17E-4F24-96D6-E58D66471324}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FADD8A4-A17E-4F24-96D6-E58D66471324}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FADD8A4-A17E-4F24-96D6-E58D66471324}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{ED63E99B-0EF8-4CEB-B4B5-BE795DE9FF78} = {5493F5AB-AEC8-4D51-AC9E-513C1505D8A2}
{09763D74-4477-47A8-AE59-B9E90D9AD64F} = {ED63E99B-0EF8-4CEB-B4B5-BE795DE9FF78}
{9FADD8A4-A17E-4F24-96D6-E58D66471324} = {ED63E99B-0EF8-4CEB-B4B5-BE795DE9FF78}
EndGlobalSection
EndGlobal