ViewModel'i her oluşturduğumda veritabanından getirmem gereken ülkeler, ürünler, kategoriler vb. Gibi birçok veriye sahip karmaşık görünüm modelim olduğunu varsayalım.Deposu görünüm modelinde kullanmak tamam mı?
düzeltmek istiyorum asıl sorun ben POST işlemleri işlemek ve bazı TestModel
false
olmak ModelState.IsValid
neden yanlış değerlerle ne zaman gönderildiğini, daha sonra şu anda Yayınlanan model ile aynı görünüm dönmek zorunda olmasıdır. Bu, GET eyleminde bunu yaptığım için tekrar kategoriler listemi almaya zorluyor. Bu, denetleyicide çok sayıda çoğaltılan kod ekler ve onu kaldırmak istiyorum.
Benim modelim ve görünümü modelleri: Şu anda aşağıdaki yapıyorum
Modeli, varlık veritabanında saklanan:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<Category> SubCategories { get; set; }
}
Görünüm modelleri:
public class CategoryModel
{
public int Id { get; set; }
public string Name { get; set; }
}
public class TestModel
{
[Required]
[MaxLength(5)]
public string Text { get; set; }
public int SelectedCategory { get; set; }
public IEnumerable<CategoryModel> Categories { get; set; }
public SelectList CategoriesList
{
get
{
var items = Categories == null || !Categories.Any()
? Enumerable.Empty<SelectListItem>()
: Categories.Select(c => new SelectListItem
{
Value = c.Id.ToString(),
Text = c.Name
});
return new SelectList(items, "Value", "Text");
}
}
}
Benim denetleyicisi: Ben, temelde bu kodu alma ve haritalama yinelenen Kategoriler kaldırmak istediğiniz
public class HomeController : Controller
{
private readonly Repository _repository = ObjectFactory.GetRepositoryInstance();
public ActionResult Index()
{
var model = new TestModel
{
Categories = _repository.Categories.Select(c => new CategoryModel
{
Id = c.Id,
Name = c.Name
})
};
return View(model);
}
[HttpPost]
public ActionResult Index(TestModel model)
{
if (ModelState.IsValid)
{
return RedirectToAction("Succes");
}
model.Categories = _repository.Categories.Select(c => new CategoryModel
{
Id = c.Id,
Name = c.Name
});
return View(model);
}
public ActionResult Succes()
{
return View();
}
}
: denetleyicisinden
.Categories = _repository.Categories.Select(c => new CategoryModel
{
Id = c.Id,
Name = c.Name
})
. Ayrıca ben ModelState
geçerlilik denetimi kaldırmak istiyorum, ben sadece ModelState.IsValid
denetleyici kodu AS TEMIZ OLARAK OLMAYAN OLARAK tutmak için eylemi yürütmek istiyorum.
eylem yürütmeden önce Şimdi modeli doğrulandığında
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var viewData = filterContext.Controller.ViewData;
if(viewData.ModelState.IsValid) return;
viewData.Model = filterContext.ActionParameters["model"];
filterContext.Result = new ViewResult
{
ViewData = viewData,
};
}
}
özel ValidateModelAttribute oluşturun: Şimdiye kadar ModelState
geçerlilik kontrolünü kaldırmak için aşağıdaki çözümü var. Doğrulama hataları durumunda, aynı görüntüyü aynı son yayınlanan modelle kullanırız. Dolayısıyla, denetleyici POST eylem şuna benzer:
[HttpPost]
[ValidateModelAttribute]
public ActionResult Index(TestModel model)
{
// Do some important stuff with posted data
return RedirectToAction("Success");
}
Bu güzel, ama ben veritabanından kategorileri getirir ve onları uygun şekilde eşleştirmek zorunda çünkü artık benim TestModel
benim Categories
özelliği, boş. Yani şuna benzer benim bakış modelini değiştirmek için OK:
public class TestModel
{
private readonly Repository _repository = ObjectFactory.GetRepositoryInstance();
...
public int SelectedCategory { get; set; }
public IEnumerable<CategoryModel> Categories {
get
{
return _repository.Categories.Select(c => new CategoryModel
{
Id = c.Id,
Name = c.Name
});
}
}
...
}
Bu bize çok temiz denetleyiciniz sağlayacak, ancak performansı veya mimari konularda çeşit neden olmaz? Bakış modelleri için tek sorumluluk ilkesini kırmaz mıydı? ViewModels, ihtiyaç duyduğu verileri almaktan sorumlu olmalı mı?
İdeal hayır, senin bakış modelleri depo ile doğrudan etkileşim olmaz, böyle yapardım. Modelinizi depodan doldurmanız gerekiyorsa, bu kontrol cihazınızda gerçekleşir. Kategoriler popülasyonunu ayrı denetleyici yollarında çoğaltmak istemiyorsanız, bu mantığı yeniden ayrı bir yönteme yerleştirmeyi deneyebilirsiniz. – timothyclifford