Реализован функционал добавления фильмов.

Добавлена страница добавления фильма.
parent 881e671f
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<e p="Cinema.csproj" t="IncludeRecursive" /> <e p="Cinema.csproj" t="IncludeRecursive" />
<e p="Cinema.sln" t="IncludeFlat" /> <e p="Cinema.sln" t="IncludeFlat" />
<e p="Controllers" t="Include"> <e p="Controllers" t="Include">
<e p="Films.cs" t="Include" /> <e p="FilmsController.cs" t="Include" />
</e> </e>
<e p="Data" t="Include"> <e p="Data" t="Include">
<e p="CinemaContext.cs" t="Include" /> <e p="CinemaContext.cs" t="Include" />
...@@ -21,15 +21,20 @@ ...@@ -21,15 +21,20 @@
<e p="Models" t="Include"> <e p="Models" t="Include">
<e p="ErrorViewModel.cs" t="Include" /> <e p="ErrorViewModel.cs" t="Include" />
<e p="Film.cs" t="Include" /> <e p="Film.cs" t="Include" />
<e p="FilmViewModel.cs" t="Include" />
<e p="User.cs" t="Include" /> <e p="User.cs" t="Include" />
</e> </e>
<e p="Program.cs" t="Include" /> <e p="Program.cs" t="Include" />
<e p="Properties" t="Include"> <e p="Properties" t="Include">
<e p="launchSettings.json" t="Include" /> <e p="launchSettings.json" t="Include" />
</e> </e>
<e p="Services" t="Include">
<e p="UploadFileService.cs" t="Include" />
</e>
<e p="Startup.cs" t="Include" /> <e p="Startup.cs" t="Include" />
<e p="Views" t="Include"> <e p="Views" t="Include">
<e p="Films" t="Include"> <e p="Films" t="Include">
<e p="Add.cshtml" t="Include" />
<e p="Index.cshtml" t="Include" /> <e p="Index.cshtml" t="Include" />
</e> </e>
<e p="Shared" t="Include"> <e p="Shared" t="Include">
...@@ -57,6 +62,11 @@ ...@@ -57,6 +62,11 @@
<e p="site.css" t="Include" /> <e p="site.css" t="Include" />
</e> </e>
<e p="favicon.ico" t="Include" /> <e p="favicon.ico" t="Include" />
<e p="images" t="Include">
<e p="Posters" t="Include">
<e p="bell-1096280_960_720.png" t="Include" />
</e>
</e>
<e p="js" t="Include"> <e p="js" t="Include">
<e p="site.js" t="Include" /> <e p="site.js" t="Include" />
</e> </e>
......
...@@ -13,18 +13,17 @@ ...@@ -13,18 +13,17 @@
<select /> <select />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="411e953d-ac1b-431b-8c52-f61006a5f2f2" name="Default Changelist" comment="Добавлены модели: User для дополнительного описания сущности пользователя, в виде Имени и Фамилии.&#10;Film для описания сущности фильма.&#10;Определены и добавлены следующие nuget-пакеты :&#10;Identity, efCore Design, Proxies, Sqlite.Core&#10;Настроена конфигурация используемой БД.&#10;Добавлена начальная миграция"> <list default="true" id="411e953d-ac1b-431b-8c52-f61006a5f2f2" name="Default Changelist" comment="&#10;Добавлен файл БД(cinema.db)&#10;Удалены лишние файлы не относящиеся к проекту (HomeController) и его представления&#10;Стартовая страница изменена на Films/Index&#10;Добавлено представление для главной страницы Films/Index&#10;В контроллере Films добавлен Экшен Index">
<change afterPath="$PROJECT_DIR$/Controllers/Films.cs" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Controllers/FilmsController.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Views/Films/Index.cshtml" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Models/FilmViewModel.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/cinema.db" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Services/UploadFileService.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Views/Films/Add.cshtml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.Cinema/.idea/contentModel.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Cinema/.idea/contentModel.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/.idea.Cinema/.idea/contentModel.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Cinema/.idea/contentModel.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.Cinema/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Cinema/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/.idea.Cinema/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Cinema/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Controllers/HomeController.cs" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/Controllers/Films.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Data/CinemaContext.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Data/CinemaContext.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Models/Film.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Models/Film.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Startup.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Startup.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Startup.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Startup.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Views/Home/Index.cshtml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Views/Home/Privacy.cshtml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Views/Shared/Error.cshtml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Views/Shared/_Layout.cshtml" beforeDir="false" afterPath="$PROJECT_DIR$/Views/Shared/_Layout.cshtml" afterDir="false" />
</list> </list>
<list id="b32251c1-d844-4e65-bf1c-9f6cfe4d536a" name="Добавлены модели: User для дополнительного описания сущности пользователя, в виде Имени и Фамилии. Film для описания сущности фильма. Определены и добавлены следующие nuget-пакеты : Identity, efCore Design, Proxies, Sqlite Настроена конфигурация используемой БД. Добавлена начальная миграция" comment="" /> <list id="b32251c1-d844-4e65-bf1c-9f6cfe4d536a" name="Добавлены модели: User для дополнительного описания сущности пользователя, в виде Имени и Фамилии. Film для описания сущности фильма. Определены и добавлены следующие nuget-пакеты : Identity, efCore Design, Proxies, Sqlite Настроена конфигурация используемой БД. Добавлена начальная миграция" comment="" />
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
...@@ -47,13 +46,17 @@ ...@@ -47,13 +46,17 @@
<component name="IdeDocumentHistory"> <component name="IdeDocumentHistory">
<option name="CHANGED_PATHS"> <option name="CHANGED_PATHS">
<list> <list>
<option value="$PROJECT_DIR$/Models/Film.cs" />
<option value="$PROJECT_DIR$/Models/User.cs" /> <option value="$PROJECT_DIR$/Models/User.cs" />
<option value="$PROJECT_DIR$/Data/CinemaContext.cs" />
<option value="$PROJECT_DIR$/Views/Shared/_Layout.cshtml" /> <option value="$PROJECT_DIR$/Views/Shared/_Layout.cshtml" />
<option value="$PROJECT_DIR$/Controllers/Films.cs" />
<option value="$PROJECT_DIR$/Startup.cs" />
<option value="$PROJECT_DIR$/Views/Films/Index.cshtml" /> <option value="$PROJECT_DIR$/Views/Films/Index.cshtml" />
<option value="$PROJECT_DIR$/Services/UploadFileService.cs" />
<option value="$PROJECT_DIR$/Data/CinemaContext.cs" />
<option value="$PROJECT_DIR$/Startup.cs" />
<option value="$PROJECT_DIR$/Controllers/Films.cs" />
<option value="$PROJECT_DIR$/Models/FilmViewModel.cs" />
<option value="$PROJECT_DIR$/Views/Films/Add.cshtml" />
<option value="$PROJECT_DIR$/Controllers/FilmsController.cs" />
<option value="$PROJECT_DIR$/Models/Film.cs" />
</list> </list>
</option> </option>
</component> </component>
...@@ -110,7 +113,7 @@ ...@@ -110,7 +113,7 @@
<option name="number" value="Default" /> <option name="number" value="Default" />
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1605771522746</updated> <updated>1605771522746</updated>
<workItem from="1605771536927" duration="5505000" /> <workItem from="1605771536927" duration="10080000" />
</task> </task>
<task id="LOCAL-00001" summary="Начало проекта"> <task id="LOCAL-00001" summary="Начало проекта">
<created>1605772561160</created> <created>1605772561160</created>
...@@ -133,7 +136,14 @@ ...@@ -133,7 +136,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1605775039789</updated> <updated>1605775039789</updated>
</task> </task>
<option name="localTasksCounter" value="4" /> <task id="LOCAL-00004" summary="&#10;Добавлен файл БД(cinema.db)&#10;Удалены лишние файлы не относящиеся к проекту (HomeController) и его представления&#10;Стартовая страница изменена на Films/Index&#10;Добавлено представление для главной страницы Films/Index&#10;В контроллере Films добавлен Экшен Index">
<created>1605778110766</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1605778110766</updated>
</task>
<option name="localTasksCounter" value="5" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
...@@ -157,13 +167,30 @@ ...@@ -157,13 +167,30 @@
<MESSAGE value="Начало проекта" /> <MESSAGE value="Начало проекта" />
<MESSAGE value="Добавлены модели: User для дополнительного описания сущности пользователя, в виде Имени и Фамилии.&#10;Film для описания сущности фильма.&#10;Определены и добавлены следующие nuget-пакеты :&#10;Identity, efCore Design, Proxies, Sqlite&#10;Настроена конфигурация используемой БД.&#10;Добавлена начальная миграция" /> <MESSAGE value="Добавлены модели: User для дополнительного описания сущности пользователя, в виде Имени и Фамилии.&#10;Film для описания сущности фильма.&#10;Определены и добавлены следующие nuget-пакеты :&#10;Identity, efCore Design, Proxies, Sqlite&#10;Настроена конфигурация используемой БД.&#10;Добавлена начальная миграция" />
<MESSAGE value="Добавлены модели: User для дополнительного описания сущности пользователя, в виде Имени и Фамилии.&#10;Film для описания сущности фильма.&#10;Определены и добавлены следующие nuget-пакеты :&#10;Identity, efCore Design, Proxies, Sqlite.Core&#10;Настроена конфигурация используемой БД.&#10;Добавлена начальная миграция" /> <MESSAGE value="Добавлены модели: User для дополнительного описания сущности пользователя, в виде Имени и Фамилии.&#10;Film для описания сущности фильма.&#10;Определены и добавлены следующие nuget-пакеты :&#10;Identity, efCore Design, Proxies, Sqlite.Core&#10;Настроена конфигурация используемой БД.&#10;Добавлена начальная миграция" />
<option name="LAST_COMMIT_MESSAGE" value="Добавлены модели: User для дополнительного описания сущности пользователя, в виде Имени и Фамилии.&#10;Film для описания сущности фильма.&#10;Определены и добавлены следующие nuget-пакеты :&#10;Identity, efCore Design, Proxies, Sqlite.Core&#10;Настроена конфигурация используемой БД.&#10;Добавлена начальная миграция" /> <MESSAGE value="&#10;Добавлен файл БД(cinema.db)&#10;Удалены лишние файлы не относящиеся к проекту (HomeController) и его представления&#10;Стартовая страница изменена на Films/Index&#10;Добавлено представление для главной страницы Films/Index&#10;В контроллере Films добавлен Экшен Index" />
<option name="LAST_COMMIT_MESSAGE" value="&#10;Добавлен файл БД(cinema.db)&#10;Удалены лишние файлы не относящиеся к проекту (HomeController) и его представления&#10;Стартовая страница изменена на Films/Index&#10;Добавлено представление для главной страницы Films/Index&#10;В контроллере Films добавлен Экшен Index" />
</component> </component>
<component name="WindowStateProjectService"> <component name="WindowStateProjectService">
<state x="529" y="406" width="852" height="229" key="Git.Rebase.Log.Action.NewCommitMessage.Dialog" timestamp="1605775025446"> <state x="529" y="406" width="852" height="229" key="Git.Rebase.Log.Action.NewCommitMessage.Dialog" timestamp="1605775025446">
<screen x="0" y="0" width="1920" height="1044" /> <screen x="0" y="0" width="1920" height="1044" />
</state> </state>
<state x="529" y="406" width="852" height="229" key="Git.Rebase.Log.Action.NewCommitMessage.Dialog/0.0.1920.1044/1920.0.1920.1080@0.0.1920.1044" timestamp="1605775025446" /> <state x="529" y="406" width="852" height="229" key="Git.Rebase.Log.Action.NewCommitMessage.Dialog/0.0.1920.1044/1920.0.1920.1080@0.0.1920.1044" timestamp="1605775025446" />
<state width="1878" height="277" key="GridCell.Tab.0.bottom" timestamp="1605785567204">
<screen x="0" y="0" width="1920" height="1044" />
</state>
<state width="1878" height="277" key="GridCell.Tab.0.bottom/0.0.1920.1044/1920.0.1920.1080@0.0.1920.1044" timestamp="1605785567204" />
<state width="1878" height="277" key="GridCell.Tab.0.center" timestamp="1605785567204">
<screen x="0" y="0" width="1920" height="1044" />
</state>
<state width="1878" height="277" key="GridCell.Tab.0.center/0.0.1920.1044/1920.0.1920.1080@0.0.1920.1044" timestamp="1605785567204" />
<state width="1878" height="277" key="GridCell.Tab.0.left" timestamp="1605785567204">
<screen x="0" y="0" width="1920" height="1044" />
</state>
<state width="1878" height="277" key="GridCell.Tab.0.left/0.0.1920.1044/1920.0.1920.1080@0.0.1920.1044" timestamp="1605785567204" />
<state width="1878" height="277" key="GridCell.Tab.0.right" timestamp="1605785567204">
<screen x="0" y="0" width="1920" height="1044" />
</state>
<state width="1878" height="277" key="GridCell.Tab.0.right/0.0.1920.1044/1920.0.1920.1080@0.0.1920.1044" timestamp="1605785567204" />
<state x="644" y="228" width="622" height="585" key="RiderGenerateDialog" timestamp="1605774080803"> <state x="644" y="228" width="622" height="585" key="RiderGenerateDialog" timestamp="1605774080803">
<screen x="0" y="0" width="1920" height="1044" /> <screen x="0" y="0" width="1920" height="1044" />
</state> </state>
......
using System.Collections.Generic;
using System.Linq;
using Cinema.Data;
using Cinema.Models;
using Microsoft.AspNetCore.Mvc;
namespace Cinema.Controllers
{
public class Films : Controller
{
private CinemaContext _db;
public Films(CinemaContext db)
{
_db = db;
}
public IActionResult Index()
{
List<Film> films = _db.Films.OrderBy(f => f.UpdatedAt).ToList();
return View(films);
}
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Cinema.Data;
using Cinema.Models;
using Cinema.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
namespace Cinema.Controllers
{
public class Films : Controller
{
private CinemaContext _db;
private UploadFileService _uploader;
private readonly IHostEnvironment _environment;
public Films(
CinemaContext db,
UploadFileService uploader,
IHostEnvironment environment
)
{
_db = db;
_uploader = uploader;
_environment = environment;
}
public IActionResult Index()
{
List<Film> films = _db.Films.OrderBy(f => f.UpdatedAt).ToList();
return View(films);
}
[HttpGet]
public IActionResult Add()
{
return View();
}
public async Task<IActionResult> Add(FilmViewModel film)
{
if (!ModelState.IsValid) return View(film);
string path = Path.Combine(_environment.ContentRootPath,"wwwroot/images/Posters/");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
string posterPath = $"images/Posters/{film.Name}{film.File.FileName}";
_uploader.Upload(path, film.File.FileName, film.File);
Film post = new Film()
{
Description = film.Description,
Poster = posterPath,
UserId = "fixture"
};
var result = _db.Films.AddAsync(post);
if (!result.IsCompleted) return View(film);
await _db.SaveChangesAsync();
return RedirectToAction("Index");
}
}
}
\ No newline at end of file
...@@ -9,7 +9,9 @@ namespace Cinema.Data ...@@ -9,7 +9,9 @@ namespace Cinema.Data
public DbSet<Film> Films { get; set; } public DbSet<Film> Films { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options) protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=cinema.db"); => options
.UseLazyLoadingProxies()
.UseSqlite("Data Source=cinema.db");
public CinemaContext(DbContextOptions options) : base(options) public CinemaContext(DbContextOptions options) : base(options)
{ {
......
...@@ -10,10 +10,10 @@ namespace Cinema.Models ...@@ -10,10 +10,10 @@ namespace Cinema.Models
public string Poster { get; set; } public string Poster { get; set; }
public int PublishYear { get; set; } public int PublishYear { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; } public DateTime UpdatedAt { get; set; } = DateTime.Now;
public string UserId { get; set; } public string UserId { get; set; }
public User User { get; set; } public virtual User User { get; set; }
} }
} }
\ No newline at end of file
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Http;
namespace Cinema.Models
{
public class FilmViewModel
{
[Required(ErrorMessage = "Поле название обязательно для заполнения")]
[MinLength(10, ErrorMessage = "Минимальная длина описания 10 символов")]
[Display(Name = "Название фильма")]
public string Name { get; set; }
[Required(ErrorMessage = "Поле описание обязательно для заполнения")]
[MinLength(10, ErrorMessage = "Минимальная длина описания 10 символов")]
[Display(Name = "Описание")]
[DataType(DataType.Text)]
public string Description { get; set; }
[Required(ErrorMessage = "Загрузка фото обязательна")]
[DataType(DataType.Upload)]
[Display(Name = "Постер фильма")]
public IFormFile File { get; set; }
[Display(Name = "Название фильма")]
public int PublishYear { get; set; }
}
}
\ No newline at end of file
using System.IO;
using Microsoft.AspNetCore.Http;
namespace Cinema.Services
{
public class UploadFileService
{
public async void Upload(string path, string fileName, IFormFile file)
{
await using var stream = new FileStream(Path.Combine(path, fileName), FileMode.Create);
await file.CopyToAsync(stream);
}
}
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Cinema.Data; using Cinema.Data;
using Cinema.Services;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.HttpsPolicy;
...@@ -25,6 +26,8 @@ namespace Cinema ...@@ -25,6 +26,8 @@ namespace Cinema
{ {
services.AddControllersWithViews(); services.AddControllersWithViews();
services.AddDbContext<CinemaContext>(); services.AddDbContext<CinemaContext>();
services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/Login");
services.AddTransient<UploadFileService>();
} }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
......
@model FilmViewModel
@{
ViewBag.Title = "Добавление фильма";
Layout = "_Layout";
}
<div class="row">
<div class="col align-self-center">
<div class="form">
<form asp-action="Add" asp-controller="Films" method="post" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly"></div>
<div class="form-group">
<label asp-for="Name">Название фильма</label><br/>
<input class="form-control" asp-for="Name"/>
<span asp-validation-for="Description"></span>
</div>
<div class="form-group">
<label asp-for="Description">Описание фильма</label><br/>
<input class="form-control" asp-for="Description"/>
<span asp-validation-for="Description"></span>
</div>
<div class="form-group">
<label asp-for="File"></label><br />
<input class="form-control-file" asp-for="File"/>
<span asp-validation-for="File"></span>
</div>
<div class="form-group">
<label asp-for="PublishYear"></label><br />
<input class="form-control-file" asp-for="PublishYear"/>
<span asp-validation-for="File"></span>
</div>
<div>
<button class="form-control" type="submit" id="submit" >Добавить</button>
</div>
</form>
</div>
</div>
</div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment