diff --git a/Directory.Packages.props b/Directory.Packages.props
index b9c94c0106..f5cf8871de 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -107,7 +107,6 @@
-
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
index aa16e3931c..ee660f72e4 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
@@ -592,6 +592,8 @@
"OrganizationId": "Organization Id",
"RemoveAllWinnersConfirmationMessage": "Are you sure you want to remove all winners?",
"AutoRenewals": "Auto Renewals",
- "OrganizationHasCreditCard": "Organization has credit card. Please remove credit card first!"
+ "OrganizationHasCreditCard": "Organization has credit card. Please remove credit card first!",
+ "DisplayName:DontSendEmailForLicenseExpire": "Don't Send Email For License Expire",
+ "DontSendEmailForLicenseExpire": "Don't Send Email For License Expire"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
index f2f4bf8d41..29a4cf27d3 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
@@ -1131,6 +1131,7 @@
"NameOnCard": "Name on Card",
"BillingDetails": "Billing Details",
"ThereIsNoDeveloper": "There is no developer.",
- "CardDetails": "Card Details"
+ "CardDetails": "Debit/Credit Card Details",
+ "NoActiveLicence": "You are not eligible for this action! You have no active license."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
index 963546d9a3..7151345ea9 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
@@ -255,6 +255,8 @@
"LatestArticles": "أحدث المقالات",
"RaffleHeader": "مرحبًا عضو مجتمع برنامج الجسر الأكاديمي!",
"RafflesInfo": " هذه هي صفحة السحب المخصصة لإظهار تقديرنا لك لكونك عضوًا نشطًا في المجتمع. نحن نقوم بإجراء محادثات مجتمعية لبرنامج ABP، ومؤتمر ABP .NET ، ونحضر أو نرعى الأحداث المتعلقة بـ .NET والتي نقدم فيها بعض الهدايا.
يمكنك متابعة هذه الصفحة لرؤية السحوبات القادمة أو حضورها أو الاطلاع على السحوبات السابقة التي قمنا بسحبها بما في ذلك الفائزين.
شكرا لكونك عضوا نشطا! نراكم في السحوبات القادمة.",
- "RafflesInfoTitle": "سحوبات مجتمع ABP"
+ "RafflesInfoTitle": "سحوبات مجتمع ABP",
+ "MarkdownSupported": "Markdown أيد.",
+ "Preview": "معاينة"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json
index 418cf5aef1..252b0dcb2b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json
@@ -255,6 +255,8 @@
"LatestArticles": "poslední články",
"RaffleHeader": "Dobrý den, člen komunity ABP!",
"RafflesInfo": " Toto je stránka s losováním věnovaná tomu, abychom vám ukázali naše uznání za to, že jste aktivním členem komunity. Pořádáme ABP Community Talks, ABP .NET Conference , účastníme se nebo sponzorujeme akce související s .NET, ve kterých rozdáváme nějaké dárky.
Na této stránce můžete sledovat nadcházející tomboly, zúčastnit se jich nebo si prohlédnout předchozí tomboly, které losujeme, včetně výherců.
Děkujeme, že jste aktivním členem! Uvidíme se v nadcházejícím slosování.",
- "RafflesInfoTitle": "Komunitní tomboly ABP"
+ "RafflesInfoTitle": "Komunitní tomboly ABP",
+ "MarkdownSupported": "Markdown podporováno.",
+ "Preview": "Náhled"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json
index 021c19b3ff..4326ff88ef 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de.json
@@ -255,6 +255,8 @@
"LatestArticles": "Neueste Artikel",
"RaffleHeader": "Hallo ABP-Community-Mitglied!",
"RafflesInfo": " Auf dieser Verlosungsseite möchten wir Ihnen unsere Wertschätzung dafür zeigen, dass Sie ein aktives Community-Mitglied sind. Wir veranstalten ABP Community Talksund ABP .NET Conferences , nehmen an .NET-bezogenen Veranstaltungen teil oder sponsern diese, bei denen wir einige Geschenke verschenken.
Sie können dieser Seite folgen, um die bevorstehenden Verlosungen zu sehen, daran teilzunehmen oder frühere Verlosungen, die wir verlosen, einschließlich der Gewinner, anzusehen.
Vielen Dank, dass Sie ein aktives Mitglied sind! Wir sehen uns bei den kommenden Gewinnspielen.",
- "RafflesInfoTitle": "ABP-Community- Verlosungen"
+ "RafflesInfoTitle": "ABP-Community- Verlosungen",
+ "MarkdownSupported": "Markdown unterstützt.",
+ "Preview": "Vorschau"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
index 0283b963bc..347b18ce4b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
@@ -103,6 +103,8 @@
"Language": "Language",
"CreatePostLanguageInfo": "Language of the post",
"SeeMore": "See More",
- "MemberNotPublishedPostYet": "This member hasn't published any posts yet."
+ "MemberNotPublishedPostYet": "This member hasn't published any posts yet.",
+ "MarkdownSupported": "Markdown supported.",
+ "Preview": "Preview"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
index fa10d9c408..b22fc19de8 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
@@ -256,6 +256,8 @@
"RaffleHeader": "Hello ABP Community Member!",
"RafflesInfo": " This is the raffle page dedicated to show our appreciation towards you for being an active Community Member. We do ABP Community Talks,ABP .NET Conference, attend or sponsor to the .NET-related events in which we give away some gifts.
You can follow this page to see the upcoming raffles, attend them, or see previous raffles we draw including the winners.
Thank you for being an active member! See you in the upcoming raffles.",
"RafflesInfoTitle": "ABP Community Raffles",
- "ToLuckyWinner": "to 1 lucky winner"
+ "ToLuckyWinner": "to 1 lucky winner",
+ "MarkdownSupported": "Markdown supported.",
+ "Preview": "Preview"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
index c4e178bbd9..c53b45ab81 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
@@ -255,6 +255,8 @@
"LatestArticles": "últimos artículos",
"RaffleHeader": "¡Hola miembro de la comunidad ABP!",
"RafflesInfo": " Esta es la página del sorteo dedicada a mostrarle nuestro agradecimiento por ser un miembro activo de la comunidad. Realizamos charlas comunitarias de ABP, conferencias ABP .NET , asistimos o patrocinamos eventos relacionados con .NET en los que regalamos algunos obsequios.
Puedes seguir esta página para ver los próximos sorteos, asistir a ellos o ver sorteos anteriores que sorteamos incluyendo a los ganadores.
¡Gracias por ser un miembro activo! Nos vemos en los próximos sorteos.",
- "RafflesInfoTitle": "Rifas de la Comunidad ABP"
+ "RafflesInfoTitle": "Rifas de la Comunidad ABP",
+ "MarkdownSupported": "Markdown soportado.",
+ "Preview": "Avance"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
index ac509875d6..abd8cdd21f 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
@@ -255,6 +255,8 @@
"LatestArticles": "Viimeisimmät artikkelit",
"RaffleHeader": "Hei ABP-yhteisön jäsen!",
"RafflesInfo": " Tämä on arvontasivu, joka on omistettu osoittamaan kiitollisuuttamme sinua kohtaan, että olet aktiivinen yhteisön jäsen. Teemme ABP Community Talksia, ABP .NET -konferenssia , osallistumme tai sponsoroimme .NET-tapahtumia, joissa annamme lahjoja.
Voit seurata tätä sivua nähdäksesi tulevat arvonnat, osallistua niihin tai nähdäksesi aiemmat arvonnamme, mukaan lukien voittajat.
Kiitos aktiivisesta jäsenyydestäsi! Nähdään tulevissa arvonnassa.",
- "RafflesInfoTitle": "ABP-yhteisön arpajaiset"
+ "RafflesInfoTitle": "ABP-yhteisön arpajaiset",
+ "MarkdownSupported": "Markdown tuettu.",
+ "Preview": "Esikatselu"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
index c98a48d93e..1f259aac6d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
@@ -255,6 +255,8 @@
"LatestArticles": "Derniers articles",
"RaffleHeader": "Bonjour membre de la communauté ABP !",
"RafflesInfo": " Ceci est la page de tirage au sort dédiée à vous montrer notre gratitude pour votre participation active à la communauté. Nous organisons des discussions communautaires ABP, des conférences ABP .NET , assistons ou sponsorisons des événements liés à .NET au cours desquels nous offrons des cadeaux.
Vous pouvez suivre cette page pour voir les tirages au sort à venir, y assister ou voir les tirages au sort précédents que nous tirons, y compris les gagnants.
Merci d'être un membre actif ! Rendez-vous lors des prochains tirages au sort.",
- "RafflesInfoTitle": "Tirages au sort communautaires ABP"
+ "RafflesInfoTitle": "Tirages au sort communautaires ABP",
+ "MarkdownSupported": "Markdown prise en charge.",
+ "Preview": "Aperçu"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
index f3d300e8a2..b868260ae6 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
@@ -255,6 +255,8 @@
"LatestArticles": "नवीनतम लेख",
"RaffleHeader": "नमस्ते एबीपी समुदाय सदस्य!",
"RafflesInfo": " यह रैफ़ल पेज है जो एक सक्रिय समुदाय सदस्य होने के लिए आपके प्रति हमारी सराहना दिखाने के लिए समर्पित है। हम एबीपी सामुदायिक वार्ता, एबीपी .NET सम्मेलन करते हैं, .NET से संबंधित कार्यक्रमों में भाग लेते हैं या प्रायोजित करते हैं जिसमें हम कुछ उपहार देते हैं।
आप आगामी रैफ़ल देखने, उनमें भाग लेने, या विजेताओं सहित हमारे द्वारा निकाले गए पिछले रैफ़ल देखने के लिए इस पृष्ठ का अनुसरण कर सकते हैं।
सक्रिय सदस्य बनने के लिए धन्यवाद! आगामी रैफ़ल में मिलते हैं।",
- "RafflesInfoTitle": "एबीपी कम्युनिटी रैफल्स"
+ "RafflesInfoTitle": "एबीपी कम्युनिटी रैफल्स",
+ "MarkdownSupported": "Markdown का समर्थन किया।",
+ "Preview": "पूर्व दर्शन"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json
index 5b3546a78b..eb3b66d9c8 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hr.json
@@ -255,6 +255,8 @@
"LatestArticles": "Najnoviji članci",
"RaffleHeader": "Pozdrav članu ABP zajednice!",
"RafflesInfo": " Ovo je stranica za nagradnu igru namijenjena da vam pokažemo našu zahvalnost što ste aktivni član zajednice. Vodimo razgovore o ABP zajednici, ABP .NET konferenciji , prisustvujemo ili sponzoriramo događaje vezane uz .NET na kojima dijelimo neke darove.
Možete pratiti ovu stranicu kako biste vidjeli nadolazeće nagradne igre, prisustvovali im ili vidjeli prethodne nagradne igre koje izvlačimo uključujući dobitnike.
Hvala vam što ste aktivan član! Vidimo se u nadolazećim nagradnim igrama.",
- "RafflesInfoTitle": "Izvlačenje nagradne igre zajednice ABP"
+ "RafflesInfoTitle": "Izvlačenje nagradne igre zajednice ABP",
+ "MarkdownSupported": "Markdown podržan.",
+ "Preview": "Pregled"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json
index 1f74f9e7a9..08917573ff 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json
@@ -255,6 +255,8 @@
"LatestArticles": "Legfrissebb cikkek",
"RaffleHeader": "Kedves ABP közösségi tag!",
"RafflesInfo": " Ez az a sorsolási oldal, amelynek célja, hogy kifejezzük hálánkat feléd, amiért aktív közösségi tag vagy. Az ABP Community Talks-okat, az ABP .NET konferenciákat szervezzük, részt veszünk vagy szponzorálunk olyan .NET-hez kapcsolódó eseményeket, amelyeken ajándékokat adunk.
Ezt az oldalt követheti, hogy megtekinthesse a közelgő sorsolásokat, részt vegyen azokon, vagy megtekinthesse korábbi sorsolásainkat, beleértve a nyerteseket is.
Köszönjük, hogy aktív tag vagy! Találkozunk a sorsoláson.",
- "RafflesInfoTitle": "ABP közösségi tombola"
+ "RafflesInfoTitle": "ABP közösségi tombola",
+ "MarkdownSupported": "Markdown támogatott.",
+ "Preview": "Előnézet"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
index a991c387d4..0d8eb6cb48 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
@@ -255,6 +255,8 @@
"LatestArticles": "Nýjustu greinar",
"RaffleHeader": "Halló ABP samfélagsmeðlimur!",
"RafflesInfo": " Þetta er happdrættisíðan sem er tileinkuð þér að þakka þér fyrir að vera virkur samfélagsmeðlimur. Við gerum ABP Community Talks, ABP .NET ráðstefnu , sækjum eða styrkjum .NET tengda viðburði þar sem við gefum nokkrar gjafir.
Þú getur fylgst með þessari síðu til að sjá komandi happdrætti, mæta á þær eða sjá fyrri happdrætti sem við drögum út, þar á meðal vinningshafa.
Þakka þér fyrir að vera virkur meðlimur! Sjáumst í komandi happdrætti.",
- "RafflesInfoTitle": "ABP samfélagshappdrætti"
+ "RafflesInfoTitle": "ABP samfélagshappdrætti",
+ "MarkdownSupported": "Markdown stutt.",
+ "Preview": "Forskoðun"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
index 901c356c9a..a301a7f482 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
@@ -255,6 +255,8 @@
"LatestArticles": "Articoli Recenti",
"RaffleHeader": "Ciao membro della comunità ABP!",
"RafflesInfo": " Questa è la pagina della lotteria dedicata a mostrare il nostro apprezzamento nei tuoi confronti per essere un membro attivo della comunità. Organizziamo ABP Community Talks, ABP .NET Conference , partecipiamo o sponsorizziamo eventi relativi a .NET in cui regaliamo alcuni regali.
Puoi seguire questa pagina per vedere le prossime lotterie, parteciparvi o vedere le lotterie precedenti che estraiamo, compresi i vincitori.
Grazie per essere un membro attivo! Ci vediamo alle prossime lotterie.",
- "RafflesInfoTitle": "Lotterie comunitarie ABP"
+ "RafflesInfoTitle": "Lotterie comunitarie ABP",
+ "MarkdownSupported": "Markdown supportato.",
+ "Preview": "Anteprima"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json
index 4ee8e44a09..45b3024c96 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json
@@ -255,6 +255,8 @@
"LatestArticles": "Laatste artikels",
"RaffleHeader": "Hallo ABP Community-lid!",
"RafflesInfo": " Dit is de loterijpagina die bedoeld is om onze waardering voor u te tonen omdat u een actief lid van de community bent. We houden ABP Community Talks, ABP .NET Conference , wonen of sponsoren de .NET-gerelateerde evenementen bij waarin we een aantal geschenken weggeven.
U kunt deze pagina volgen om de komende loterijen te zien, deze bij te wonen of eerdere loterijen te zien die we trekken, inclusief de winnaars.
Bedankt dat u een actief lid bent! Tot ziens bij de komende loterijen.",
- "RafflesInfoTitle": "ABP- gemeenschaploterijen"
+ "RafflesInfoTitle": "ABP- gemeenschaploterijen",
+ "MarkdownSupported": "Markdown ondersteund.",
+ "Preview": "Voorbeeld"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json
index 2df6780f03..124f910ac0 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json
@@ -255,6 +255,8 @@
"LatestArticles": "ostatnie artykuły",
"RaffleHeader": "Witaj, członku społeczności ABP!",
"RafflesInfo": " To jest strona loterii, której celem jest wyrażenie naszego uznania dla Ciebie za bycie aktywnym członkiem społeczności. Prowadzimy rozmowy społecznościowe ABP, konferencje ABP .NET , uczestniczymy lub sponsorujemy wydarzenia związane z .NET, podczas których rozdajemy prezenty.
Możesz śledzić tę stronę, aby zobaczyć nadchodzące loterie, wziąć w nich udział lub zobaczyć poprzednie loterie, które losowaliśmy, w tym zwycięzców.
Dziękujemy za bycie aktywnym członkiem! Do zobaczenia w nadchodzących loteriach.",
- "RafflesInfoTitle": "Loterie społecznościowe ABP"
+ "RafflesInfoTitle": "Loterie społecznościowe ABP",
+ "MarkdownSupported": "Markdown utrzymany.",
+ "Preview": "Zapowiedź"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json
index 9f2ce433d9..419ef77140 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json
@@ -255,6 +255,8 @@
"LatestArticles": "Artigos Mais Recentes",
"RaffleHeader": "Olá, membro da comunidade ABP!",
"RafflesInfo": " Esta é a página do sorteio dedicada a mostrar nosso agradecimento por você ser um membro ativo da comunidade. Fazemos ABP Community Talks, ABP .NET Conference , participamos ou patrocinamos eventos relacionados ao .NET nos quais distribuímos alguns presentes.
Você pode seguir esta página para ver os próximos sorteios, participar deles ou ver os sorteios anteriores que sorteamos, incluindo os vencedores.
Obrigado por ser um membro ativo! Nos vemos nos próximos sorteios.",
- "RafflesInfoTitle": "Sorteios da Comunidade ABP"
+ "RafflesInfoTitle": "Sorteios da Comunidade ABP",
+ "MarkdownSupported": "Markdown suportado.",
+ "Preview": "Visualização"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
index c2862d1fd7..47e513f125 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
@@ -255,6 +255,8 @@
"LatestArticles": "ultimele articole",
"RaffleHeader": "Bună ziua, membru al comunității ABP!",
"RafflesInfo": " Aceasta este pagina de tombolă dedicată pentru a arăta aprecierea noastră față de dvs. pentru că sunteți un membru activ al comunității. Facem ABP Community Talks, ABP .NET Conference , participăm sau sponsorizăm evenimentele legate de .NET în care oferim câteva cadouri.
Puteți urmări această pagină pentru a vedea tombolele viitoare, a participa la ele sau pentru a vedea tombolele anterioare pe care le extragem, inclusiv câștigătorii.
Vă mulțumim că sunteți un membru activ! Ne vedem la tombolele viitoare.",
- "RafflesInfoTitle": "Tombole comunitare ABP"
+ "RafflesInfoTitle": "Tombole comunitare ABP",
+ "MarkdownSupported": "Markdown sprijinit.",
+ "Preview": "previzualizare"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json
index 27f2b1203a..b91893ce94 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json
@@ -258,6 +258,8 @@
"LatestArticles": "Последние статьи",
"RaffleHeader": "Привет, участник сообщества ABP!",
"RafflesInfo": " Эта страница розыгрыша посвящена тому, чтобы выразить нашу признательность вам за то, что вы являетесь активным членом сообщества. Обсуждения сообщества ABP,Конференция ABP .NET, посещать или спонсировать мероприятия, связанные с .NET, на которых мы раздаем подарки.
Вы можете подписаться на эту страницу, чтобы увидеть предстоящие розыгрыши, посетить их или просмотреть предыдущие розыгрыши, которые мы проводим, включая победителей.
Спасибо за активное участие! ",
- "RafflesInfoTitle": "Сообщество АБП Розыгрыши"
+ "RafflesInfoTitle": "Сообщество АБП Розыгрыши",
+ "MarkdownSupported": "Markdown поддерживается.",
+ "Preview": "Предварительный просмотр"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
index 6ab3c9d074..25a73a6bd7 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
@@ -255,6 +255,8 @@
"LatestArticles": "Najnovšie články",
"RaffleHeader": "Dobrý deň, člen komunity ABP!",
"RafflesInfo": " Toto je stránka žrebovania venovaná na vyjadrenie nášho uznania vám za to, že ste aktívnym členom komunity. Robíme ABP Community Talks, ABP .NET konferenciu , zúčastňujeme sa alebo sponzorujeme podujatia súvisiace s .NET, na ktorých rozdávame nejaké darčeky.
Na tejto stránke si môžete pozrieť pripravované tomboly, zúčastniť sa ich alebo si pozrieť predchádzajúce žrebovanie, ktoré vyžrebujeme vrátane výhercov.
Ďakujeme, že ste aktívnym členom! Vidíme sa v najbližšom žrebovaní.",
- "RafflesInfoTitle": "Komunitné tomboly ABP"
+ "RafflesInfoTitle": "Komunitné tomboly ABP",
+ "MarkdownSupported": "Markdown podporované.",
+ "Preview": "Náhľad"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json
index 23763c6f78..b6192142c6 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json
@@ -255,6 +255,8 @@
"LatestArticles": "Najnovejši članki",
"RaffleHeader": "Pozdravljeni član skupnosti ABP!",
"RafflesInfo": " To je stran za nagradno igro, namenjena izkazovanju naše hvaležnosti do vas, ker ste aktivni član skupnosti. Izvajamo ABP Community Talks, ABP .NET Conference , se udeležujemo ali sponzoriramo dogodke, povezane z .NET, na katerih podarimo nekaj daril.
To stran lahko spremljate in si ogledate prihajajoče nagradne igre, se jih udeležite ali si ogledate prejšnje nagradne igre, ki smo jih izžrebali, vključno z zmagovalci.
Hvala, ker ste aktivni član! Se vidimo na prihajajočih nagradnih igrah.",
- "RafflesInfoTitle": "Žrebanje skupnosti ABP"
+ "RafflesInfoTitle": "Žrebanje skupnosti ABP",
+ "MarkdownSupported": "Markdown podprt.",
+ "Preview": "Predogled"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
index 2d52d01ed2..88c88208e8 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
@@ -189,6 +189,8 @@
"Layout_MetaDescription": "ABP Topluluğu, insanların ABP çerçevesi hakkında paylaşımlarda bulunabileceği ve projeleri takip edebileceği bir ortamdır.",
"Index_Page_CommunityIntroduction": "Burası ABP Çerçevesi, .NET ve yazılım geliştirme için bir merkezdir. Makaleleri okuyabilir, eğitim videolarını izleyebilir, ABP'nin gelişim süreci ve ABP ile ilgili etkinlikler hakkında bilgi alabilir, diğer geliştiricilere yardımcı olabilir ve uzmanlığınızı ABP topluluğu ile paylaşabilirsiniz.",
"IConsentToMedium": "Bu yazının https://medium.com/volosoft adresinde yayınlanmasına izin veriyorum.",
- "DiscordPageTitle": "ABP Discord Topluluğu"
+ "DiscordPageTitle": "ABP Discord Topluluğu",
+ "MarkdownSupported": "Markdown destekleniyor.",
+ "Preview": "Ön izleme"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json
index a36ec9b0e8..e195a80fa5 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json
@@ -255,6 +255,8 @@
"LatestArticles": "Bài viết mới nhất",
"RaffleHeader": "Xin chào Thành viên Cộng đồng ABP!",
"RafflesInfo": " Đây là trang xổ số dành riêng để thể hiện sự đánh giá cao của chúng tôi đối với bạn vì đã trở thành Thành viên cộng đồng tích cực. Chúng tôi tổ chức các buổi nói chuyện cộng đồng ABP, Hội nghị ABP .NET , tham dự hoặc tài trợ cho các sự kiện liên quan đến .NET mà trong đó chúng tôi tặng một số quà tặng.
Bạn có thể theo dõi trang này để xem các cuộc xổ số sắp tới, tham dự hoặc xem các cuộc xổ số trước đây mà chúng tôi rút ra bao gồm cả những người chiến thắng.
Cảm ơn bạn đã là thành viên tích cực! Hẹn gặp lại các bạn trong đợt xổ số sắp tới.",
- "RafflesInfoTitle": "Xổ số cộng đồng ABP"
+ "RafflesInfoTitle": "Xổ số cộng đồng ABP",
+ "MarkdownSupported": "Markdown được hỗ trợ.",
+ "Preview": "Xem trước"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
index e899a94872..fd1130b894 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
@@ -255,6 +255,8 @@
"LatestArticles": "最新文章",
"RaffleHeader": "你好,ABP 社区成员!",
"RafflesInfo": " 这是一个抽奖页面,旨在感谢您成为活跃的社区成员。我们举办 ABP 社区讲座、ABP .NET 会议,参加或赞助与 .NET 相关的活动,并在活动中赠送一些礼品。
您可以关注此页面,查看即将举行的抽奖活动、参加这些活动或查看我们以前举行的抽奖活动(包括获奖者)。
感谢您成为我们的活跃成员!在即将举行的抽奖活动中再见。",
- "RafflesInfoTitle": "ABP 社区来抽奖来抽奖Markdown 支持的。",
+ "Preview": "预览"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json
index ebec42dd8a..e5725ce996 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json
@@ -255,6 +255,8 @@
"LatestArticles": "最新的文章",
"RaffleHeader": "ABP 社群成員您好!",
"RafflesInfo": " 這是抽獎頁面,旨在表達我們對您作為活躍社區成員的感謝。我們舉辦ABP 社群講座、ABP .NET 會議、參加或贊助 .NET 相關活動,並在活動中贈送一些禮物。
您可以關注此頁面查看即將舉行的抽獎活動、參加抽獎活動或查看我們之前抽獎的抽獎活動(包括獲獎者)。
感謝您成為活躍會員!在即將到來的抽獎活動中再見。",
- "RafflesInfoTitle": "ABP 社區萊佛士"
+ "RafflesInfoTitle": "ABP 社區萊佛士",
+ "MarkdownSupported": "Markdown 支持的。",
+ "Preview": "预览"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
index d1bc23b308..ec2d301a29 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
@@ -353,6 +353,8 @@
"BuildSolutionsWithAbp": "Build maintainable .NET solutions by following software development best practices using ABP.",
"BuyOnAmazon": "Buy on Amazon",
"BuyOnPackt": "Buy on Packt",
+ "BuyOnDangDang": "Buy on DangDang",
+ "BuyOnJD": "Buy on JD",
"Discounted": "Discounted",
"MasteringAbpFramework_Book_KeyFeatures": "Key Features",
"MasteringAbpFramework_Book_Key_Features_Description_1": "Build robust, maintainable, modular, and scalable software solutions using ABP Framework.",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
index 9fb6a08b32..88d56a6303 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hans.json
@@ -353,6 +353,8 @@
"BuildSolutionsWithAbp": "使用 ABP,遵循软件开发最佳实践,构建可维护的 .NET 解决方案。",
"BuyOnAmazon": "在亚马逊上购买",
"BuyOnPackt": "在 Packt 购买",
+ "BuyOnDangDang": "在当当网购买",
+ "BuyOnJD": "在京东上购买",
"Discounted": "折扣",
"MasteringAbpFramework_Book_KeyFeatures": "主要功能",
"MasteringAbpFramework_Book_Key_Features_Description_1": "使用 ABP 框架构建稳健、可维护、模块化和可扩展的软件解决方案。",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
index 81664b5f8d..dc396ce8b9 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/zh-Hant.json
@@ -353,6 +353,8 @@
"BuildSolutionsWithAbp": "使用 ABP 遵循軟體開發最佳實務來建立可維護的 .NET 解決方案。",
"BuyOnAmazon": "在亞馬遜上購買",
"BuyOnPackt": "在 Packt 上購買",
+ "BuyOnDangDang": "在當當上購買",
+ "BuyOnJD": "在京東上購買",
"Discounted": "折扣",
"MasteringAbpFramework_Book_KeyFeatures": "主要特徵",
"MasteringAbpFramework_Book_Key_Features_Description_1": "使用 ABP 框架建構健壯、可維護、模組化和可擴展的軟體解決方案。",
diff --git a/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md
new file mode 100644
index 0000000000..285d7d5dc9
--- /dev/null
+++ b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/Post.md
@@ -0,0 +1,72 @@
+# Use Deepl to translate localization files
+
+Translating localized text during the development of ABP modules is a boring job. For this reason, we have added the `translate` command to the CLI tool to translate the localization files, but it still requires manual translation of texts by the developer.
+
+Now, we introduce a new way to translate the target language, which is to use the [Deepl](https://www.deepl.com/translator) translation service to translate the target language.
+
+You can use the `translate --online` command in your module directory to translate the target language.
+
+For example, if you have added all `en` localization texts to your module, and you want to translate them to `zh-Hans`, you can run the following command:
+
+```
+abp translate -r en -c zh-Hans --online --deepl-auth-key your_auth_key
+```
+
+* `-r` parameter is used to specify the source language. It is usually a localized file that you have created.
+* `-c` parameter is used to specify the target language. It is usually a language that you want to translate.
+* `--online` parameter is used to indicate that the translation is performed from the Deepl service.
+* `--deepl-auth-key` parameter is the API key of your Deepl account. You can get it from [here](https://support.deepl.com/hc/en-us/articles/360020695820-Authentication-Key).
+
+
+The output of the above command is as follows:
+
+```
+ABP CLI 8.0.0
+Abp translate online...
+Target culture: zh-Hans
+Reference culture: en
+Create translation: Settings => 设置
+Create translation: SuccessfullySaved => 成功保存
+Create translation: Permission:SettingManagement => 设置管理
+Create translation: Permission:Emailing => 发送电子邮件
+Create translation: Permission:EmailingTest => 电子邮件测试
+Create translation: Permission:TimeZone => 时区
+Create translation: SendTestEmail => 发送测试电子邮件
+Create translation: SenderEmailAddress => 发件人电子邮件地址
+Create translation: TargetEmailAddress => 目标电子邮件地址
+Create translation: Subject => 主题
+Create translation: Body => 正文
+Create translation: TestEmailSubject => 测试电子邮件 {0}
+Create translation: TestEmailBody => 在此测试电子邮件正文信息
+Create translation: SuccessfullySent => 成功发送
+Create translation: Send => 发送
+Create translation: Menu:Emailing => 发送电子邮件
+Create translation: Menu:TimeZone => 时区
+Create translation: DisplayName:Timezone => 时区
+Create translation: TimezoneHelpText => 此设置用于应用程序范围或基于租户的设置。
+Create translation: SmtpHost => 主机
+Create translation: SmtpPort => 端口
+Create translation: SmtpUserName => 用户名
+Create translation: SmtpPassword => 密码
+Create translation: SmtpDomain => 域名
+Create translation: SmtpEnableSsl => 启用 ssl
+Create translation: SmtpUseDefaultCredentials => 使用默认凭据
+Create translation: DefaultFromAddress => 默认地址
+Create translation: DefaultFromDisplayName => 显示名称的默认值
+Create translation: Feature:SettingManagementGroup => 设置管理
+Create translation: Feature:SettingManagementEnable => 启用设置管理
+Create translation: Feature:SettingManagementEnableDescription => 在应用程序中启用设置管理系统。
+Create translation: Feature:AllowChangingEmailSettings => 允许更改电子邮件设置。
+Create translation: Feature:AllowChangingEmailSettingsDescription => 允许更改电子邮件设置。
+Write translation json to setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hans.json.
+```
+
+The generated `zh-Hans.json` as follow:
+
+
+
+In this example, It only translates one `en.json` to `zh-Hans.json`, but if there are multiple `en.json` files in the module, it will translate all `en.json` files to `zh-Hans.json`.
+
+Of course, the translation is not always correct, you can update the translation in the generated `zh-Hans.json` files.
+
+Enjoy it!
diff --git a/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/deepl.jpg b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/deepl.jpg
new file mode 100644
index 0000000000..c54b9840f0
Binary files /dev/null and b/docs/en/Community-Articles/2024-01-04-CLI-Online-Translate/deepl.jpg differ
diff --git a/docs/en/Migration-Guides/Abp-8_1.md b/docs/en/Migration-Guides/Abp-8_1.md
new file mode 100644
index 0000000000..6f4c316d3f
--- /dev/null
+++ b/docs/en/Migration-Guides/Abp-8_1.md
@@ -0,0 +1,85 @@
+# ABP Version 8.1 Migration Guide
+
+This document is a guide for upgrading ABP v8.0 solutions to ABP v8.1. There are some changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application.
+
+## Added `NormalizedName` property to `Tenant`
+
+The `Tenant` entity has a new property called `NormalizedName`. It is used to find/cache a tenant by its name in a case-insensitive way.
+This property is automatically set when a tenant is created or updated. It gets the normalized name of the tenant name by `UpperInvariantTenantNormalizer(ITenantNormalizer)` service. You can implement this service to change the normalization logic.
+
+### `ITenantStore`
+
+The `ITenantStore` will use the `NormalizedName` parameter to get tenants, Please use the `ITenantNormalizer` to normalize the tenant name before calling the `ITenantStore` methods.
+
+### Update `NormalizedName` in `appsettings.json`
+
+If your tenants defined in the `appsettings.json` file, you should add the `NormalizedName` property to your tenants.
+
+````json
+"Tenants": [
+ {
+ "Id": "446a5211-3d72-4339-9adc-845151f8ada0",
+ "Name": "tenant1",
+ "NormalizedName": "TENANT1" // <-- Add this property
+ },
+ {
+ "Id": "25388015-ef1c-4355-9c18-f6b6ddbaf89d",
+ "Name": "tenant2",
+ "NormalizedName": "TENANT2", // <-- Add this property
+ "ConnectionStrings": {
+ "Default": "...tenant2's db connection string here..."
+ }
+ }
+ ]
+````
+
+### Update `NormalizedName` in the database
+
+Please add a sql script to your migration to set the `NormalizedName` property of the existing tenants. You can use the following script:
+
+> This script is for the SQL Server database. You can change it for your database.
+
+> The table name `SaasTenants` is used for ABP commercial Saas module. `AbpTenants` is for the ABP open-source Tenant Management module.
+
+```sql
+UPDATE SaasTenants SET NormalizedName = UPPER(Name) WHERE NormalizedName IS NULL OR NormalizedName = ''
+```
+
+```csharp
+///
+public partial class Add_NormalizedName : Migration
+{
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "NormalizedName",
+ table: "SaasTenants",
+ type: "nvarchar(64)",
+ nullable: false,
+ defaultValue: "");
+
+ migrationBuilder.Sql("UPDATE SaasTenants SET NormalizedName = UPPER(Name) WHERE NormalizedName IS NULL OR NormalizedName = ''");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_SaasTenants_NormalizedName",
+ table: "SaasTenants",
+ column: "NormalizedName");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropIndex(
+ name: "IX_SaasTenants_NormalizedName",
+ table: "SaasTenants");
+
+ migrationBuilder.DropColumn(
+ name: "NormalizedName",
+ table: "SaasTenants");
+ }
+}
+```
+
+See https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/managing?tabs=dotnet-core-cli#adding-raw-sql to learn how to add raw SQL to migrations.
+
diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md
index 661d99da16..922976767d 100644
--- a/docs/en/Multi-Tenancy.md
+++ b/docs/en/Multi-Tenancy.md
@@ -394,6 +394,8 @@ app.UseMultiTenancy();
`ITenantStore` is used to get the tenant configuration from a data source.
+> Tenant names are not case-sensitive. `ITenantStore` will use the `NormalizedName` parameter to get tenants, You need to use `ITenantNormalizer` to normalize tenant names.
+
#### Tenant Management Module
The [tenant management module](Modules/Tenant-Management) is **included in the startup templates** and implements the `ITenantStore` interface to get the tenants and their configuration from a database. It also provides the necessary functionality and UI to manage the tenants and their connection strings.
@@ -408,11 +410,13 @@ The [tenant management module](Modules/Tenant-Management) is **included in the s
"Tenants": [
{
"Id": "446a5211-3d72-4339-9adc-845151f8ada0",
- "Name": "tenant1"
+ "Name": "tenant1",
+ "NormalizedName": "TENANT1"
},
{
"Id": "25388015-ef1c-4355-9c18-f6b6ddbaf89d",
"Name": "tenant2",
+ "NormalizedName": "TENANT2",
"ConnectionStrings": {
"Default": "...tenant2's db connection string here..."
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs
index d17a2b6f87..3873b48db3 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs
@@ -23,13 +23,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency
Cache = cache;
}
- public async Task FindAsync(string name)
+ public async Task FindAsync(string normalizedName)
{
- var cacheKey = CreateCacheKey(name);
+ var cacheKey = CreateCacheKey(normalizedName);
var tenantConfiguration = await Cache.GetOrAddAsync(
cacheKey,
- async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))!,
+ async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(normalizedName))!,
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow =
@@ -57,13 +57,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency
return tenantConfiguration;
}
- public TenantConfiguration? Find(string name)
+ public TenantConfiguration? Find(string normalizedName)
{
- var cacheKey = CreateCacheKey(name);
+ var cacheKey = CreateCacheKey(normalizedName);
var tenantConfiguration = Cache.GetOrAdd(
cacheKey,
- () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name)))!,
+ () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(normalizedName)))!,
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow =
@@ -98,16 +98,16 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency
return null;
}
- return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name!);
+ return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name!, tenantResultDto.NormalizedName!);
}
- protected virtual string CreateCacheKey(string tenantName)
+ protected virtual string CreateCacheKey(string normalizedName)
{
- return $"RemoteTenantStore_Name_{tenantName}";
+ return $"RemoteTenantStore_Name_{normalizedName}";
}
protected virtual string CreateCacheKey(Guid tenantId)
{
return $"RemoteTenantStore_Id_{tenantId:N}";
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs
index 310add4bfc..520e2944f6 100644
--- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs
@@ -8,6 +8,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
@@ -15,7 +16,7 @@ using Volo.Abp.Settings;
namespace Volo.Abp.AspNetCore.MultiTenancy;
-public class MultiTenancyMiddleware : IMiddleware, ITransientDependency
+public class MultiTenancyMiddleware : AbpMiddlewareBase, ITransientDependency
{
public ILogger Logger { get; set; }
@@ -38,7 +39,7 @@ public class MultiTenancyMiddleware : IMiddleware, ITransientDependency
_options = options.Value;
}
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
TenantConfiguration? tenant = null;
try
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs
index e0c450b8b4..1bc7856ca6 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs
@@ -29,9 +29,9 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
Options = options.Value;
}
- public async Task FindAsync(string name)
+ public async Task FindAsync(string normalizedName)
{
- var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(name);
+ var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName);
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext)
@@ -42,7 +42,7 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
var tenantConfiguration = await Cache.GetAsync(cacheKey);
if (tenantConfiguration == null)
{
- await TenantAppService.FindTenantByNameAsync(name);
+ await TenantAppService.FindTenantByNameAsync(normalizedName);
tenantConfiguration = await Cache.GetAsync(cacheKey);
}
@@ -79,9 +79,9 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
return tenantConfiguration?.Value;
}
- public TenantConfiguration? Find(string name)
+ public TenantConfiguration? Find(string normalizedName)
{
- var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(name);
+ var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName);
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext)
@@ -92,7 +92,7 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency
var tenantConfiguration = Cache.Get(cacheKey);
if (tenantConfiguration == null)
{
- AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByNameAsync(name));
+ AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByNameAsync(normalizedName));
tenantConfiguration = Cache.Get(cacheKey);
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs
index 599b0b8a67..1de5f942dc 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs
@@ -11,5 +11,7 @@ public class FindTenantResultDto
public string? Name { get; set; }
+ public string? NormalizedName { get; set; }
+
public bool IsActive { get; set; }
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelperService.cs
index 671b00e094..8b46f6e78c 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelperService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelperService.cs
@@ -90,13 +90,13 @@ public class AbpModalFooterTagHelperService : AbpTagHelperService FindTenantByNameAsync(string name)
{
- var tenant = await TenantStore.FindAsync(name);
+ var tenant = await TenantStore.FindAsync(TenantNormalizer.NormalizeName(name)!);
if (tenant == null)
{
@@ -29,6 +31,7 @@ public class AbpTenantAppService : ApplicationService, IAbpTenantAppService
Success = true,
TenantId = tenant.Id,
Name = tenant.Name,
+ NormalizedName = tenant.NormalizedName,
IsActive = tenant.IsActive
};
}
@@ -47,6 +50,7 @@ public class AbpTenantAppService : ApplicationService, IAbpTenantAppService
Success = true,
TenantId = tenant.Id,
Name = tenant.Name,
+ NormalizedName = tenant.NormalizedName,
IsActive = tenant.IsActive
};
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs
index f6711be826..94a6760df3 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs
@@ -18,13 +18,16 @@ public class TenantSwitchModalModel : AbpPageModel
public TenantInfoModel Input { get; set; } = default!;
protected ITenantStore TenantStore { get; }
+ protected ITenantNormalizer TenantNormalizer { get; }
protected AbpAspNetCoreMultiTenancyOptions Options { get; }
public TenantSwitchModalModel(
ITenantStore tenantStore,
+ ITenantNormalizer tenantNormalizer,
IOptions options)
{
TenantStore = tenantStore;
+ TenantNormalizer = tenantNormalizer;
Options = options.Value;
LocalizationResourceType = typeof(AbpUiMultiTenancyResource);
}
@@ -45,7 +48,7 @@ public class TenantSwitchModalModel : AbpPageModel
Guid? tenantId = null;
if (!Input.Name.IsNullOrEmpty())
{
- var tenant = await TenantStore.FindAsync(Input.Name!);
+ var tenant = await TenantStore.FindAsync(TenantNormalizer.NormalizeName(Input.Name!)!);
if (tenant == null)
{
throw new UserFriendlyException(L["GivenTenantIsNotExist", Input.Name!]);
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js
index 51c7db5cd9..4a11feeda2 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js
@@ -103,6 +103,13 @@ var abp = abp || {};
abp.libs.sweetAlert.config.default.confirmButtonText = l('Ok');
abp.libs.sweetAlert.config.default.denyButtonText = l('No');
abp.libs.sweetAlert.config.default.cancelButtonText = l('Cancel');
+ abp.libs.sweetAlert.config.default.buttonsStyling = false;
+ abp.libs.sweetAlert.config.default.customClass = {
+ confirmButton: "btn btn-primary",
+ cancelButton: "btn btn-outline-primary mx-2",
+ denyButton: "btn btn-outline-primary mx-2"
+ };
+
abp.libs.sweetAlert.config.confirm.title = l('AreYouSure');
abp.libs.sweetAlert.config.confirm.confirmButtonText = l('Yes');
abp.libs.sweetAlert.config.confirm.showCancelButton = true;
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
index c9b5984843..a2f2c1c989 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
@@ -14,6 +14,7 @@ using System.Linq;
using System.Net;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.DataAnnotations;
using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -25,6 +26,7 @@ using Volo.Abp.ApiVersioning;
using Volo.Abp.Application;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Volo.Abp.AspNetCore.Mvc.ApiExploring;
+using Volo.Abp.AspNetCore.Mvc.ApplicationModels;
using Volo.Abp.AspNetCore.Mvc.Conventions;
using Volo.Abp.AspNetCore.Mvc.DataAnnotations;
using Volo.Abp.AspNetCore.Mvc.DependencyInjection;
@@ -176,6 +178,7 @@ public class AbpAspNetCoreMvcModule : AbpModule
context.Services.Replace(ServiceDescriptor.Singleton());
context.Services.AddSingleton();
+ context.Services.TryAddEnumerable(ServiceDescriptor.Transient());
context.Services.AddOptions()
.Configure((mvcOptions, serviceProvider) =>
{
@@ -247,7 +250,7 @@ public class AbpAspNetCoreMvcModule : AbpModule
.Distinct();
AddToApplicationParts(partManager, controllerAssemblies);
-
+
var additionalAssemblies = moduleContainer
.Modules
.SelectMany(m => m.GetAdditionalAssemblies())
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs
new file mode 100644
index 0000000000..1ae2180e47
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcActionDescriptorProvider.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Abstractions;
+using Microsoft.AspNetCore.Mvc.Controllers;
+using Volo.Abp.AspNetCore.Filters;
+
+namespace Volo.Abp.AspNetCore.Mvc.ApplicationModels;
+
+public class AbpMvcActionDescriptorProvider : IActionDescriptorProvider
+{
+ public virtual int Order => -1000 + 10;
+
+ public virtual void OnProvidersExecuting(ActionDescriptorProviderContext context)
+ {
+ }
+
+ public virtual void OnProvidersExecuted(ActionDescriptorProviderContext context)
+ {
+ foreach (var action in context.Results.Where(x => x is ControllerActionDescriptor).Cast())
+ {
+ var disableAbpFeaturesAttribute = action.ControllerTypeInfo.GetCustomAttribute(true);
+ if (disableAbpFeaturesAttribute != null && disableAbpFeaturesAttribute.DisableMvcFilters)
+ {
+ action.FilterDescriptors.RemoveAll(x => x.Filter is ServiceFilterAttribute serviceFilterAttribute &&
+ typeof(IAbpFilter).IsAssignableFrom(serviceFilterAttribute.ServiceType));
+ }
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs
index 07101da0cb..d982adb12a 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs
@@ -5,12 +5,13 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using Volo.Abp.Aspects;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.Auditing;
-public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency
+public class AbpAuditActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs
index 8445be60ae..6b97ac980a 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs
@@ -5,12 +5,13 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using Volo.Abp.Aspects;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.Auditing;
-public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency
+public class AbpAuditPageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency
{
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
index 61e37104ee..a63e557198 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
@@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.ExceptionHandling;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.Authorization;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ExceptionHandling;
@@ -18,7 +19,7 @@ using Volo.Abp.Json;
namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
-public class AbpExceptionFilter : IAsyncExceptionFilter, ITransientDependency
+public class AbpExceptionFilter : IAsyncExceptionFilter, IAbpFilter, ITransientDependency
{
public virtual async Task OnExceptionAsync(ExceptionContext context)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs
index 31784cb6ea..97c21268fe 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs
@@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.ExceptionHandling;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.Authorization;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ExceptionHandling;
@@ -18,7 +19,7 @@ using Volo.Abp.Json;
namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
-public class AbpExceptionPageFilter : IAsyncPageFilter, ITransientDependency
+public class AbpExceptionPageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency
{
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs
index b4b70a5e1a..35bb9ba572 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeatureActionFilter.cs
@@ -2,12 +2,13 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Volo.Abp.Aspects;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
namespace Volo.Abp.AspNetCore.Mvc.Features;
-public class AbpFeatureActionFilter : IAsyncActionFilter, ITransientDependency
+public class AbpFeatureActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs
index 3c586f762b..a35764c43c 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs
@@ -2,12 +2,13 @@
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Volo.Abp.Aspects;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
namespace Volo.Abp.AspNetCore.Mvc.Features;
-public class AbpFeaturePageFilter : IAsyncPageFilter, ITransientDependency
+public class AbpFeaturePageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency
{
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs
index aae85e4d25..34f125f228 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeatureActionFilter.cs
@@ -6,12 +6,13 @@ using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Aspects;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.DependencyInjection;
using Volo.Abp.GlobalFeatures;
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures;
-public class GlobalFeatureActionFilter : IAsyncActionFilter, ITransientDependency
+public class GlobalFeatureActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs
index 46455730a4..3c43301221 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/GlobalFeatures/GlobalFeaturePageFilter.cs
@@ -6,12 +6,13 @@ using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Aspects;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.DependencyInjection;
using Volo.Abp.GlobalFeatures;
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures;
-public class GlobalFeaturePageFilter : IAsyncPageFilter, ITransientDependency
+public class GlobalFeaturePageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency
{
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs
index b0565cbc4d..455dd52f24 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs
@@ -2,11 +2,12 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.Response;
-public class AbpNoContentActionFilter : IAsyncActionFilter, ITransientDependency
+public class AbpNoContentActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs
index 14032b52d5..4a6a04a554 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs
@@ -4,12 +4,13 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
namespace Volo.Abp.AspNetCore.Mvc.Uow;
-public class AbpUowActionFilter : IAsyncActionFilter, ITransientDependency
+public class AbpUowActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs
index 7cfc1f0492..f4a7be3333 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs
@@ -4,13 +4,14 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.AspNetCore.Uow;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
namespace Volo.Abp.AspNetCore.Mvc.Uow;
-public class AbpUowPageFilter : IAsyncPageFilter, ITransientDependency
+public class AbpUowPageFilter : IAsyncPageFilter, IAbpFilter, ITransientDependency
{
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs
index e88cee4eb6..f866c85585 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/AbpValidationActionFilter.cs
@@ -3,13 +3,14 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Filters;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection;
using Volo.Abp.Validation;
namespace Volo.Abp.AspNetCore.Mvc.Validation;
-public class AbpValidationActionFilter : IAsyncActionFilter, ITransientDependency
+public class AbpValidationActionFilter : IAsyncActionFilter, IAbpFilter, ITransientDependency
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Serilog/Volo/Abp/AspNetCore/Serilog/AbpSerilogMiddleware.cs b/framework/src/Volo.Abp.AspNetCore.Serilog/Volo/Abp/AspNetCore/Serilog/AbpSerilogMiddleware.cs
index 1df327b742..52ee2e6b76 100644
--- a/framework/src/Volo.Abp.AspNetCore.Serilog/Volo/Abp/AspNetCore/Serilog/AbpSerilogMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Serilog/Volo/Abp/AspNetCore/Serilog/AbpSerilogMiddleware.cs
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Options;
using Serilog.Context;
using Serilog.Core;
using Serilog.Core.Enrichers;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.Clients;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
@@ -13,7 +14,7 @@ using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Serilog;
-public class AbpSerilogMiddleware : IMiddleware, ITransientDependency
+public class AbpSerilogMiddleware : AbpMiddlewareBase, ITransientDependency
{
private readonly ICurrentClient _currentClient;
private readonly ICurrentTenant _currentTenant;
@@ -35,7 +36,7 @@ public class AbpSerilogMiddleware : IMiddleware, ITransientDependency
_options = options.Value;
}
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var enrichers = new List();
diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs
index 6fd02a0470..cb531762ba 100644
--- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs
@@ -4,11 +4,12 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.DependencyInjection;
namespace Microsoft.AspNetCore.RequestLocalization;
-public class AbpRequestLocalizationMiddleware : IMiddleware, ITransientDependency
+public class AbpRequestLocalizationMiddleware : AbpMiddlewareBase, ITransientDependency
{
public const string HttpContextItemName = "__AbpSetCultureCookie";
@@ -23,7 +24,7 @@ public class AbpRequestLocalizationMiddleware : IMiddleware, ITransientDependenc
_loggerFactory = loggerFactory;
}
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var middleware = new RequestLocalizationMiddleware(
next,
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs
index 0987a8fd8f..86cc997ae7 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
@@ -11,7 +12,7 @@ using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Auditing;
-public class AbpAuditingMiddleware : IMiddleware, ITransientDependency
+public class AbpAuditingMiddleware : AbpMiddlewareBase, ITransientDependency
{
private readonly IAuditingManager _auditingManager;
protected AbpAuditingOptions AuditingOptions { get; }
@@ -34,9 +35,9 @@ public class AbpAuditingMiddleware : IMiddleware, ITransientDependency
AspNetCoreAuditingOptions = aspNetCoreAuditingOptions.Value;
}
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
- if (!AuditingOptions.IsEnabled || IsIgnoredUrl(context))
+ if (await ShouldSkipAsync(context, next) || !AuditingOptions.IsEnabled || IsIgnoredUrl(context))
{
await next(context);
return;
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs
index b9d3b83068..7d5ef610e5 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/AbpExceptionHandlingMiddleware.cs
@@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Authorization;
using Volo.Abp.DependencyInjection;
@@ -14,7 +15,7 @@ using Volo.Abp.Json;
namespace Volo.Abp.AspNetCore.ExceptionHandling;
-public class AbpExceptionHandlingMiddleware : IMiddleware, ITransientDependency
+public class AbpExceptionHandlingMiddleware : AbpMiddlewareBase, ITransientDependency
{
private readonly ILogger _logger;
@@ -27,7 +28,7 @@ public class AbpExceptionHandlingMiddleware : IMiddleware, ITransientDependency
_clearCacheHeadersDelegate = ClearCacheHeaders;
}
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
try
{
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs
new file mode 100644
index 0000000000..dbd55a8ed4
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs
@@ -0,0 +1,6 @@
+namespace Volo.Abp.AspNetCore.Filters;
+
+public interface IAbpFilter
+{
+
+}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs
new file mode 100644
index 0000000000..52c9990a4f
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Middleware/AbpMiddlewareBase.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.Controllers;
+
+namespace Volo.Abp.AspNetCore.Middleware;
+
+public abstract class AbpMiddlewareBase : IMiddleware
+{
+ protected Task ShouldSkipAsync(HttpContext context, RequestDelegate next)
+ {
+ var endpoint = context.GetEndpoint();
+ var controllerActionDescriptor = endpoint?.Metadata.GetMetadata();
+ var disableAbpFeaturesAttribute = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttribute();
+ return Task.FromResult(disableAbpFeaturesAttribute != null && disableAbpFeaturesAttribute.DisableMiddleware);
+ }
+
+ public abstract Task InvokeAsync(HttpContext context, RequestDelegate next);
+}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs
index ae2e3b173b..4542dd32e1 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs
@@ -5,11 +5,12 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Security;
-public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency
+public class AbpSecurityHeadersMiddleware : AbpMiddlewareBase, ITransientDependency
{
public IOptions Options { get; set; }
protected const string ScriptSrcKey = "script-src";
@@ -20,7 +21,7 @@ public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency
Options = options;
}
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
/*X-Content-Type-Options header tells the browser to not try and “guess” what a mimetype of a resource might be, and to just take what mimetype the server has returned as fact.*/
AddHeader(context, "X-Content-Type-Options", "nosniff");
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs
index ab23bdb944..bb2bedf901 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs
@@ -4,14 +4,15 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Security.Claims;
-public class AbpClaimsMapMiddleware : IMiddleware, ITransientDependency
+public class AbpClaimsMapMiddleware : AbpMiddlewareBase, ITransientDependency
{
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var currentPrincipalAccessor = context.RequestServices
.GetRequiredService();
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs
index 777ca7744a..9c62fa8b25 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs
@@ -2,14 +2,15 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Security.Claims;
-public class AbpDynamicClaimsMiddleware : IMiddleware, ITransientDependency
+public class AbpDynamicClaimsMiddleware : AbpMiddlewareBase, ITransientDependency
{
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (context.User.Identity?.IsAuthenticated == true)
{
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs
index a5f954c260..38356f8151 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Tracing/AbpCorrelationIdMiddleware.cs
@@ -3,12 +3,13 @@ using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Tracing;
namespace Volo.Abp.AspNetCore.Tracing;
-public class AbpCorrelationIdMiddleware : IMiddleware, ITransientDependency
+public class AbpCorrelationIdMiddleware : AbpMiddlewareBase, ITransientDependency
{
private readonly AbpCorrelationIdOptions _options;
private readonly ICorrelationIdProvider _correlationIdProvider;
@@ -20,7 +21,7 @@ public class AbpCorrelationIdMiddleware : IMiddleware, ITransientDependency
_correlationIdProvider = correlationIdProvider;
}
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var correlationId = GetCorrelationIdFromRequest(context);
using (_correlationIdProvider.Change(correlationId))
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs
index 186501b4ac..013b3dad98 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs
@@ -3,12 +3,13 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Middleware;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
namespace Volo.Abp.AspNetCore.Uow;
-public class AbpUnitOfWorkMiddleware : IMiddleware, ITransientDependency
+public class AbpUnitOfWorkMiddleware : AbpMiddlewareBase, ITransientDependency
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly AbpAspNetCoreUnitOfWorkOptions _options;
@@ -21,9 +22,9 @@ public class AbpUnitOfWorkMiddleware : IMiddleware, ITransientDependency
_options = options.Value;
}
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
- if (IsIgnoredUrl(context))
+ if (await ShouldSkipAsync(context, next) || IsIgnoredUrl(context))
{
await next(context);
return;
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs
index ba9240d48b..fffc35792a 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using JetBrains.Annotations;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
@@ -34,7 +33,10 @@ public class WebContentFileProvider : IWebContentFileProvider, ISingletonDepende
public virtual IFileInfo GetFileInfo(string subpath)
{
- Check.NotNullOrEmpty(subpath, nameof(subpath));
+ if (string.IsNullOrEmpty(subpath))
+ {
+ return new NotFoundFileInfo(subpath);
+ }
if (PathUtils.PathNavigatesAboveRoot(subpath))
{
@@ -53,11 +55,9 @@ public class WebContentFileProvider : IWebContentFileProvider, ISingletonDepende
return _fileProvider.GetFileInfo(_rootPath + subpath);
}
- public virtual IDirectoryContents GetDirectoryContents([NotNull] string subpath)
+ public virtual IDirectoryContents GetDirectoryContents(string subpath)
{
- Check.NotNullOrEmpty(subpath, nameof(subpath));
-
- if (PathUtils.PathNavigatesAboveRoot(subpath))
+ if (subpath == null || PathUtils.PathNavigatesAboveRoot(subpath))
{
return NotFoundDirectoryContents.Singleton;
}
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs
index 84d0ad0b2c..aebd14f36e 100644
--- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs
+++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs
@@ -13,19 +13,31 @@ public class PermissionValueProviderManager : IPermissionValueProviderManager, I
private readonly Lazy> _lazyProviders;
protected AbpPermissionOptions Options { get; }
+ protected IServiceProvider ServiceProvider { get; }
public PermissionValueProviderManager(
IServiceProvider serviceProvider,
IOptions options)
{
Options = options.Value;
+ ServiceProvider = serviceProvider;
- _lazyProviders = new Lazy>(
- () => Options
- .ValueProviders
- .Select(c => serviceProvider.GetRequiredService(c) as IPermissionValueProvider)
- .ToList()!,
- true
- );
+ _lazyProviders = new Lazy>(GetProviders, true);
+ }
+
+ protected virtual List GetProviders()
+ {
+ var providers = Options
+ .ValueProviders
+ .Select(type => (ServiceProvider.GetRequiredService(type) as IPermissionValueProvider)!)
+ .ToList();
+
+ var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1);
+ if(multipleProviders != null)
+ {
+ throw new AbpException($"Duplicate permission value provider name detected: {multipleProviders.Key}. Providers:{Environment.NewLine}{multipleProviders.Select(p => p.GetType().FullName!).JoinAsString(Environment.NewLine)}");
+ }
+
+ return providers;
}
}
diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs
index 043f824b1a..53216b03b9 100644
--- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs
+++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs
@@ -1,12 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using Autofac.Core;
using Autofac.Extras.DynamicProxy;
using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp;
using Volo.Abp.Autofac;
using Volo.Abp.Castle.DynamicProxy;
using Volo.Abp.DependencyInjection;
+using Volo.Abp.DynamicProxy;
using Volo.Abp.Modularity;
namespace Autofac.Builder;
@@ -75,11 +78,15 @@ public static class AbpRegistrationBuilderExtensions
if (serviceRegistredArgs.Interceptors.Any())
{
- registrationBuilder = registrationBuilder.AddInterceptors(
- registrationActionList,
- serviceType,
- serviceRegistredArgs.Interceptors
- );
+ var disableAbpFeaturesAttribute = serviceRegistredArgs.ImplementationType.GetCustomAttribute(true);
+ if (disableAbpFeaturesAttribute == null || !disableAbpFeaturesAttribute.DisableInterceptors)
+ {
+ registrationBuilder = registrationBuilder.AddInterceptors(
+ registrationActionList,
+ serviceType,
+ serviceRegistredArgs.Interceptors
+ );
+ }
}
return registrationBuilder;
diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor
index 82fc576b7e..9951e616e2 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor
+++ b/framework/src/Volo.Abp.BlazoriseUI/Components/UiMessageAlert.razor
@@ -22,7 +22,7 @@
@if ( IsConfirmation )
{
-