Skip to content

Commit 34bb823

Browse files
committed
Create edit details
1 parent b46ff04 commit 34bb823

File tree

11 files changed

+391
-333
lines changed

11 files changed

+391
-333
lines changed

ContosoUniversity/Features/Instructors/Create.cshtml

Lines changed: 0 additions & 77 deletions
This file was deleted.
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel.DataAnnotations;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using AutoMapper;
7+
using AutoMapper.QueryableExtensions;
8+
using ContosoUniversity.Data;
9+
using ContosoUniversity.Models;
10+
using FluentValidation;
11+
using MediatR;
12+
using Microsoft.EntityFrameworkCore;
13+
14+
namespace ContosoUniversity.Features.Instructors
15+
{
16+
public class CreateEdit
17+
{
18+
public class Query : IRequest<Command>
19+
{
20+
public int? Id { get; set; }
21+
}
22+
23+
public class QueryValidator : AbstractValidator<Query>
24+
{
25+
public QueryValidator()
26+
{
27+
RuleFor(m => m.Id).NotNull();
28+
}
29+
}
30+
31+
32+
public class Command : IRequest<int>
33+
{
34+
public Command()
35+
{
36+
AssignedCourses = new List<AssignedCourseData>();
37+
CourseAssignments = new List<CourseAssignment>();
38+
SelectedCourses = new string[0];
39+
}
40+
41+
public int? Id { get; set; }
42+
43+
public string LastName { get; set; }
44+
[Display(Name = "First Name")]
45+
public string FirstMidName { get; set; }
46+
47+
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
48+
public DateTime? HireDate { get; set; }
49+
50+
[Display(Name = "Location")]
51+
public string OfficeAssignmentLocation { get; set; }
52+
53+
[IgnoreMap]
54+
public string[] SelectedCourses { get; set; }
55+
56+
[IgnoreMap]
57+
public List<AssignedCourseData> AssignedCourses { get; set; }
58+
public List<CourseAssignment> CourseAssignments { get; set; }
59+
60+
public class AssignedCourseData
61+
{
62+
public int CourseID { get; set; }
63+
public string Title { get; set; }
64+
public bool Assigned { get; set; }
65+
}
66+
67+
public class CourseAssignment
68+
{
69+
public int CourseID { get; set; }
70+
}
71+
}
72+
73+
public class CommandValidator : AbstractValidator<Command>
74+
{
75+
public CommandValidator()
76+
{
77+
RuleFor(m => m.LastName).NotNull().Length(0, 50);
78+
RuleFor(m => m.FirstMidName).NotNull().Length(0, 50);
79+
RuleFor(m => m.HireDate).NotNull();
80+
}
81+
}
82+
83+
public class QueryHandler : IAsyncRequestHandler<Query, Command>
84+
{
85+
private readonly SchoolContext _db;
86+
87+
public QueryHandler(SchoolContext db)
88+
{
89+
_db = db;
90+
}
91+
92+
public async Task<Command> Handle(Query message)
93+
{
94+
Command model;
95+
if (message.Id == null)
96+
{
97+
model = new Command();
98+
}
99+
else
100+
{
101+
model = await _db.Instructors
102+
.Where(i => i.Id == message.Id)
103+
.Map()
104+
.SingleOrDefaultAsync<Command>();
105+
106+
//.ProjectTo<Command>()
107+
//.SingleOrDefaultAsync();
108+
}
109+
110+
PopulateAssignedCourseData(model);
111+
112+
return model;
113+
}
114+
115+
private void PopulateAssignedCourseData(Command model)
116+
{
117+
var allCourses = _db.Courses;
118+
var instructorCourses = new HashSet<int>(model.CourseAssignments.Select(c => c.CourseID));
119+
var viewModel = allCourses.Select(course => new Command.AssignedCourseData
120+
{
121+
CourseID = course.Id,
122+
Title = course.Title,
123+
Assigned = instructorCourses.Contains(course.Id)
124+
}).ToList();
125+
model.AssignedCourses = viewModel;
126+
}
127+
128+
}
129+
130+
public class CommandHandler : IAsyncRequestHandler<Command, int>
131+
{
132+
private readonly SchoolContext _db;
133+
134+
public CommandHandler(SchoolContext db)
135+
{
136+
_db = db;
137+
}
138+
139+
public async Task<int> Handle(Command message)
140+
{
141+
Instructor instructor;
142+
if (message.Id == null)
143+
{
144+
instructor = new Instructor();
145+
_db.Instructors.Add(instructor);
146+
}
147+
else
148+
{
149+
instructor = await _db.Instructors
150+
.Include(i => i.OfficeAssignment)
151+
.Include(i => i.CourseAssignments)
152+
.Where(i => i.Id == message.Id)
153+
.SingleAsync();
154+
}
155+
156+
var courses = await _db.Courses.ToListAsync();
157+
158+
instructor.Handle(message, courses);
159+
160+
await _db.SaveChangesAsync();
161+
162+
return instructor.Id;
163+
}
164+
}
165+
}
166+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
@model ContosoUniversity.Features.Instructors.CreateEdit.Command
2+
3+
@{
4+
ViewBag.Title = Model.Id == null ? "Create" : "Edit";
5+
}
6+
7+
<h2>@(Model.Id == null ? "Create" : "Edit")</h2>
8+
9+
<h4>Instructor</h4>
10+
<hr />
11+
<div class="row">
12+
<div class="col-md-4">
13+
<form>
14+
@Html.ValidationDiv()
15+
@Html.FormBlock(m => m.LastName)
16+
@Html.FormBlock(m => m.FirstMidName)
17+
@Html.FormBlock(m => m.HireDate)
18+
@Html.FormBlock(m => m.OfficeAssignmentLocation)
19+
<div class="form-group">
20+
<div class="col-md-offset-2 col-md-10">
21+
<table>
22+
<tr>
23+
@{
24+
int cnt = 0;
25+
26+
foreach (var course in Model.AssignedCourses)
27+
{
28+
if (cnt++ % 3 == 0)
29+
{
30+
@:</tr><tr>
31+
}
32+
@:<td>
33+
<label style="font-weight: normal">
34+
<input type="checkbox"
35+
name="selectedCourses"
36+
value="@course.CourseID"
37+
@(Html.Raw(course.Assigned ? "checked=\"checked\"" : "")) />
38+
@course.CourseID : @course.Title
39+
</label>
40+
@:</td>
41+
}
42+
@:</tr>
43+
}
44+
45+
</table>
46+
</div>
47+
</div>
48+
<div class="form-group">
49+
<input type="submit" value="Save" class="btn btn-default" />
50+
</div>
51+
</form>
52+
</div>
53+
</div>
54+
55+
<div>
56+
<a asp-action="Index">Back to List</a>
57+
</div>
58+
59+
@section Scripts {
60+
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
61+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using AutoMapper.QueryableExtensions;
6+
using ContosoUniversity.Data;
7+
using FluentValidation;
8+
using MediatR;
9+
using Microsoft.EntityFrameworkCore;
10+
11+
namespace ContosoUniversity.Features.Instructors
12+
{
13+
public class Details
14+
{
15+
public class Query : IRequest<Model>
16+
{
17+
public int? Id { get; set; }
18+
}
19+
20+
public class Validator : AbstractValidator<Query>
21+
{
22+
public Validator()
23+
{
24+
RuleFor(m => m.Id).NotNull();
25+
}
26+
}
27+
28+
public class Model
29+
{
30+
public int? ID { get; set; }
31+
32+
public string LastName { get; set; }
33+
[Display(Name = "First Name")]
34+
public string FirstMidName { get; set; }
35+
36+
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
37+
public DateTime? HireDate { get; set; }
38+
39+
[Display(Name = "Location")]
40+
public string OfficeAssignmentLocation { get; set; }
41+
}
42+
43+
public class Handler : IAsyncRequestHandler<Query, Model>
44+
{
45+
private readonly SchoolContext _db;
46+
47+
public Handler(SchoolContext db) => _db = db;
48+
49+
public Task<Model> Handle(Query message) => _db
50+
.Instructors
51+
.Where(i => i.Id == message.Id)
52+
.ProjectTo<Model>()
53+
.SingleOrDefaultAsync();
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)