بررسی تکراری بودن نام محصول
csharp
bool exists = _context.Products
.Any(p => p.Name == updatedProduct.Name && p.Id != id);
if (exists)
ModelState.AddModelError("Name", "نام محصول تکراری است.");
بذار با مثال ساده و دقیق برات توضیح بدم تا کاملاً جا بیفته:
---
✅ سناریو: بررسی تکراری بودن نام محصول در اکشن ویرایش
فرض کن در دیتابیس محصولی داریم با:
plaintext Id = 1 Name = "گوشی"حالا کاربر میخواد محصولی با Id = 1 رو ویرایش کنه. --- 🔹 حالت اول: کاربر نام محصول رو به "گوشی" تغییر میده ولی محصول دیگری با همین نام وجود دارد
csharp bool exists = _context.Products .Any(p => p.Name == updatedProduct.Name && p.Id != id);این شرط یعنی: > آیا محصولی با همین نام وجود دارد ولی شناسهاش با محصول فعلی فرق دارد؟ ✅ اگر محصول دیگری با نام "گوشی" و Id ≠ 1 وجود داشته باشه، شرط exists == true میشه و خطا نمایش داده میشه: «نام محصول تکراری است.» --- 🔹 حالت دوم: کاربر فقط قیمت یا وضعیت محصول را تغییر میدهد و نام را همان "گوشی" باقی میگذارد در این حالت: - updatedProduct.Name == product.Name - و چون Id == id، شرط p.Id != id باعث میشه خود محصول فعلی در بررسی تکراری بودن محاسبه نشه ✅ بنابراین شرط exists == false میشه ✅ و خطای "نام محصول تکراری است" نمایش داده نمیشه --- 🎯 نتیجهگیری | وضعیت | آیا خطا نمایش داده میشود؟ | |-------|-----------------------------| | تغییر نام به نام محصول دیگری | ✅ بله، چون نام تکراری است و شناسه فرق دارد | | نام محصول تغییر نکرده | ❌ نه، چون خودش است و تکراری محسوب نمیشود |
پروژه ASP.Net Core MVC (وب و سی شارپ)
بیایم این سه اکشن مهم رو با مثالهای ساده و توضیح مرحلهبهمرحله بررسی کنیم تا دقیقاً بفهمی چه اتفاق
زمان:
حجم:
3.8M
مدیریت محصول در پروژه های وب رمزگشایی منطق C# برای ویرایش در ASP.Net Core MVC
ساخته شده از هوش مصنوعی
پروژه محصول و سفارش
https://eitaa.com/projectall/1200
Shop & Orders (4).zip
حجم:
24.9M
حذف @functions و آوردن تابع کمکی در کنترلر order
پروژه ASP.Net Core MVC (وب و سی شارپ)
حذف @functions و آوردن تابع کمکی در کنترلر order
بیایم خیلی خلاصه و دقیق فقط روی تغییرات لازم تمرکز کنیم، نه توضیح تئوری:
---
## ✅ تغییر در @functions
- ❌ حذف @functions از View
- ✅ تبدیل تابع
GetStatusList()به تابع
privateدر کنترلر - ✅ استفاده از خروجی تابع در ViewBag.StatusList --- ## ✅ تغییر در اکشن
Edit### در حالت
GET:
public IActionResult Edit(int id)
{
var order = _context.Orders
.Include(o => o.OrderProducts)
.FirstOrDefault(o => o.Id == id);
if (order == null)
return NotFound();
LoadFormData(); // ✅ آمادهسازی لیستها
return View(order);
}
### در حالت POST:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(int id, Order updatedOrder, List<int> selectedProductIds)
{
var order = _context.Orders
.Include(o => o.OrderProducts)
.FirstOrDefault(o => o.Id == id);
if (order == null)
return NotFound();
if (ModelState.IsValid)
{
// بهروزرسانی سفارش
...
_context.SaveChanges();
TempData["Success"] = "سفارش با موفقیت ویرایش شد.";
return RedirectToAction(nameof(Index));
}
LoadFormData(); // ✅ نمایش مجدد فرم با لیستها
return View(updatedOrder);
}
---
## ✅ تابع کمکی در کنترلر
private void LoadFormData()
{
ViewBag.Products = _context.Products
.Where(p => p.IsAvailable)
.OrderBy(p => p.Name)
.ToList();
ViewBag.StatusList = Enum.GetValues(typeof(OrderStatus))
.Cast<OrderStatus>()
.Select(s => new SelectListItem
{
Value = s.ToString(),
Text = s.GetType()
.GetMember(s.ToString())
.First()
.GetCustomAttribute<DisplayAttribute>()?.Name ?? s.ToString()
}).ToList();
}
---
## ✅ تغییر در View
<select asp-for="Status" class="form-select" asp-items="ViewBag.StatusList"></select>--- این تغییرات باعث میشن کدت تمیزتر، قابل نگهداریتر و حرفهایتر باشه.
پروژه ASP.Net Core MVC (وب و سی شارپ)
حذف @functions و آوردن تابع کمکی در کنترلر order
اگه همه منطقها رو در یک کلاس مشترک قرار بدی و هم در اکشن GET و هم در POST صدا بزنی، این کار کاملاً قابل قبول و رایج هست — مخصوصاً در مراحل ابتدایی جداسازی منطق از کنترلر.
---
✅ مزایای کلاس مشترک برای GET و POST
- کاهش تکرار کد: مثلاً تابع LoadFormData() یا GetStatusList() فقط یکبار نوشته میشه
- افزایش خوانایی کنترلر: کنترلر فقط صدا میزنه، خودش درگیر جزئیات نیست
- آمادگی برای جداسازی بیشتر: بعداً میتونی همین کلاس رو به سرویس یا لایههای CQRS تبدیل کنی
- تستپذیری بهتر: کلاس جدا راحتتر تست میشه نسبت به کد داخل کنترلر
---
⚠️ نکته مهم
اگر کلاس مشترک خیلی بزرگ بشه و هم منطق خواندن (GET) و هم منطق نوشتن (POST) رو با هم نگه داره، ممکنه:
- وابستگی زیاد بین متدها ایجاد بشه
- تستپذیری سختتر بشه
- اصل Single Responsibility نقض بشه
---
✅ راهحل حرفهایتر در آینده
وقتی آماده شدی برای معماری تمیزتر، میتونی:
- کلاس رو به دو بخش تقسیم کنی:
- OrderQueryService برای GET
- OrderCommandService برای POST
یا حتی با CQRS:
- EditOrderQueryHandler برای گرفتن اطلاعات
- EditOrderCommandHandler برای ذخیره تغییرات
---
🎯 نتیجه
الان که در مرحله توسعه هستی، کلاس مشترک کاملاً خوبه و منطقیه.
بعداً که پروژه بزرگتر شد، میتونی با تقسیم وظایف و CQRS ساختار حرفهایتری بسازی.
SmartShopPlus.zip
حجم:
25.3M
ترکیب سه پروژه قبل به یک پروژه + زبان
نکته : پروژه در ظاهر اول نگاه کنی ظاهر خوبی ندارد ولی پروژه فقط برای آموزش ساخته شده و اگر کامل نیست خودتون کامل کنید مخصوصا زبان که فقط یک کلمه را ترجمه می کند و کل سایت را خودتون ترجمه و
@inject SmartShopPlus.Service.ILanguageService Lang
در بالای ویو
<h1>@Lang.Translate("Dashboard.Title")</h1>
در همه جا قرار دهید و ترجمه کنید
SmartShopPlus (2).zip
حجم:
25.4M
پروژه enum helper اضافه شد
SmartShopPlus (3).zip
حجم:
25.5M
افزودن دیکشنری و تغییر زبان و عوض شدن محتوا داده
پروژه ASP.Net Core MVC (وب و سی شارپ)
افزودن دیکشنری و تغییر زبان و عوض شدن محتوا داده
هدف اینه که مخاطب بفهمه فرق بین LanguageHelper و LanguageService چیه، کدوم برای چه شرایطی بهتره، و اینکه لزومی نداره هر دو رو همزمان داشته باشه.
---
🎯 تفاوت LanguageHelper و LanguageService در پروژههای چندزبانه MVC
در پروژههای چندزبانه، معمولاً نیاز داریم متنها رو بر اساس زبان انتخابشده توسط کاربر نمایش بدیم. برای این کار دو روش رایج وجود داره:
---
✅ ۱. LanguageHelper (کلاس استاتیک)
csharp
public static class LanguageHelper
{
public static string Translate(ApplicationDbContext context, IHttpContextAccessor httpContext, string key)
{
var culture = httpContext.HttpContext.Request.Cookies["lang"] ?? "fa";
var resource = context.LanguageResources
.FirstOrDefault(r => r.Key == key && r.Culture == culture);
return resource?.Value ?? key;
}
}
📌 ویژگیها:
- استاتیکه، یعنی نیازی به ساخت نمونه (instance) نداره
- در کنترلرها و کلاسها قابل استفادهست
- باید هر بار context و httpContext رو دستی بهش بدی
- در Razor View مستقیم قابل استفاده نیست (مگر با ViewBag یا ViewData)
---
✅ ۲. LanguageService (سرویس تزریقی)
csharp
public class LanguageService : ILanguageService
{
private readonly ApplicationDbContext _context;
private readonly IHttpContextAccessor _http;
public LanguageService(ApplicationDbContext context, IHttpContextAccessor http)
{
_context = context;
_http = http;
}
public string Translate(string key)
{
var culture = _http.HttpContext?.Request.Cookies["lang"] ?? "fa";
var value = _context.LanguageResources
.Where(x => x.Key == key && x.Culture == culture)
.Select(x => x.Value)
.FirstOrDefault();
return value ?? $"[{key}]";
}
}
📌 استفاده در Razor View:
razor @inject ILanguageService Lang <h1>@Lang.Translate("Dashboard.Title")</h1>📌 ویژگیها: - از طریق DI (Dependency Injection) تزریق میشه - در Razor View مستقیم قابل استفادهست - نیازی به ارسال دستی context و http نداره - قابل تست، توسعه و مدیریت بهتره --- ⚖️ مقایسه نهایی | ویژگی | LanguageHelper | LanguageService | |--------------------------|----------------|-----------------| | سادگی اولیه | ✅ ساده | ❌ کمی پیچیدهتر | | استفاده در View | ❌ سخت | ✅ راحت با @inject | | نیاز به DI | ❌ ندارد | ✅ دارد | | توسعهپذیری | ❌ محدود | ✅ قابل گسترش | | مناسب پروژههای بزرگ | ❌ نه | ✅ بله | --- ✅ کدام را انتخاب کنیم؟ 🔹 اگر پروژهات ساده است یا فقط در کنترلرها ترجمه نیاز داری → LanguageHelper کافیست 🔹 اگر پروژهات چندزبانه، قابل توسعه و حرفهای است → LanguageService بهتر و استانداردتر است ❗ لزومی نداره هر دو را همزمان داشته باشی فقط یکی را انتخاب کن و در کل پروژه از همان استفاده کن تا کدت تمیز و منسجم بماند.
SmartShopPlus (4).zip
حجم:
25.5M
ویرایش منو و اصلاح پروژه و حذف کدهای بی مصرف