بله؛ این امکان وجود دارد که سیستم را افزونه پذیر کرد و مدلها رو در زمان اجرا به DbContext اضافه کرد.
جزئیات آن خارج است از بحث «قسمت دوم» ما.
جزئیات آن خارج است از بحث «قسمت دوم» ما.
private const string SeparatorTitle = " - "; private const int MaxLenghtTitle = 60; public static string GeneratePageTitle(params string[] crumbs) { var title = ""; for (int i = 0; i < crumbs.Length; i++) { title += string.Format ( "{0}{1}", crumbs[i], (i < crumbs.Length - 1) ? SeparatorTitle : string.Empty ); } title = title.Substring(0, title.Length <= MaxLenghtTitle ? title.Length : MaxLenghtTitle).Trim(); return title; }
public enum CacheControlType { [Description("public")] _public, [Description("private")] _private, [Description("no-cache")] _nocache, [Description("no-store")] _nostore }
private const int MaxLenghtTitle = 60; private const int MaxLenghtDescription = 170; private const string FaviconPath = "~/cdn/ui/favicon.ico"; public static string GenerateMetaTag(string title, string description, bool allowIndexPage, bool allowFollowLinks, string author = "", string lastmodified = "", string expires = "never", string language = "fa", CacheControlType cacheControlType = CacheControlType._private) { title = title.Substring(0, title.Length <= MaxLenghtTitle ? title.Length : MaxLenghtTitle).Trim(); description = description.Substring(0, description.Length <= MaxLenghtDescription ? description.Length : MaxLenghtDescription).Trim(); var meta = ""; meta += string.Format("<title>{0}</title>\n", title); meta += string.Format("<link rel=\"shortcut icon\" href=\"{0}\"/>\n", FaviconPath); meta += string.Format("<meta http-equiv=\"content-language\" content=\"{0}\"/>\n", language); meta += string.Format("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/>\n"); meta += string.Format("<meta charset=\"utf-8\"/>\n"); meta += string.Format("<meta name=\"description\" content=\"{0}\"/>\n", description); meta += string.Format("<meta http-equiv=\"Cache-control\" content=\"{0}\"/>\n", EnumExtensions.EnumHelper<CacheControlType>.GetEnumDescription(cacheControlType.ToString())); meta += string.Format("<meta name=\"robots\" content=\"{0}, {1}\" />\n", allowIndexPage ? "index" : "noindex", allowFollowLinks ? "follow" : "nofollow"); meta += string.Format("<meta name=\"expires\" content=\"{0}\"/>\n", expires); if (!string.IsNullOrEmpty(lastmodified)) meta += string.Format("<meta name=\"last-modified\" content=\"{0}\"/>\n", lastmodified); if (!string.IsNullOrEmpty(author)) meta += string.Format("<meta name=\"author\" content=\"{0}\"/>\n", author); //------------------------------------Google & Bing Doesn't Use Meta Keywords ... //meta += string.Format("<meta name=\"keywords\" content=\"{0}\"/>\n", keywords); return meta; }
private const int MaxLenghtSlug = 45; public static string GenerateSlug(string title) { var slug = RemoveAccent(title).ToLower(); slug = Regex.Replace(slug, @"[^a-z0-9-\u0600-\u06FF]", "-"); slug = Regex.Replace(slug, @"\s+", "-").Trim(); slug = Regex.Replace(slug, @"-+", "-"); slug = slug.Substring(0, slug.Length <= MaxLenghtSlug ? slug.Length : MaxLenghtSlug).Trim(); return slug; } private static string RemoveAccent(string text) { var bytes = Encoding.GetEncoding("UTF-8").GetBytes(text); return Encoding.UTF8.GetString(bytes); }
Head.InnerHtml = SEO.GenerateMetaTag ( title: SEO.GeneratePageTitle(".NET Tips", "آرشیو مطالب", "ASP.NET MVC #1"), description: "چرا ASP.NET MVC با وجود فریم ورک پختهای به نام ASP.NET web forms، اولین سؤالی که حین سوئیچ به ASP.NET MVC مطرح میشود این است: «برای چی؟». بنابراین تا به این سؤال پاسخ داده نشود، هر نوع بحث فنی در این مورد بی فایده است.", allowIndexPage: true, allowFollowLinks: true, author: "وحید نصیری", cacheControlType: SEO.CacheControlType._private );
<title>.NET Tips - آرشیو مطالب - ASP.NET MVC #1</title> <link rel="shortcut icon" href="../../cdn/images/ui/favicon.ico"/> <meta http-equiv="content-language" content="fa"/> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <meta charset="utf-8"/> <meta name="description" content="چرا ASP.NET MVC ؟با وجود فریم ورک پختهای به نام ASP.NET web forms، اولین سؤالی که حین سوئیچ به ASP.NET MVC مطرح میشود این است: «برای چی؟». بن ..."/> <meta http-equiv="Cache-control" content="private"/> <meta name="robots" content="index, follow" /> <meta name="expires" content="never"/> <meta name="author" content="وحید نصیری"/>
D:\Prog\1395\Core1RtmEmptyTest\src\Core1RtmEmptyTest>dotnet ef _/\__ ---==/ \\ ___ ___ |. \|\ | __|| __| | ) \\\ | _| | _| \_/ | //|\\ |___||_| / \\\/\\ Entity Framework .NET Core CLI Commands 1.0.0-preview2-21431 Usage: dotnet ef [options] [command] Options: -h|--help Show help information -v|--verbose Enable verbose output --version Show version information --assembly <ASSEMBLY> The assembly file to load. --startup-assembly <ASSEMBLY> The assembly file containing the startup class. --data-dir <DIR> The folder used as the data directory (defaults to current working directory). --project-dir <DIR> The folder used as the project directory (defaults to current working directory). --content-root-path <DIR> The folder used as the content root path for the application (defaults to application base directory). --root-namespace <NAMESPACE> The root namespace of the target project (defaults to the project assembly name). Commands: database Commands to manage your database dbcontext Commands to manage your DbContext types migrations Commands to manage your migrations Use "dotnet ef [command] --help" for more information about a command.
D:\Prog\1395\Core1RtmEmptyTest\src\Core1RtmEmptyTest>dotnet ef migrations add InitialDatabase
D:\Prog\1395\Core1RtmEmptyTest\src\Core1RtmEmptyTest>dotnet ef database update Applying migration '13950526050417_InitialDatabase'. Done.
using System.Collections.Generic; using System.Linq; using Core1RtmEmptyTest.Entities; using Microsoft.Extensions.DependencyInjection; namespace Core1RtmEmptyTest.Migrations { public static class ApplicationDbContextSeedData { public static void SeedData(this IServiceScopeFactory scopeFactory) { using (var serviceScope = scopeFactory.CreateScope()) { var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>(); if (!context.Persons.Any()) { var persons = new List<Person> { new Person { FirstName = "Admin", LastName = "User" } }; context.AddRange(persons); context.SaveChanges(); } } } } }
public void Configure(IServiceScopeFactory scopeFactory) { scopeFactory.SeedData();
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(ServiceLifetime.Scoped);
namespace Core1RtmEmptyTest.Entities { public class Person { public int PersonId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } } }
An unhandled exception occurred while processing the request. SqlException: Invalid column name 'Age'.
D:\Prog\1395\Core1RtmEmptyTest\src\Core1RtmEmptyTest>dotnet ef migrations add v2 D:\Prog\1395\Core1RtmEmptyTest\src\Core1RtmEmptyTest>dotnet ef database update
D:\Prog\1395\Core1RtmEmptyTest\src\Core1RtmEmptyTest>dotnet ef migrations script -o v2.sql
public Configuration() { AutomaticMigrationsEnabled = true; }
using Core1RtmEmptyTest.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; namespace Core1RtmEmptyTest.Migrations { public static class DbInitialization { public static void Initialize(this IServiceScopeFactory scopeFactory) { using (var serviceScope = scopeFactory.CreateScope()) { var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>(); // Applies any pending migrations for the context to the database. // Will create the database if it does not already exist. context.Database.Migrate(); } } } }
public class FaLanguageActionFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { CultureInfo.CurrentCulture = new CultureInfo("fa-IR"); CultureInfo.CurrentUICulture = new CultureInfo("fa-IR"); base.OnActionExecuting(context); } }
public abstract class MyCustomBaseView<TModel> : RazorPage<TModel> { protected MyCustomBaseView() { CultureInfo.CurrentCulture = new CultureInfo("fa-IR"); CultureInfo.CurrentUICulture = new CultureInfo("fa-IR"); }
public abstract class BaseEntity { public int Id { set; get; } } public class User : BaseEntity { public string Name { set; get; } public virtual ICollection<Advertisement> Advertisements { get; set; } } public class Advertisement : BaseEntity { public string Title { get; set; } public string Description { get; set; } [ForeignKey("UserId")] public virtual User User { get; set; } public int UserId { get; set; } }
public class AdvertisementViewModel { public int Id { get; set; } public string Title { get; set; } public int UserId { get; set; } } public class UserViewModel { public int Id { set; get; } public string Name { set; get; } public List<AdvertisementViewModel> Advertisements { get; set; } }
this.CreateMap<AdvertisementViewModel, Advertisement>() .ForMember(advertisement => advertisement.Description, opt => opt.Ignore()) .ForMember(advertisement => advertisement.User, opt => opt.Ignore());
var uiUser1 = new UserViewModel { Id = 1, Name = "user 1", Advertisements = new List<AdvertisementViewModel> { new AdvertisementViewModel { Id = 1, Title = "Adv 1", UserId = 1 }, new AdvertisementViewModel { Id = 2, Title = "Adv 2", UserId = 1 } } };
var dbUser1 = ctx.Users.Include(user => user.Advertisements).First(x => x.Id == uiUser1.Id); Mapper.Map(source: uiUser1, destination: dbUser1);
this.CreateMap<UserViewModel, User>()
this.CreateMap<UserViewModel, User>().ForMember(user => user.Advertisements, opt => opt.Ignore());
using (var ctx = new MyContext()) { var dbUser1 = ctx.Users.Include(user => user.Advertisements).First(x => x.Id == uiUser1.Id); Mapper.Map(source: uiUser1, destination: dbUser1); foreach (var uiUserAdvertisement in uiUser1.Advertisements) { var dbUserAdvertisement = dbUser1.Advertisements.FirstOrDefault(ad => ad.Id == uiUserAdvertisement.Id); if (dbUserAdvertisement == null) { // Add new record var advertisement = Mapper.Map<AdvertisementViewModel, Advertisement>(uiUserAdvertisement); dbUser1.Advertisements.Add(advertisement); } else { // Update the existing record Mapper.Map(uiUserAdvertisement, dbUserAdvertisement); } } ctx.SaveChanges(); }
public class Person { public string FirstName { get; set; } public Person(string firstName) { this.FirstName = firstName; } }
public class Person { public string FirstName { get; set; } public Person(string firstName) => this.FirstName = firstName; }
public class Person { public string Name { get; } public int Age { get; } public Person(string name, int age) => (Name, Age) = (name, age); }
public class Person { private readonly (string name, int age) _tuple; public string Name => _tuple.name; public int Age => _tuple.age; public Person(string name, int age) => _tuple = (name, age); }
public class Resource { ~Resource() => Console.WriteLine("destructor"); }
private int _x; public int X { get { return _x; } set { _x = value; } }
private int _x; public int X { get => _x; set => _x = value; }
همچنین برای Event Accessors نیز میتوانیم از این قابلیت استفاده کنیم:
private EventHandler _someEvent; public event EventHandler SomeEvent { add => _someEvent += value; remove => _someEvent -= value; }
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
}
}
using System.Web.Mvc;
namespace MvcApplication2.Controllers
{
public class HomeController : Controller
{
[NonAction]
public string ShowData()
{
return "Text";
}
public ActionResult Index()
{
ViewBag.Message = string.Format("{0}/{1}/{2}",
RouteData.Values["controller"],
RouteData.Values["action"],
RouteData.Values["id"]);
return View();
}
public ActionResult Search(string data = "*")
{
// do something ...
return View();
}
}
}
using System.Web.Mvc;
namespace MvcApplication2.Controllers
{
public class ActionResultsController : Controller
{
//http://localhost/actionresults/welcome
public string Welcome()
{
return "Hello, World";
}
//http://localhost/actionresults/index
public ActionResult Index() // or ContentResult
{
return Content("Hello, World");
}
//http://localhost/actionresults/SendMail
public void SendMail()
{
}
public ActionResult SendMailCompleted() // or EmptyResult
{
// do whatever
return new EmptyResult();
}
public ActionResult GetFile() // or FilePathResult
{
return File(Server.MapPath("~/content/site.css"), "text/css", "mySite.css");
}
public ActionResult UnauthorizedStatus() // or HttpStatusCodeResult/HttpUnauthorizedResult
{
return new HttpUnauthorizedResult("You need to login first.");
}
public ActionResult Status() // or HttpStatusCodeResult
{
return new HttpStatusCodeResult(501, "Server Error");
}
public ActionResult GetJavaScript() // or JavaScriptResult
{
return JavaScript("...JavaScript...");
}
public ActionResult GetJson() // or JsonResult
{
var obj = new { prop1 = 1, prop2 = "data" };
return Json(obj, JsonRequestBehavior.AllowGet);
}
public ActionResult RedirectTo() // or RedirectResult
{
return RedirectPermanent("http://www.site.com");
//return RedirectToAction("Home", "Index");
}
public ActionResult ShowView() // or ViewResult
{
return View();
}
}
}
[TestMethod]
public void TestMethod1()
{
// Arrange
var controller = new ActionResultsController();
// Act
var result = controller.Index() as ContentResult;
// Assert
Assert.NotNull(result);
Assert.AreEqual( "Hello, World", result.Content);
}