ASP.NET MVC рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЦрд░рд╛рдм рдиреЛрдЯреНрд╕ред рднрд╛рдЧ 1 (рдФрд░ рдХреЗрд╡рд▓ рдПрдХ)

рд╣рд╛рд▓ рд╣реА рдореЗрдВ, ASP.NET MVC рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦ рдЕрдХреНрд╕рд░ рд╣реЗрдмреЗ рдкрд░ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд▓рдЧреЗред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЙрдкрд░реЛрдХреНрдд рд░реВрдкрд░реЗрдЦрд╛ рдкрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдиреЛрдЯреНрд╕ рдмрдирд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛: рдиреВрдЧреЗрдЯ-рдкреИрдХреЗрдЬреЛрдВ рдХрд╛ рдиреНрдпреВрдирддрдо рд╕реЗрдЯ (рдЬрд┐рд╕рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рд╢реБрд░реВ рдХрд░рдирд╛ рдкрд╛рдк рд╣реИ), рдорд╛рдирдХ рд╕рджрд╕реНрдпрддрд╛-, рдкреНрд░реЛрдлрд╛рдЗрд▓-рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд▓реЙрдЧрд┐рдВрдЧ, рдиреБрдХрд╕рд╛рдиред рдФрд░ рдЖрдЦрд┐рд░ рдХреНрдпреЛрдВ, MVC 4 рд╕реЗ рд╡реЗрдм рдПрдкреАрдЖрдИ рд╡рд╣ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╣рдо рд╕рднреА рдХреЛ рдЗрдВрддрдЬрд╛рд░ рд╣реИред

NuGet-рд╕рдВрдХреБрд▓


рддреЛ, рдЖрдЗрдП рдмрд┐рдирд╛ рдпрд╣ рддрдп рдХрд░реЗрдВ рдХрд┐ рдЖрдк ASP.NET MVC рдкрд░ рдХреМрди рд╕рд╛ рдкреИрдХреЗрдЬ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдиреАрдЪреЗ рджреА рдЧрдИ рд╕реВрдЪреА рдореЗрдВ рд╡реЗ [рд╕рдВрдХреБрд▓] рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬреЛ рдПрдХ рд╕рдорд╛рдзрд╛рди рдмрдирд╛рддреЗ рд╕рдордп рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рд╣реЛрддреЗ рд╣реИрдВ, рдлрд┐рд░ рднреА рдореИрдВ рдЙрдиреНрд╣реЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░реВрдВрдЧрд╛ред

рдЗрдХрд╛рдИ рдлреНрд░реЗрдорд╡рд░реНрдХ 4.1 - рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдХреНрдпреЛрдВ рд╣реИ? рдЦреИрд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕рдордЭрд╛рддреЗ рд╣реИрдВред рдЕрдиреНрдп рд╕рдорд╛рди, рд╢реНрд░реЗрд╖реНрда, рдЖрджрд┐ ORM рдЪреМрдЦрдЯреЗ (рдПрдХ NHibernate рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИ) рдХреА рдкрд░реНрдпрд╛рдкреНрдд рд╕рдВрдЦреНрдпрд╛ рд╣реИред рдмрд╕ рдХреБрдЫ рд╕рд╛рд▓ рдкрд╣рд▓реЗ, рдореИрдВ рд╣рд▓реНрдХреЗ (рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд, рд╕рд┐рдВрдереЗрдЯрд┐рдХ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ LINQ рд╕реЗ SQL рдореЗрдВ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреВрдВрдЧрд╛ред рд▓реЗрдХрд┐рди! рдХреЛрдб рдлрд░реНрд╕реНрдЯ рдХреЗ рд╕рд╛рде рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ 4.1 рдХреА рд░рд┐рд▓реАрдЬ рдиреЗ рд╕рднреА рдиреБрдХрд╕рд╛рдиреЛрдВ рдХреЛ рджреВрд░ рдХрд░ рджрд┐рдпрд╛: рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрдЯрд╛ рд▓реЗрдпрд░ рдХреЛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХрд░рдирд╛ рдПрдХ рдЦреБрд╢реА рдереАред рдпрджрд┐ рдкрд╣рд▓реА рдмрд╛рд░ рдЖрдкрдХреЛ рдПрдХ рдбрд┐рдЬрд╛рдЗрдирд░ рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдбреАрдмреАрдПрдордПрд▓ рдлрд╛рдЗрд▓реЛрдВ рд╕реЗ рдирд┐рдкрдЯреЗрдВ, рддреЛ рдпрд╣рд╛рдВ рд╣рдо рдХреЗрд╡рд▓ рдкреАрдУрд╕реАрдУ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕реНрдЯреЛрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдбреЗрдЯрд╛ рдореЙрдбрд▓:

public class Product { public int ProductId { get; set; } public string Name { get; set; } public int CategoryId { get; set; } public virtual Category Category { get; set; } public int Price { get; set; } public DateTime CreationDate { get; set; } public string Description { get; set; } } public class Category { public int CategoryId { get; set; } public string Name { get; set; } public virtual ICollection<Product> Products { get; set; } } public class ProductsContext : DbContext { public DbSet<Category> Categories { get; set; } } 

MvcScaffolding - рдЬрд▓реНрджреА рд╕реЗ рдПрдХ CRUD рдкреИрдирд▓ рд╕реНрдХреЗрдЪ рдХреА рдЬрд░реВрд░рдд рд╣реИ? рдкрд╣рд▓реЗ рд╕реЗ рд╣реА EF рдореЙрдбрд▓ рд╣реИ, рдпрд╛ LINQ to SQL? рдлрд┐рд░ рдЗрд╕ рдЖрджреЗрд╢ рдХреЛ NuGet рд╡рд┐рдВрдбреЛ рдореЗрдВ рджрд░реНрдЬ рдХрд░реЗрдВ рдФрд░ рдХреЛрдб рдЬрдирд░реЗрд╢рди рдкрд░ рдЖрдирдиреНрджрд┐рдд рд╣реЛрдВ
Scaffold Controller [ ] тАУRepository
тАУRepository рдзреНрд╡рдЬ рдЖрдкрдХреЛ рдбреЗрдЯрд╛ рд▓реЗрдпрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рднреА рджреЗрддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдЙрдкрд░реЛрдХреНрдд рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рджрд░реНрдЬ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж
Scaffold Controller Product тАУRepository
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд CRUD рдкреГрд╖реНрда рдФрд░ рдЕрдореВрд░реНрдд рднрдВрдбрд╛рд░ рдЙрддреНрдкрдиреНрди рд╣реЛрдВрдЧреЗ:

 public interface IProductRepository { IQueryable<Product> All { get; } IQueryable<Product> AllIncluding(params Expression<Func<Product, object>>[] includeProperties); Product Find(int id); void InsertOrUpdate(Product product); void Delete(int id); void Save(); } 

рдФрд░ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:

 public class ProductRepository : IProductRepository { ProductsContext context = new ProductsContext(); public IQueryable<Product> All { get { return context.Products; } } public IQueryable<Product> AllIncluding(params Expression<Func<Product, object>>[] includeProperties) { IQueryable<Product> query = context.Products; foreach (var includeProperty in includeProperties) { query = query.Include(includeProperty); } return query; } public Product Find(int id) { return context.Products.Find(id); } public void InsertOrUpdate(Product product) { if (product.ProductId == default(int)) { // New entity context.Products.Add(product); } else { // Existing entity context.Entry(product).State = EntityState.Modified; } } public void Delete(int id) { var product = context.Products.Find(id); context.Products.Remove(product); } public void Save() { context.SaveChanges(); } } 


рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддреГрдд рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЖрдкрдХреЛ рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рд╕реНрд╡рдпрдВ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХреЗ рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдкрдврд╝реЗрдВред

рдирд┐рдиреНрдЬреЗрдХреНрдЯ - рдореБрдЭреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЧрд░реНрднрдкрд╛рдд рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдирд╣реАрдВ рд╣реИред ASP.NET MVC рдХреЗ рдкрд╛рд╕ рдЕрдкрдиреЗ рдХрд╛рд░рдЦрд╛рдиреЛрдВ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд / рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рд╕реБрд╡рд┐рдзрд╛рдПрдБ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд░реНрдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдмрд╛рдВрдзрдирд╛ рдПрдХ рдмреБрд░рд╛ рд░реВрдк рд╣реИред рдирд┐рдирдЬреЗ рдХреНрдпреЛрдВ? рдЙрддреНрддрд░ рд╕рд░рд▓ рд╣реИ - рдпрд╣ рд╣рд▓реНрдХрд╛ рд╣реИ, рдЗрд╕рдореЗрдВ рдХрдИ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИрдВ, рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛ рд░рд╣рд╛ рд╣реИред
рдЗрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, рд╕рд╛рде рд╣реА рд╕рд╛рде MVC3 рдХреЛ рднреА рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ:
рдЙрд╕рдХреЗ рдмрд╛рдж, App_Start рдлрд╝реЛрд▓реНрдбрд░ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛, рдЬрд╣рд╛рдВ NinjectMVC3.cs рдлрд╝рд╛рдЗрд▓ рд╕реНрдерд┐рдд рд╣реЛрдЧреАред
DI рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдПрдВ:

 class RepoModule : NinjectModule { public override void Load() { Bind<ICategoryRepository>().To<CategoryRepository>(); Bind<IProductRepository>().To<ProductRepository>(); } } 


NinjectMVC3.cs рдлрд╝рд╛рдЗрд▓ рдореЗрдВ CreateKernel рд╡рд┐рдзрд┐ рдореЗрдВ, рд▓рд┐рдЦреЗрдВ:

 var modules = new INinjectModule[] { new RepoModule() }; var kernel = new StandardKernel(modules); RegisterServices(kernel); return kernel; 


рдЕрдм рд╣рдорд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдХ рд▓рд┐рдЦреЗрдВ:

 public class ProductsController : Controller { private readonly IProductRepository productRepository; public ProductsController(IProductRepository productRepository) { this.productRepository = productRepository; } } 

NLog - рдпрд╣ рдХреИрд╕реЗ рдкрддрд╛ рдХрд░реЗрдВ рдХрд┐ рдСрдкрд░реЗрд╢рди рдХрд░рддреЗ рд╕рдордп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╕рдлрд▓рддрд╛ / рд╡рд┐рдлрд▓рддрд╛рдПрдВ? рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рдЙрдкрд╛рдп рд▓реЙрдЧрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдЕрдкрдиреА рдмрд╛рдЗрдХ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИред рд╕рдм рд╕реЗ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк NLog рдФрд░ log4net рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдмрд╛рдж рд╡рд╛рд▓рд╛ рдЬрд╛рд╡рд╛ (log4j) рдХреЗ рд╕рд╛рде рдПрдХ рд╕реАрдзрд╛ рдмрдВрджрд░рдЧрд╛рд╣ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдмрд╣реБрдд рд╕рдХреНрд░рд┐рдп рдирд╣реАрдВ рд╣реИ, рдЕрдЧрд░ рдЗрд╕реЗ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдирд╣реАрдВ рдЫреЛрдбрд╝рд╛ рдЬрд╛рдПред NLog, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛ рд░рд╣рд╛ рд╣реИ, рдЗрд╕рдореЗрдВ рд╕рдореГрджреНрдз рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдФрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдПрдкреАрдЖрдИ рд╣реИред
рдХреИрд╕реЗ рдЬрд▓реНрджреА рд╕реЗ рдПрдХ рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП:

 public class ProductController : Controller { private static Logger log = LogManager.GetCurrentClassLogger(); public ActionResult DoStuff() { //very important stuff log.Info("Everything is OK!"); return View(); } } 

PagedList - рдХреНрдпрд╛ рдЖрдкрдХреЛ рдкреЗрдЬ рдЯрд░реНрдирд┐рдВрдЧ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рд╣рд╛рдВ, рдЖрдк рдЦреБрдж рдмреИрда рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдЖ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВ? рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рд╣реИред

Lucene.NET - рдХреНрдпрд╛ рдЖрдк рдЕрднреА рднреА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдЦреБрдж рдХреЛ рдорд┐рдЯрд╛ рд░рд╣реЗ рд╣реИрдВ? рднреВрд▓ рдЬрд╛рдУ! рдХреБрдЫ рдорд┐рдирдЯреЛрдВ рдФрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдЕрд▓реНрдЯреНрд░рд╛-рдлрд╛рд╕реНрдЯ рдЦреЛрдЬ рд╣реЛрдЧреАред
рдЗрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, рд╕рд╛рде рд╣реА рдЗрд╕рдХреЗ SimpleLucene рдРрдб-рдСрди:
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЗрдВрдбреЗрдХреНрд╕ рдмрдирд╛рдиреЗ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

 public class ProductIndexDefinition : IIndexDefinition<Product> { public Document Convert(Product entity) { var document = new Document(); document.Add(new Field("ProductId", entity.ProductId.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); document.Add(new Field("Name", entity.Name, Field.Store.YES, Field.Index.ANALYZED)); if (!string.IsNullOrEmpty(entity.Description)) { document.Add(new Field("Description", entity.Description, Field.Store.YES, Field.Index.ANALYZED)); } document.Add(new Field("CreationDate", DateTools.DateToString(entity.CreationDate, DateTools.Resolution.DAY), Field.Store.YES, Field.Index.NOT_ANALYZED)); if (entity.Price != null) { var priceField = new NumericField("Price", Field.Store.YES, true); priceField.SetIntValue(entity.Price); document.Add(priceField); } document.Add(new Field("CategoryId", entity.CategoryId.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); return document; } public Term GetIndex(Product entity) { return new Term("ProductId", entity.ProductId.ToString()); } } 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдХрдиреНрд╡рд░реНрдЯ рд╡рд┐рдзрд┐ рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдо рд▓реНрдпреВрдХреЛрди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ POCO рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рддреЗ рд╣реИрдВред
рдирд┐рдпрдВрддреНрд░рдХ рдХреЛрдб:

 public ActionResult Create(Product product) { if (ModelState.IsValid) { product.CreationDate = DateTime.Now; productRepository.InsertOrUpdate(product); productRepository.Save(); // index location var indexLocation = new FileSystemIndexLocation(new DirectoryInfo(Server.MapPath("~/Index"))); var definition = new ProductIndexDefinition(); var task = new EntityUpdateTask<Product>(product, definition, indexLocation); task.IndexOptions.RecreateIndex = false; task.IndexOptions.OptimizeIndex = true; //IndexQueue.Instance.Queue(task); var indexWriter = new DirectoryIndexWriter(new DirectoryInfo(Server.MapPath("~/Index")), false); using (var indexService = new IndexService(indexWriter)) { task.Execute(indexService); } return RedirectToAction("Index"); } else { ViewBag.PossibleCategories = categoryRepository.All; return View(); } } 


рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдкрд░рд┐рдгрд╛рдо рдмрдирд╛рдПрдВ:

 public class ProductResultDefinition : IResultDefinition<Product> { public Product Convert(Document document) { var product = new Product(); product.ProductId = document.GetValue<int>("ProductId"); product.Name = document.GetValue("Name"); product.Price = document.GetValue<int>("Price"); product.CategoryId = document.GetValue<int>("CategoryId"); product.CreationDate = DateTools.StringToDate(document.GetValue("CreationDate")); product.Description = document.GetValue("Description"); return product; } } 


рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ POCO deserializes рд╣реИред
рдФрд░ рдЕрдВрдд рдореЗрдВ, рд╣рдо рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

 public class ProductQuery : QueryBase { public ProductQuery(Query query) : base(query) { } public ProductQuery() { } public ProductQuery WithKeywords(string keywords) { if (!string.IsNullOrEmpty(keywords)) { string[] fields = { "Name", "Description" }; var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, fields, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29)); Query multiQuery = parser.Parse(keywords); this.AddQuery(multiQuery); } return this; } } } 


рдЕрдм рдирд┐рдпрдВрддреНрд░рдХ рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВ:

 public ActionResult Search(string searchText, bool? orderByDate) { string IndexPath = Server.MapPath("~/Index"); var indexSearcher = new DirectoryIndexSearcher(new DirectoryInfo(IndexPath), true); using (var searchService = new SearchService(indexSearcher)) { var query = new ProductQuery().WithKeywords(searchText); var result = searchService.SearchIndex<Product>(query.Query, new ProductResultDefinition()); if (orderByDate.HasValue) { return View(result.Results.OrderBy(x => x.CreationDate).ToList()) } return View(result.Results.ToList()); } } 


рдЬреЗрдПрд╕ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд╡рд┐рд╕реНрддрд╛рд░ - рдЧреНрд░рд╛рд╣рдХ рдХрд╛ рдЖрдзрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдирд╣реАрдВ, рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ, рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде рдЧреНрд░рд╛рд╣рдХ рдкрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдврд╛рдВрдЪреЗ рдХрд╛ рдПрдХ рдЪрд┐рдХрдирд╛ рдирд┐рд░реНрдорд╛рдг рдЕрднреА рднреА рдорд╛рдВрдЧрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореИрдВ рдЖрдкрдХреЛ Rx рд╡рд┐рдХрд╛рд╕ рдкрд░ рдореЗрд░реА рдкреЛрд╕реНрдЯ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ ред

рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг


рдореИрдВ рдЖрдкрдХреЛ рддреБрд░рдВрдд рдЪреЗрддрд╛рд╡рдиреА рджреЗрддрд╛ рд╣реВрдВ - рдХрднреА рднреА рдорд╛рдирдХ AspNetMembershipProvider рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВ! рдпрджрд┐ рдЖрдк рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдЙрд╕рдХреА рд░рд╛рдХреНрд╖рд╕реА рд╕рдВрдЧреНрд░рд╣реАрдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрд╕реЗ рдмрд╛рд╣рд░ рдлреЗрдВрдХрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
InstallMembership.sql рдФрд░ InstallProfile.SQL рдлрд╛рдЗрд▓реЛрдВ рдХреЛ C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЦреЛрд▓реЗрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ InstallMembership.sql рд╕реЗ FindUsersByName рдХреЗ рд▓рд┐рдП SQL рдХреЛрдб рдХреНрдпрд╛ рд╣реИ:

 CREATE PROCEDURE dbo.aspnet_Membership_FindUsersByName @ApplicationName nvarchar(256), @UserNameToMatch nvarchar(256), @PageIndex int, @PageSize int AS BEGIN DECLARE @ApplicationId uniqueidentifier SELECT @ApplicationId = NULL SELECT @ApplicationId = ApplicationId FROM dbo.aspnet_Applications WHERE LOWER(@ApplicationName) = LoweredApplicationName IF (@ApplicationId IS NULL) RETURN 0 -- Set the page bounds DECLARE @PageLowerBound int DECLARE @PageUpperBound int DECLARE @TotalRecords int SET @PageLowerBound = @PageSize * @PageIndex SET @PageUpperBound = @PageSize - 1 + @PageLowerBound -- Create a temp table TO store the select results CREATE TABLE #PageIndexForUsers ( IndexId int IDENTITY (0, 1) NOT NULL, UserId uniqueidentifier ) -- Insert into our temp table INSERT INTO #PageIndexForUsers (UserId) SELECT u.UserId FROM dbo.aspnet_Users u, dbo.aspnet_Membership m WHERE u.ApplicationId = @ApplicationId AND m.UserId = u.UserId AND u.LoweredUserName LIKE LOWER(@UserNameToMatch) ORDER BY u.UserName SELECT u.UserName, m.Email, m.PasswordQuestion, m.Comment, m.IsApproved, m.CreateDate, m.LastLoginDate, u.LastActivityDate, m.LastPasswordChangedDate, u.UserId, m.IsLockedOut, m.LastLockoutDate FROM dbo.aspnet_Membership m, dbo.aspnet_Users u, #PageIndexForUsers p WHERE u.UserId = p.UserId AND u.UserId = m.UserId AND p.IndexId >= @PageLowerBound AND p.IndexId <= @PageUpperBound ORDER BY u.UserName SELECT @TotalRecords = COUNT(*) FROM #PageIndexForUsers RETURN @TotalRecords END 


рдФрд░ рдпрд╣рд╛рдБ InstallProfile.SQL рд╕реЗ Profile_GetProfiles рд╣реИ:

 CREATE PROCEDURE dbo.aspnet_Profile_GetProfiles @ApplicationName nvarchar(256), @ProfileAuthOptions int, @PageIndex int, @PageSize int, @UserNameToMatch nvarchar(256) = NULL, @InactiveSinceDate datetime = NULL AS BEGIN DECLARE @ApplicationId uniqueidentifier SELECT @ApplicationId = NULL SELECT @ApplicationId = ApplicationId FROM aspnet_Applications WHERE LOWER(@ApplicationName) = LoweredApplicationName IF (@ApplicationId IS NULL) RETURN -- Set the page bounds DECLARE @PageLowerBound int DECLARE @PageUpperBound int DECLARE @TotalRecords int SET @PageLowerBound = @PageSize * @PageIndex SET @PageUpperBound = @PageSize - 1 + @PageLowerBound -- Create a temp table TO store the select results CREATE TABLE #PageIndexForUsers ( IndexId int IDENTITY (0, 1) NOT NULL, UserId uniqueidentifier ) -- Insert into our temp table INSERT INTO #PageIndexForUsers (UserId) SELECT u.UserId FROM dbo.aspnet_Users u, dbo.aspnet_Profile p WHERE ApplicationId = @ApplicationId AND u.UserId = p.UserId AND (@InactiveSinceDate IS NULL OR LastActivityDate <= @InactiveSinceDate) AND ( (@ProfileAuthOptions = 2) OR (@ProfileAuthOptions = 0 AND IsAnonymous = 1) OR (@ProfileAuthOptions = 1 AND IsAnonymous = 0) ) AND (@UserNameToMatch IS NULL OR LoweredUserName LIKE LOWER(@UserNameToMatch)) ORDER BY UserName SELECT u.UserName, u.IsAnonymous, u.LastActivityDate, p.LastUpdatedDate, DATALENGTH(p.PropertyNames) + DATALENGTH(p.PropertyValuesString) + DATALENGTH(p.PropertyValuesBinary) FROM dbo.aspnet_Users u, dbo.aspnet_Profile p, #PageIndexForUsers i WHERE u.UserId = p.UserId AND p.UserId = i.UserId AND i.IndexId >= @PageLowerBound AND i.IndexId <= @PageUpperBound SELECT COUNT(*) FROM #PageIndexForUsers DROP TABLE #PageIndexForUsers END 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЛ рд▓рдЧрд╛рддрд╛рд░ рдмрдирд╛рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рднреА рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдХреА рдЙрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рд╕реЛрдЪрд┐рдП рдЕрдЧрд░ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб 100 рдРрд╕реЗ рдХреЙрд▓ рд╣реЛрдВред
рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрд╢рд╛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рджрд╛рддрд╛ рдмрдирд╛рдПрдВред

ASP.NET MVC4 рд╡реЗрдм рдПрдкреАрдЖрдИ


ASP.NET MVC рд░реЗрд╕реНрдЯрдлреБрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмреЗрд╣рддрд░реАрди рдврд╛рдВрдЪрд╛ рд╣реИред рдПрдкреАрдЖрдИ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

 public class AjaxProductsController : Controller { private readonly IProductRepository productRepository; public AjaxProductsController(IProductRepository productRepository) { this.productRepository = productRepository; } public ActionResult Details(int id) { return Json(productRepository.Find(id)); } public ActionResult List(int category) { var products = from p in productRepository.All where p.CategoryId == category select p; return Json(products.ToList()); } } 


рд╣рд╛рдВ, AJAX рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдирд┐рдпрдВрддреНрд░рдХ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдерд╛ред
рдЕрдиреНрдп рд╕реНрдкреЗрдЧреЗрдЯреА рдХреЛрдб рд╣реИ:

 public class ProductsController : Controller { private readonly IProductRepository productRepository; public ProductsController(IProductRepository productRepository) { this.productRepository = productRepository; } public ActionResult List(int category) { var products = from p in productRepository.All where p.CategoryId == category select p; if (Request.IsAjaxRequest()) { return Json(products.ToList()); } return View(products.ToList()); } } 


рдФрд░ рдЕрдЧрд░ рдЖрдкрдХреЛ CRUD рдСрдкрд░реЗрд╢рди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ:

 [HttpPost] public ActionResult Create(Product product) { if (ModelState.IsValid) { productRepository.InsertOrUpdate(product); productRepository.Save(); return RedirectToAction("Index"); } return View(); } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЛрдб рдореЗрдВ AJAX рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╕рдмрд╕реЗ рд╕рд╛рдл рдХреЛрдб рдирд╣реАрдВ рд╣реИред рд╣рдо рдПрдХ рдПрдкреАрдЖрдИ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рд╣реИ рдирд╛?
MVC4 рдХреА рд░рд┐рд▓реАрдЬрд╝ рдиреЗ рд╡реЗрдм API рдХреА рдирдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ред рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рдпрд╣ рдПрдорд╡реАрд╕реА рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдФрд░ рдбрдмреНрд▓реНрдпреВрд╕реАрдПрдл рдбреЗрдЯрд╛ рд╕реЗрд╡рд╛рдУрдВ рдХрд╛ рдорд┐рд╢реНрд░рдг рд╣реИред
рдореИрдВ рд╡реЗрдм рдПрдкреАрдЖрдИ рд╡рд┐рд╖рдп рдкрд░ рдПрдХ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдирд╣реАрдВ рджреВрдВрдЧрд╛, рдЙрдирдореЗрдВ рд╕реЗ рдмрд╣реБрдд рд╕реЗ ASP.NET MVC рд╕рд╛рдЗрдЯ рдкрд░ рд╣реА рд╣реИрдВред
рдореИрдВ рдЙрдкрд░реЛрдХреНрдд рд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, ProductRepository рд╕реЗ InsertOrUpdate рд╡рд┐рдзрд┐ рдмрджрд▓реЗрдВ:

 public Product InsertOrUpdate(Product product) { if (product.ProductId == default(int)) { // New entity return context.Products.Add(product); } // Existing entity context.Entry(product).State = EntityState.Modified; return context.Entry(product).Entity; } 


рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рд╕реНрд╡рдпрдВ рд▓рд┐рдЦреЗрдВ:

 public class ProductsController : ApiController { /* *  */ public IEnumerable<Product> GetAllProducts(int category) { var products = from p in productRepository.All where p.CategoryId == category select p; return products.ToList(); } // Not the final implementation! public Product PostProduct(Product product) { var entity = productRepository.InsertOrUpdate(product); return entity; } } 


рддреЛ, рдХреБрдЫ рдмрд┐рдВрджреБ, рдХреНрдпрд╛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:

рдореИрдВрдиреЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдмрддрд╛рдпрд╛ рдХрд┐ рд╡реЗрдм рдПрдкреАрдЖрдИ рдПрдорд╡реАрд╕реА рдФрд░ рдбрдмреНрд▓реНрдпреВрд╕реАрдПрдл рдбреЗрдЯрд╛ рд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдХрд╛ рдорд┐рд╢реНрд░рдг рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╣рд╛рдБ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ? рдпрд╣ рд╕рд░рд▓ рд╣реИ - рдирдпрд╛ рдПрдкреАрдЖрдИ OData рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ! рдФрд░ рдпрд╣ рдПрдХ рд╕рдорд╛рди рд╕рд┐рджреНрдзрд╛рдВрдд рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реЙрд░реНрдЯрд┐рдВрдЧ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛:

 public ActionResult List(string sortOrder, int category) { var products = from p in productRepository.All where p.CategoryId == category select p; switch (sortOrder.ToLower()) { case "name": products = products.OrderBy(x => x.Name); break; case "desc": products = products.OrderBy(x => x.Description); break; } return Json(products.ToList()); } 


рдЕрдм рдЖрдкрдХреЛ рдмрд╕ GetAllProducts рд╡рд┐рдзрд┐ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 public IQueryable<Product> GetAllProducts(int category) { var products = from p in productRepository.All where p.CategoryId == category select p; return products; } 


рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрди рдЯрд╛рдЗрдк рдХрд░реЗрдВ:
http://localhost/api/products?category=1&$orderby=Name

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рд╡рд┐рдХрд░реНрд╖рдгреЛрдВ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд▓рд┐рдпрд╛ рдФрд░ рдЕрдм рдПрдкреАрдЖрдИ рдмрдирд╛рдиреЗ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

Source: https://habr.com/ru/post/In143024/


All Articles