mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-23 18:19:40 +00:00
Compare commits
143 Commits
version-1.
...
2.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5a664e481 | ||
|
|
64389a9bbe | ||
|
|
86e94d7812 | ||
|
|
9f05a3d34b | ||
|
|
63e0af2ee8 | ||
|
|
dc5e980efa | ||
|
|
e0ab3ddcca | ||
|
|
0c058894c2 | ||
|
|
98385cbcb0 | ||
|
|
77cac3b6be | ||
|
|
051150475f | ||
|
|
128683be0e | ||
|
|
576e3debf1 | ||
|
|
44f86eb8a1 | ||
|
|
22ff88ab79 | ||
|
|
70d89b9ad3 | ||
|
|
c94563c700 | ||
|
|
814df07034 | ||
|
|
4492d3eab7 | ||
|
|
efdfbf5dbb | ||
|
|
6f2e408083 | ||
|
|
70a4a68e7c | ||
|
|
a1942edbfe | ||
|
|
fd90301b1c | ||
|
|
58145d33e3 | ||
|
|
2135c30d66 | ||
|
|
5191531813 | ||
|
|
03018f32b7 | ||
|
|
e632d2bb69 | ||
|
|
7a56f643f7 | ||
|
|
056b955f52 | ||
|
|
0993f46c9e | ||
|
|
4ba0358987 | ||
|
|
721e3c45fd | ||
|
|
27f59c6971 | ||
|
|
943fb2f482 | ||
|
|
2c4bc302de | ||
|
|
5b634ee33c | ||
|
|
6e1fa2b2c3 | ||
|
|
f72ebbd66e | ||
|
|
391ceec559 | ||
|
|
076b5304e0 | ||
|
|
94fc84a9b4 | ||
|
|
9cce26ebd8 | ||
|
|
513d288a5d | ||
|
|
429a432dd3 | ||
|
|
76928bcbaa | ||
|
|
95c81729cd | ||
|
|
8352ec7626 | ||
|
|
bebb82eb69 | ||
|
|
3da87dd3d3 | ||
|
|
117c1a6cbd | ||
|
|
53f5a77490 | ||
|
|
5fd9b93324 | ||
|
|
55bd0c05cb | ||
|
|
f9068819be | ||
|
|
85bf621386 | ||
|
|
328eb0451b | ||
|
|
bc7742148e | ||
|
|
4ceed817a3 | ||
|
|
6d85e752e1 | ||
|
|
460f202832 | ||
|
|
73054559cc | ||
|
|
d007a3fbba | ||
|
|
fcd3cf9dd7 | ||
|
|
48bca777fe | ||
|
|
aadcfa1fb7 | ||
|
|
f683b39806 | ||
|
|
c128fa6e06 | ||
|
|
ed7e07a057 | ||
|
|
749d112b08 | ||
|
|
3ef23ece23 | ||
|
|
90922fb3c6 | ||
|
|
68e84bac3f | ||
|
|
bcb359e355 | ||
|
|
a7a3a359fa | ||
|
|
a38d3bdc4b | ||
|
|
627da65692 | ||
|
|
8e5f255346 | ||
|
|
67ba6271a0 | ||
|
|
a3bcc0d863 | ||
|
|
5e7bb0f5c5 | ||
|
|
8396be24c8 | ||
|
|
728b18431d | ||
|
|
32d9bdee6c | ||
|
|
9a59bccad9 | ||
|
|
e50d4825c3 | ||
|
|
bf6d2227db | ||
|
|
06c94d54eb | ||
|
|
bcaa3af92e | ||
|
|
3685592b01 | ||
|
|
f3b7103c83 | ||
|
|
2acdad38cd | ||
|
|
0dd24068ca | ||
|
|
0526852e05 | ||
|
|
e331355c1d | ||
|
|
60c8a3471d | ||
|
|
c7b7f40d2c | ||
|
|
d8c0bd8898 | ||
|
|
5127a74d3f | ||
|
|
e38399fbf4 | ||
|
|
045c05fc88 | ||
|
|
b444831c8d | ||
|
|
2aaceaa9f8 | ||
|
|
1c5bd98d8a | ||
|
|
0626bb1594 | ||
|
|
d9e75c89ae | ||
|
|
ebe9d8ae92 | ||
|
|
dbdc81a06a | ||
|
|
d42cd10975 | ||
|
|
8a1d64cc73 | ||
|
|
087183ea18 | ||
|
|
9b131ea7d3 | ||
|
|
75fd215b1a | ||
|
|
38997c3f3f | ||
|
|
bee4c6ff11 | ||
|
|
cc859306a3 | ||
|
|
44512226c6 | ||
|
|
a2bde750be | ||
|
|
c592282646 | ||
|
|
b86e9f9254 | ||
|
|
970dc6c457 | ||
|
|
6baa2faf09 | ||
|
|
918e7edbff | ||
|
|
e1c90b3601 | ||
|
|
b9e62cd4c9 | ||
|
|
ad9cfbb176 | ||
|
|
941ae9a34d | ||
|
|
3645ae6cf2 | ||
|
|
ad645cbfe9 | ||
|
|
d5483f3b64 | ||
|
|
a4512873f9 | ||
|
|
9e59ed4bc8 | ||
|
|
b091932e10 | ||
|
|
42b88c15f2 | ||
|
|
3ee16a5ba5 | ||
|
|
33cc640942 | ||
|
|
baae62132b | ||
|
|
58fa07d4dc | ||
|
|
deaaa43e02 | ||
|
|
58fd9150b9 | ||
|
|
244deca019 | ||
|
|
e081d5e091 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -28,6 +28,8 @@ nuget.exe
|
|||||||
.vs/
|
.vs/
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
/.build/
|
/.build/
|
||||||
|
global.json
|
||||||
|
*.g.targets
|
||||||
|
|
||||||
# The templates can't contain their own .gitignore files, because Yeoman has strange default handling for
|
# The templates can't contain their own .gitignore files, because Yeoman has strange default handling for
|
||||||
# files with that name (https://github.com/npm/npm/issues/1862). So, each template instead has a template_gitignore
|
# files with that name (https://github.com/npm/npm/issues/1862). So, each template instead has a template_gitignore
|
||||||
|
|||||||
4
Directory.Build.targets
Normal file
4
Directory.Build.targets
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<Project>
|
||||||
|
<Import Project="build\sources.props" />
|
||||||
|
<Import Project="build\dependencies.props" />
|
||||||
|
</Project>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26228.4
|
VisualStudioVersion = 15.0.26430.4
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{27304DDE-AFB2-4F8B-B765-E3E2F11E886C}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{27304DDE-AFB2-4F8B-B765-E3E2F11E886C}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -11,10 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.NodeSe
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SpaServices", "src\Microsoft.AspNetCore.SpaServices\Microsoft.AspNetCore.SpaServices.csproj", "{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SpaServices", "src\Microsoft.AspNetCore.SpaServices\Microsoft.AspNetCore.SpaServices.csproj", "{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.AngularServices", "src\Microsoft.AspNetCore.AngularServices\Microsoft.AspNetCore.AngularServices.csproj", "{58AAABB6-9D21-42F6-BC97-3DD282B55FD6}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.ReactServices", "src\Microsoft.AspNetCore.ReactServices\Microsoft.AspNetCore.ReactServices.csproj", "{F1081B9A-8D67-4A5E-80C6-615F9A975D4F}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "misc", "misc", "{99EAF1FE-22C8-4526-BE78-74B24125D37F}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "misc", "misc", "{99EAF1FE-22C8-4526-BE78-74B24125D37F}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.gitignore = .gitignore
|
.gitignore = .gitignore
|
||||||
@@ -32,38 +28,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Webpack", "samples\misc\Web
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NodeServicesExamples", "samples\misc\NodeServicesExamples\NodeServicesExamples.csproj", "{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NodeServicesExamples", "samples\misc\NodeServicesExamples\NodeServicesExamples.csproj", "{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "angular", "angular", "{B54435EB-D5E8-4CEC-A02E-DDCB0C750E34}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicStore", "samples\angular\MusicStore\MusicStore.csproj", "{63FC66E7-559B-4426-93E1-2D951EFC8293}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "react", "react", "{BD77E73E-13BC-4550-99DA-51869BD8DFC4}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactGrid", "samples\react\ReactGrid\ReactGrid.csproj", "{3B023106-88DB-4C3A-B01F-C1AECB02D80B}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicStore", "samples\react\MusicStore\MusicStore.csproj", "{6E898586-79CA-4AA8-946E-943B3682F376}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{1598B415-73F1-4B37-B3B4-0A10677ABB2D}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{1598B415-73F1-4B37-B3B4-0A10677ABB2D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KnockoutSpa", "templates\KnockoutSpa\KnockoutSpa.csproj", "{F60248B1-940E-43FB-BEA0-589362AA6320}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AngularSpa", "templates\AngularSpa\AngularSpa.csproj", "{4D4B84C9-13F7-40CA-B05A-DC98FD6019AC}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AureliaSpa", "templates\AureliaSpa\AureliaSpa.csproj", "{4D57B6E1-7141-48ED-959E-872BDD4A2F72}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactSpa", "templates\ReactSpa\ReactSpa.csproj", "{868A630E-C61B-4807-B7A8-7EB53BE1C28A}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactReduxSpa", "templates\ReactReduxSpa\ReactReduxSpa.csproj", "{9D4D15A1-A25B-44EC-AB63-F1CE9986712E}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApplicationBasic", "templates\WebApplicationBasic\WebApplicationBasic.csproj", "{86911E07-C733-4C18-B49F-9A007A651246}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{E415FE14-13B0-469F-836D-95059E6BAA6E}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{E415FE14-13B0-469F-836D-95059E6BAA6E}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
src\build\common.props = src\build\common.props
|
src\build\common.props = src\build\common.props
|
||||||
src\build\Key.snk = src\build\Key.snk
|
src\build\Key.snk = src\build\Key.snk
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VueSpa", "templates\VueSpa\VueSpa.csproj", "{49D7665A-20EC-43FC-B8E8-EA0204F2D8C3}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -82,14 +54,6 @@ Global
|
|||||||
{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{58AAABB6-9D21-42F6-BC97-3DD282B55FD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{58AAABB6-9D21-42F6-BC97-3DD282B55FD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{58AAABB6-9D21-42F6-BC97-3DD282B55FD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{58AAABB6-9D21-42F6-BC97-3DD282B55FD6}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F1081B9A-8D67-4A5E-80C6-615F9A975D4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F1081B9A-8D67-4A5E-80C6-615F9A975D4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F1081B9A-8D67-4A5E-80C6-615F9A975D4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F1081B9A-8D67-4A5E-80C6-615F9A975D4F}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{1931B19A-EC42-4D56-B2D0-FB06D17244DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{1931B19A-EC42-4D56-B2D0-FB06D17244DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{1931B19A-EC42-4D56-B2D0-FB06D17244DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1931B19A-EC42-4D56-B2D0-FB06D17244DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1931B19A-EC42-4D56-B2D0-FB06D17244DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1931B19A-EC42-4D56-B2D0-FB06D17244DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -102,46 +66,6 @@ Global
|
|||||||
{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{63FC66E7-559B-4426-93E1-2D951EFC8293}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{63FC66E7-559B-4426-93E1-2D951EFC8293}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{63FC66E7-559B-4426-93E1-2D951EFC8293}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{63FC66E7-559B-4426-93E1-2D951EFC8293}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{3B023106-88DB-4C3A-B01F-C1AECB02D80B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{3B023106-88DB-4C3A-B01F-C1AECB02D80B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{3B023106-88DB-4C3A-B01F-C1AECB02D80B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{3B023106-88DB-4C3A-B01F-C1AECB02D80B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6E898586-79CA-4AA8-946E-943B3682F376}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{6E898586-79CA-4AA8-946E-943B3682F376}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{6E898586-79CA-4AA8-946E-943B3682F376}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{6E898586-79CA-4AA8-946E-943B3682F376}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F60248B1-940E-43FB-BEA0-589362AA6320}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F60248B1-940E-43FB-BEA0-589362AA6320}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F60248B1-940E-43FB-BEA0-589362AA6320}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F60248B1-940E-43FB-BEA0-589362AA6320}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4D4B84C9-13F7-40CA-B05A-DC98FD6019AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4D4B84C9-13F7-40CA-B05A-DC98FD6019AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4D4B84C9-13F7-40CA-B05A-DC98FD6019AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4D4B84C9-13F7-40CA-B05A-DC98FD6019AC}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4D57B6E1-7141-48ED-959E-872BDD4A2F72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4D57B6E1-7141-48ED-959E-872BDD4A2F72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4D57B6E1-7141-48ED-959E-872BDD4A2F72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4D57B6E1-7141-48ED-959E-872BDD4A2F72}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{868A630E-C61B-4807-B7A8-7EB53BE1C28A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{868A630E-C61B-4807-B7A8-7EB53BE1C28A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{868A630E-C61B-4807-B7A8-7EB53BE1C28A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{868A630E-C61B-4807-B7A8-7EB53BE1C28A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{9D4D15A1-A25B-44EC-AB63-F1CE9986712E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{9D4D15A1-A25B-44EC-AB63-F1CE9986712E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{9D4D15A1-A25B-44EC-AB63-F1CE9986712E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{9D4D15A1-A25B-44EC-AB63-F1CE9986712E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{86911E07-C733-4C18-B49F-9A007A651246}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{86911E07-C733-4C18-B49F-9A007A651246}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{86911E07-C733-4C18-B49F-9A007A651246}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{86911E07-C733-4C18-B49F-9A007A651246}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{49D7665A-20EC-43FC-B8E8-EA0204F2D8C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{49D7665A-20EC-43FC-B8E8-EA0204F2D8C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{49D7665A-20EC-43FC-B8E8-EA0204F2D8C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{49D7665A-20EC-43FC-B8E8-EA0204F2D8C3}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -150,24 +74,9 @@ Global
|
|||||||
{66B77203-1469-41DF-92F2-2BE6900BD36F} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
{66B77203-1469-41DF-92F2-2BE6900BD36F} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
||||||
{F46DEF99-6FAA-4406-B5D8-6FF34EF669E3} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
{F46DEF99-6FAA-4406-B5D8-6FF34EF669E3} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
||||||
{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
{66B071A8-EFC8-4A06-BEF6-06B99AE27EEC} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
||||||
{58AAABB6-9D21-42F6-BC97-3DD282B55FD6} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
|
||||||
{F1081B9A-8D67-4A5E-80C6-615F9A975D4F} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
|
||||||
{E6A161EA-646C-4033-9090-95BE809AB8D9} = {23836492-E7F4-4376-85BF-A635C304AC46}
|
{E6A161EA-646C-4033-9090-95BE809AB8D9} = {23836492-E7F4-4376-85BF-A635C304AC46}
|
||||||
{1931B19A-EC42-4D56-B2D0-FB06D17244DA} = {E6A161EA-646C-4033-9090-95BE809AB8D9}
|
{1931B19A-EC42-4D56-B2D0-FB06D17244DA} = {E6A161EA-646C-4033-9090-95BE809AB8D9}
|
||||||
{DE479DC3-1461-4EAD-A188-4AF7AA4AE344} = {E6A161EA-646C-4033-9090-95BE809AB8D9}
|
{DE479DC3-1461-4EAD-A188-4AF7AA4AE344} = {E6A161EA-646C-4033-9090-95BE809AB8D9}
|
||||||
{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE} = {E6A161EA-646C-4033-9090-95BE809AB8D9}
|
{93EFCC5F-C6EE-4623-894F-A42B22C0B6FE} = {E6A161EA-646C-4033-9090-95BE809AB8D9}
|
||||||
{B54435EB-D5E8-4CEC-A02E-DDCB0C750E34} = {23836492-E7F4-4376-85BF-A635C304AC46}
|
|
||||||
{63FC66E7-559B-4426-93E1-2D951EFC8293} = {B54435EB-D5E8-4CEC-A02E-DDCB0C750E34}
|
|
||||||
{BD77E73E-13BC-4550-99DA-51869BD8DFC4} = {23836492-E7F4-4376-85BF-A635C304AC46}
|
|
||||||
{3B023106-88DB-4C3A-B01F-C1AECB02D80B} = {BD77E73E-13BC-4550-99DA-51869BD8DFC4}
|
|
||||||
{6E898586-79CA-4AA8-946E-943B3682F376} = {BD77E73E-13BC-4550-99DA-51869BD8DFC4}
|
|
||||||
{F60248B1-940E-43FB-BEA0-589362AA6320} = {1598B415-73F1-4B37-B3B4-0A10677ABB2D}
|
|
||||||
{4D4B84C9-13F7-40CA-B05A-DC98FD6019AC} = {1598B415-73F1-4B37-B3B4-0A10677ABB2D}
|
|
||||||
{4D57B6E1-7141-48ED-959E-872BDD4A2F72} = {1598B415-73F1-4B37-B3B4-0A10677ABB2D}
|
|
||||||
{868A630E-C61B-4807-B7A8-7EB53BE1C28A} = {1598B415-73F1-4B37-B3B4-0A10677ABB2D}
|
|
||||||
{9D4D15A1-A25B-44EC-AB63-F1CE9986712E} = {1598B415-73F1-4B37-B3B4-0A10677ABB2D}
|
|
||||||
{86911E07-C733-4C18-B49F-9A007A651246} = {1598B415-73F1-4B37-B3B4-0A10677ABB2D}
|
|
||||||
{E415FE14-13B0-469F-836D-95059E6BAA6E} = {27304DDE-AFB2-4F8B-B765-E3E2F11E886C}
|
|
||||||
{49D7665A-20EC-43FC-B8E8-EA0204F2D8C3} = {1598B415-73F1-4B37-B3B4-0A10677ABB2D}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
Copyright (c) .NET Foundation. All rights reserved.
|
Copyright (c) .NET Foundation and Contributors
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||||
these files except in compliance with the License. You may obtain a copy of the
|
this file except in compliance with the License. You may obtain a copy of the
|
||||||
License at
|
License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software distributed
|
Unless required by applicable law or agreed to in writing, software distributed
|
||||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" />
|
<clear />
|
||||||
<add key="AspNetCoreTools" value="https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json" />
|
<!-- Restore sources should be defined in build/sources.props. -->
|
||||||
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
|
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ If you're interested in contributing to the various packages, samples, and proje
|
|||||||
* Run `dotnet restore` at the repo root dir
|
* Run `dotnet restore` at the repo root dir
|
||||||
* Go to whatever sample or template you want to run (for example, `cd templates/AngularSpa`)
|
* Go to whatever sample or template you want to run (for example, `cd templates/AngularSpa`)
|
||||||
* Restore NPM dependencies (run `npm install`)
|
* Restore NPM dependencies (run `npm install`)
|
||||||
* If the sample/template you're trying to run has a file called `webpack.config.vendor.js` at its root, run `webpack --config webpack.config.vendor.js`. It it has a file called `webpack.config.js`, run `webpack` (no args). You might need to install webpack first, by running `npm install -g webpack`.
|
* If the sample/template you're trying to run has a file called `webpack.config.vendor.js` at its root, run `webpack --config webpack.config.vendor.js`. If it has a file called `webpack.config.js`, run `webpack` (no args). You might need to install webpack first, by running `npm install -g webpack`.
|
||||||
* Launch it (`dotnet run`)
|
* Launch it (`dotnet run`)
|
||||||
|
|
||||||
If you're planning to submit a pull request, and if it's more than a trivial fix (for example, for a typo), it's usually a good idea first to file an issue describing what you're proposing to do and how it will work. Then you can find out if it's likely that such a pull request will be accepted, and how it fits into wider ongoing plans.
|
If you're planning to submit a pull request, and if it's more than a trivial fix (for example, for a typo), it's usually a good idea first to file an issue describing what you're proposing to do and how it will work. Then you can find out if it's likely that such a pull request will be accepted, and how it fits into wider ongoing plans.
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ init:
|
|||||||
install:
|
install:
|
||||||
- ps: Install-Product node 6.9.2 x64
|
- ps: Install-Product node 6.9.2 x64
|
||||||
# .NET Core SDK binaries
|
# .NET Core SDK binaries
|
||||||
# Download .NET Core SDK and add to PATH
|
# Download .NET Core 2.0 Preview 3 SDK and add to PATH
|
||||||
- ps: $urlCurrent = "https://download.microsoft.com/download/E/7/8/E782433E-7737-4E6C-BFBF-290A0A81C3D7/dotnet-dev-win-x64.1.0.4.zip"
|
- ps: $urlCurrent = "https://dotnetcli.azureedge.net/dotnet/Sdk/2.0.0-preview3-006729/dotnet-sdk-2.0.0-preview3-006729-win-x64.zip"
|
||||||
- ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetsdk"
|
- ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetsdk"
|
||||||
- ps: mkdir $env:DOTNET_INSTALL_DIR -Force | Out-Null
|
- ps: mkdir $env:DOTNET_INSTALL_DIR -Force | Out-Null
|
||||||
- ps: $tempFileCurrent = [System.IO.Path]::GetTempFileName()
|
- ps: $tempFileCurrent = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
|
||||||
- ps: (New-Object System.Net.WebClient).DownloadFile($urlCurrent, $tempFileCurrent)
|
- ps: (New-Object System.Net.WebClient).DownloadFile($urlCurrent, $tempFileCurrent)
|
||||||
- ps: Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory($tempFileCurrent, $env:DOTNET_INSTALL_DIR)
|
- ps: Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory($tempFileCurrent, $env:DOTNET_INSTALL_DIR)
|
||||||
- ps: $env:Path = "$env:DOTNET_INSTALL_DIR;$env:Path"
|
- ps: $env:Path = "$env:DOTNET_INSTALL_DIR;$env:Path"
|
||||||
|
|||||||
219
build.ps1
219
build.ps1
@@ -1,67 +1,186 @@
|
|||||||
$ErrorActionPreference = "Stop"
|
#!/usr/bin/env powershell
|
||||||
|
#requires -version 4
|
||||||
|
|
||||||
function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries)
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Build this repository
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Downloads korebuild if required. Then builds the repository.
|
||||||
|
|
||||||
|
.PARAMETER Path
|
||||||
|
The folder to build. Defaults to the folder containing this script.
|
||||||
|
|
||||||
|
.PARAMETER Channel
|
||||||
|
The channel of KoreBuild to download. Overrides the value from the config file.
|
||||||
|
|
||||||
|
.PARAMETER DotNetHome
|
||||||
|
The directory where .NET Core tools will be stored.
|
||||||
|
|
||||||
|
.PARAMETER ToolsSource
|
||||||
|
The base url where build tools can be downloaded. Overrides the value from the config file.
|
||||||
|
|
||||||
|
.PARAMETER Update
|
||||||
|
Updates KoreBuild to the latest version even if a lock file is present.
|
||||||
|
|
||||||
|
.PARAMETER ConfigFile
|
||||||
|
The path to the configuration file that stores values. Defaults to version.props.
|
||||||
|
|
||||||
|
.PARAMETER MSBuildArgs
|
||||||
|
Arguments to be passed to MSBuild
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
|
||||||
|
When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
|
||||||
|
|
||||||
|
The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set
|
||||||
|
in the file are overridden by command line parameters.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Example config file:
|
||||||
|
```json
|
||||||
{
|
{
|
||||||
while($true)
|
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json",
|
||||||
{
|
"channel": "dev",
|
||||||
try
|
"toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools"
|
||||||
{
|
|
||||||
Invoke-WebRequest $url -OutFile $downloadLocation
|
|
||||||
break
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
$exceptionMessage = $_.Exception.Message
|
|
||||||
Write-Host "Failed to download '$url': $exceptionMessage"
|
|
||||||
if ($retries -gt 0) {
|
|
||||||
$retries--
|
|
||||||
Write-Host "Waiting 10 seconds before retrying. Retries left: $retries"
|
|
||||||
Start-Sleep -Seconds 10
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$exception = $_.Exception
|
|
||||||
throw $exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
#>
|
||||||
|
[CmdletBinding(PositionalBinding = $false)]
|
||||||
|
param(
|
||||||
|
[string]$Path = $PSScriptRoot,
|
||||||
|
[Alias('c')]
|
||||||
|
[string]$Channel,
|
||||||
|
[Alias('d')]
|
||||||
|
[string]$DotNetHome,
|
||||||
|
[Alias('s')]
|
||||||
|
[string]$ToolsSource,
|
||||||
|
[Alias('u')]
|
||||||
|
[switch]$Update,
|
||||||
|
[string]$ConfigFile = $null,
|
||||||
|
[Parameter(ValueFromRemainingArguments = $true)]
|
||||||
|
[string[]]$MSBuildArgs
|
||||||
|
)
|
||||||
|
|
||||||
cd $PSScriptRoot
|
Set-StrictMode -Version 2
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
$repoFolder = $PSScriptRoot
|
#
|
||||||
$env:REPO_FOLDER = $repoFolder
|
# Functions
|
||||||
|
#
|
||||||
|
|
||||||
$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
function Get-KoreBuild {
|
||||||
if ($env:KOREBUILD_ZIP)
|
|
||||||
{
|
|
||||||
$koreBuildZip=$env:KOREBUILD_ZIP
|
|
||||||
}
|
|
||||||
|
|
||||||
$buildFolder = ".build"
|
$lockFile = Join-Path $Path 'korebuild-lock.txt'
|
||||||
$buildFile="$buildFolder\KoreBuild.ps1"
|
|
||||||
|
|
||||||
if (!(Test-Path $buildFolder)) {
|
if (!(Test-Path $lockFile) -or $Update) {
|
||||||
Write-Host "Downloading KoreBuild from $koreBuildZip"
|
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile
|
||||||
|
}
|
||||||
|
|
||||||
$tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid()
|
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
|
||||||
New-Item -Path "$tempFolder" -Type directory | Out-Null
|
if (!$version) {
|
||||||
|
Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'"
|
||||||
|
}
|
||||||
|
$version = $version.TrimStart('version:').Trim()
|
||||||
|
$korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
|
||||||
|
|
||||||
$localZipFile="$tempFolder\korebuild.zip"
|
if (!(Test-Path $korebuildPath)) {
|
||||||
|
Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
|
||||||
DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6
|
New-Item -ItemType Directory -Path $korebuildPath | Out-Null
|
||||||
|
$remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
|
||||||
|
|
||||||
|
try {
|
||||||
|
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
|
||||||
|
Get-RemoteFile $remotePath $tmpfile
|
||||||
|
if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
|
||||||
|
# Use built-in commands where possible as they are cross-plat compatible
|
||||||
|
Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Fallback to old approach for old installations of PowerShell
|
||||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder)
|
[System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Remove-Item $tmpfile -ErrorAction Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
New-Item -Path "$buildFolder" -Type directory | Out-Null
|
return $korebuildPath
|
||||||
copy-item "$tempFolder\**\build\*" $buildFolder -Recurse
|
}
|
||||||
|
|
||||||
# Cleanup
|
function Join-Paths([string]$path, [string[]]$childPaths) {
|
||||||
if (Test-Path $tempFolder) {
|
$childPaths | ForEach-Object { $path = Join-Path $path $_ }
|
||||||
Remove-Item -Recurse -Force $tempFolder
|
return $path
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
|
||||||
|
if ($RemotePath -notlike 'http*') {
|
||||||
|
Copy-Item $RemotePath $LocalPath
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$retries = 10
|
||||||
|
while ($retries -gt 0) {
|
||||||
|
$retries -= 1
|
||||||
|
try {
|
||||||
|
Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath
|
||||||
|
return
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Verbose "Request failed. $retries retries remaining"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Error "Download failed: '$RemotePath'."
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Main
|
||||||
|
#
|
||||||
|
|
||||||
|
# Load configuration or set defaults
|
||||||
|
|
||||||
|
$Path = Resolve-Path $Path
|
||||||
|
if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' }
|
||||||
|
|
||||||
|
if (Test-Path $ConfigFile) {
|
||||||
|
try {
|
||||||
|
$config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json
|
||||||
|
if ($config) {
|
||||||
|
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
|
||||||
|
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Warning "$ConfigFile could not be read. Its settings will be ignored."
|
||||||
|
Write-Warning $Error[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&"$buildFile" @args
|
if (!$DotNetHome) {
|
||||||
|
$DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
|
||||||
|
elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
|
||||||
|
elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
|
||||||
|
else { Join-Path $PSScriptRoot '.dotnet'}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$Channel) { $Channel = 'dev' }
|
||||||
|
if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
|
||||||
|
|
||||||
|
# Execute
|
||||||
|
|
||||||
|
$korebuildPath = Get-KoreBuild
|
||||||
|
Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
|
||||||
|
|
||||||
|
try {
|
||||||
|
Install-Tools $ToolsSource $DotNetHome
|
||||||
|
Invoke-RepositoryBuild $Path @MSBuildArgs
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Remove-Module 'KoreBuild' -ErrorAction Ignore
|
||||||
|
}
|
||||||
|
|||||||
242
build.sh
242
build.sh
@@ -1,46 +1,220 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
||||||
cd $repoFolder
|
|
||||||
|
|
||||||
koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
set -euo pipefail
|
||||||
if [ ! -z $KOREBUILD_ZIP ]; then
|
|
||||||
koreBuildZip=$KOREBUILD_ZIP
|
|
||||||
fi
|
|
||||||
|
|
||||||
buildFolder=".build"
|
#
|
||||||
buildFile="$buildFolder/KoreBuild.sh"
|
# variables
|
||||||
|
#
|
||||||
|
|
||||||
if test ! -d $buildFolder; then
|
RESET="\033[0m"
|
||||||
echo "Downloading KoreBuild from $koreBuildZip"
|
RED="\033[0;31m"
|
||||||
|
YELLOW="\033[0;33m"
|
||||||
|
MAGENTA="\033[0;95m"
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
|
||||||
|
config_file="$DIR/korebuild.json"
|
||||||
|
verbose=false
|
||||||
|
update=false
|
||||||
|
repo_path="$DIR"
|
||||||
|
channel=''
|
||||||
|
tools_source=''
|
||||||
|
|
||||||
tempFolder="/tmp/KoreBuild-$(uuidgen)"
|
#
|
||||||
mkdir $tempFolder
|
# Functions
|
||||||
|
#
|
||||||
|
__usage() {
|
||||||
|
echo "Usage: $(basename "${BASH_SOURCE[0]}") [options] [[--] <MSBUILD_ARG>...]"
|
||||||
|
echo ""
|
||||||
|
echo "Arguments:"
|
||||||
|
echo " <MSBUILD_ARG>... Arguments passed to MSBuild. Variable number of arguments allowed."
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " --verbose Show verbose output."
|
||||||
|
echo " -c|--channel <CHANNEL> The channel of KoreBuild to download. Overrides the value from the config file.."
|
||||||
|
echo " --config-file <FILE> The path to the configuration file that stores values. Defaults to korebuild.json."
|
||||||
|
echo " -d|--dotnet-home <DIR> The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet."
|
||||||
|
echo " --path <PATH> The directory to build. Defaults to the directory containing the script."
|
||||||
|
echo " -s|--tools-source <URL> The base url where build tools can be downloaded. Overrides the value from the config file."
|
||||||
|
echo " -u|--update Update to the latest KoreBuild even if the lock file is present."
|
||||||
|
echo ""
|
||||||
|
echo "Description:"
|
||||||
|
echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be."
|
||||||
|
echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel."
|
||||||
|
|
||||||
localZipFile="$tempFolder/korebuild.zip"
|
if [[ "${1:-}" != '--no-exit' ]]; then
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
retries=6
|
get_korebuild() {
|
||||||
until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null)
|
local version
|
||||||
do
|
local lock_file="$repo_path/korebuild-lock.txt"
|
||||||
echo "Failed to download '$koreBuildZip'"
|
if [ ! -f "$lock_file" ] || [ "$update" = true ]; then
|
||||||
if [ "$retries" -le 0 ]; then
|
__get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file"
|
||||||
|
fi
|
||||||
|
version="$(grep 'version:*' -m 1 "$lock_file")"
|
||||||
|
if [[ "$version" == '' ]]; then
|
||||||
|
__error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
|
||||||
|
local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version"
|
||||||
|
|
||||||
|
{
|
||||||
|
if [ ! -d "$korebuild_path" ]; then
|
||||||
|
mkdir -p "$korebuild_path"
|
||||||
|
local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip"
|
||||||
|
tmpfile="$(mktemp)"
|
||||||
|
echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}"
|
||||||
|
if __get_remote_file "$remote_path" "$tmpfile"; then
|
||||||
|
unzip -q -d "$korebuild_path" "$tmpfile"
|
||||||
|
fi
|
||||||
|
rm "$tmpfile" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "$korebuild_path/KoreBuild.sh"
|
||||||
|
} || {
|
||||||
|
if [ -d "$korebuild_path" ]; then
|
||||||
|
echo "Cleaning up after failed installation"
|
||||||
|
rm -rf "$korebuild_path" || true
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__error() {
|
||||||
|
echo -e "${RED}error: $*${RESET}" 1>&2
|
||||||
|
}
|
||||||
|
|
||||||
|
__warn() {
|
||||||
|
echo -e "${YELLOW}warning: $*${RESET}"
|
||||||
|
}
|
||||||
|
|
||||||
|
__machine_has() {
|
||||||
|
hash "$1" > /dev/null 2>&1
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
__get_remote_file() {
|
||||||
|
local remote_path=$1
|
||||||
|
local local_path=$2
|
||||||
|
|
||||||
|
if [[ "$remote_path" != 'http'* ]]; then
|
||||||
|
cp "$remote_path" "$local_path"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local failed=false
|
||||||
|
if __machine_has wget; then
|
||||||
|
wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true
|
||||||
|
else
|
||||||
|
failed=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$failed" = true ] && __machine_has curl; then
|
||||||
|
failed=false
|
||||||
|
curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$failed" = true ]; then
|
||||||
|
__error "Download failed: $remote_path" 1>&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# main
|
||||||
|
#
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-\?|-h|--help)
|
||||||
|
__usage --no-exit
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-c|--channel|-Channel)
|
||||||
|
shift
|
||||||
|
channel="${1:-}"
|
||||||
|
[ -z "$channel" ] && __usage
|
||||||
|
;;
|
||||||
|
--config-file|-ConfigFile)
|
||||||
|
shift
|
||||||
|
config_file="${1:-}"
|
||||||
|
[ -z "$config_file" ] && __usage
|
||||||
|
if [ ! -f "$config_file" ]; then
|
||||||
|
__error "Invalid value for --config-file. $config_file does not exist."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
retries=$((retries - 1))
|
;;
|
||||||
echo "Waiting 10 seconds before retrying. Retries left: $retries"
|
-d|--dotnet-home|-DotNetHome)
|
||||||
sleep 10s
|
shift
|
||||||
done
|
DOTNET_HOME="${1:-}"
|
||||||
|
[ -z "$DOTNET_HOME" ] && __usage
|
||||||
|
;;
|
||||||
|
--path|-Path)
|
||||||
|
shift
|
||||||
|
repo_path="${1:-}"
|
||||||
|
[ -z "$repo_path" ] && __usage
|
||||||
|
;;
|
||||||
|
-s|--tools-source|-ToolsSource)
|
||||||
|
shift
|
||||||
|
tools_source="${1:-}"
|
||||||
|
[ -z "$tools_source" ] && __usage
|
||||||
|
;;
|
||||||
|
-u|--update|-Update)
|
||||||
|
update=true
|
||||||
|
;;
|
||||||
|
--verbose|-Verbose)
|
||||||
|
verbose=true
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
unzip -q -d $tempFolder $localZipFile
|
if ! __machine_has unzip; then
|
||||||
|
__error 'Missing required command: unzip'
|
||||||
mkdir $buildFolder
|
exit 1
|
||||||
cp -r $tempFolder/**/build/** $buildFolder
|
|
||||||
|
|
||||||
chmod +x $buildFile
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
if test ! -d $tempFolder; then
|
|
||||||
rm -rf $tempFolder
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$buildFile -r $repoFolder "$@"
|
if ! __machine_has curl && ! __machine_has wget; then
|
||||||
|
__error 'Missing required command. Either wget or curl is required.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json"
|
||||||
|
if [ -f "$config_file" ]; then
|
||||||
|
if __machine_has jq ; then
|
||||||
|
if jq '.' "$config_file" >/dev/null ; then
|
||||||
|
config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")"
|
||||||
|
config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")"
|
||||||
|
else
|
||||||
|
__warn "$config_file is invalid JSON. Its settings will be ignored."
|
||||||
|
fi
|
||||||
|
elif __machine_has python ; then
|
||||||
|
if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
|
||||||
|
config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
|
||||||
|
config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
|
||||||
|
else
|
||||||
|
__warn "$config_file is invalid JSON. Its settings will be ignored."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
__warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.'
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ ! -z "${config_channel:-}" ] && channel="$config_channel"
|
||||||
|
[ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$channel" ] && channel='dev'
|
||||||
|
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
|
||||||
|
|
||||||
|
get_korebuild
|
||||||
|
install_tools "$tools_source" "$DOTNET_HOME"
|
||||||
|
invoke_repository_build "$repo_path" "$@"
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
<Project>
|
<Project>
|
||||||
|
<Import Project="..\version.props" />
|
||||||
<Import Project="dependencies.props" />
|
|
||||||
<Import Project="version.props" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Product>Microsoft ASP.NET Core</Product>
|
<Product>Microsoft ASP.NET Core</Product>
|
||||||
@@ -11,10 +9,10 @@
|
|||||||
<SignAssembly>true</SignAssembly>
|
<SignAssembly>true</SignAssembly>
|
||||||
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
|
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<VersionSuffix Condition="'$(VersionSuffix)'!='' AND '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Internal.AspNetCore.Sdk" Version="$(InternalAspNetCoreSdkVersion)" PrivateAssets="All" />
|
<PackageReference Include="Internal.AspNetCore.Sdk" Version="$(InternalAspNetCoreSdkPackageVersion)" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AspNetCoreVersion>1.1.0</AspNetCoreVersion>
|
<InternalAspNetCoreSdkPackageVersion>2.0.2-rc1-15526</InternalAspNetCoreSdkPackageVersion>
|
||||||
<AspNetCoreMvcVersion>1.1.1</AspNetCoreMvcVersion>
|
<MicrosoftAspNetCoreDiagnosticsPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreDiagnosticsPackageVersion>
|
||||||
<AspNetCoreToolsVersion>1.0.0-msbuild3-final</AspNetCoreToolsVersion>
|
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||||
<AutoMapperVersion>5.0.2</AutoMapperVersion>
|
<MicrosoftAspNetCoreHostingPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreHostingPackageVersion>
|
||||||
<CoreFxVersion>4.3.0</CoreFxVersion>
|
<MicrosoftAspNetCoreMvcPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreMvcPackageVersion>
|
||||||
<JsonNetVersion>10.0.1</JsonNetVersion>
|
<MicrosoftAspNetCoreMvcTagHelpersPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreMvcTagHelpersPackageVersion>
|
||||||
<InternalAspNetCoreSdkVersion>2.0.0-*</InternalAspNetCoreSdkVersion>
|
<MicrosoftAspNetCoreMvcViewFeaturesPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreMvcViewFeaturesPackageVersion>
|
||||||
<MicrosoftDataflowVersion>4.5.24</MicrosoftDataflowVersion>
|
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
||||||
<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>
|
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
||||||
<ThreadingDataflowVersion>4.7.0</ThreadingDataflowVersion>
|
<MicrosoftAspNetCoreStaticFilesPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreStaticFilesPackageVersion>
|
||||||
|
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.0.0</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||||
|
<MicrosoftExtensionsLoggingConsolePackageVersion>2.0.0</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||||
|
<MicrosoftExtensionsLoggingDebugPackageVersion>2.0.0</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||||
|
<NewtonsoftJsonRuntimePackageVersion>10.0.1</NewtonsoftJsonRuntimePackageVersion>
|
||||||
|
<SystemThreadingTasksDataflowPackageVersion>4.8.0</SystemThreadingTasksDataflowPackageVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
<Project>
|
|
||||||
<Target Name="NpmRestore" AfterTargets="Restore" Condition="'$(PreflightRestore)' != 'true'">
|
|
||||||
<ItemGroup>
|
|
||||||
<NpmModules Include="$(RepositoryRoot)**\package.json"
|
|
||||||
Exclude="$(RepositoryRoot)**\node_modules\**\*" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Message Text="Restoring NPM modules for: %0A - @(NpmModules -> '%(FullPath)','%0A - ')" Importance="high" />
|
|
||||||
|
|
||||||
<Exec Command="npm install" WorkingDirectory="%(NpmModules.RootDir)%(Directory)" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
17
build/sources.props
Normal file
17
build/sources.props
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<Project>
|
||||||
|
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<RestoreSources>$(DotNetRestoreSources)</RestoreSources>
|
||||||
|
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true' AND '$(AspNetUniverseBuildOffline)' != 'true' ">
|
||||||
|
$(RestoreSources);
|
||||||
|
https://dotnet.myget.org/F/aspnet-2-0-2-october2017-patch/api/v3/index.json;
|
||||||
|
https://dotnet.myget.org/F/aspnetcore-master/api/v3/index.json;
|
||||||
|
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
||||||
|
</RestoreSources>
|
||||||
|
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
|
||||||
|
$(RestoreSources);
|
||||||
|
https://api.nuget.org/v3/index.json;
|
||||||
|
</RestoreSources>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<Project>
|
|
||||||
<PropertyGroup>
|
|
||||||
<VersionPrefix>1.1.2</VersionPrefix>
|
|
||||||
<VersionSuffix>preview1</VersionSuffix>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
2
korebuild-lock.txt
Normal file
2
korebuild-lock.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
version:2.0.2-rc1-15526
|
||||||
|
commithash:436afc3dc08f5e278431db807866cc5f032f4d7b
|
||||||
4
korebuild.json
Normal file
4
korebuild.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/rel/2.0.2/tools/korebuild.schema.json",
|
||||||
|
"channel": "rel/2.0.2"
|
||||||
|
}
|
||||||
9
samples/angular/MusicStore/.gitignore
vendored
9
samples/angular/MusicStore/.gitignore
vendored
@@ -1,9 +0,0 @@
|
|||||||
/node_modules/
|
|
||||||
/wwwroot/lib/
|
|
||||||
/wwwroot/ng-app/**/*.js
|
|
||||||
/music-db.sqlite
|
|
||||||
/Properties/launchSettings.json
|
|
||||||
|
|
||||||
# Obviously you don't really want your DB to go in wwwroot, but due to https://github.com/aspnet/Microsoft.Data.Sqlite/issues/188
|
|
||||||
# it currently does when run from IIS Express. Will resolve this once RC2 is out, which is supposed to eliminate the inconsistency.
|
|
||||||
/wwwroot/music-db.sqlite
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using AutoMapper;
|
|
||||||
using MusicStore.Models;
|
|
||||||
using MusicStore.Infrastructure;
|
|
||||||
|
|
||||||
namespace MusicStore.Apis
|
|
||||||
{
|
|
||||||
[Route("api/albums")]
|
|
||||||
public class AlbumsApiController : Controller
|
|
||||||
{
|
|
||||||
private readonly MusicStoreContext _storeContext;
|
|
||||||
|
|
||||||
public AlbumsApiController(MusicStoreContext storeContext)
|
|
||||||
{
|
|
||||||
_storeContext = storeContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[NoCache]
|
|
||||||
public async Task<ActionResult> Paged(int page = 1, int pageSize = 50, string sortBy = null)
|
|
||||||
{
|
|
||||||
await _storeContext.Genres.LoadAsync();
|
|
||||||
await _storeContext.Artists.LoadAsync();
|
|
||||||
|
|
||||||
var albums = await _storeContext.Albums
|
|
||||||
.Include(a => a.Genre)
|
|
||||||
.Include(a => a.Artist)
|
|
||||||
.ToPagedListAsync(page, pageSize, sortBy,
|
|
||||||
a => a.Title, // sortExpression
|
|
||||||
SortDirection.Ascending, // defaultSortDirection
|
|
||||||
a => Mapper.Map(a, new AlbumResultDto())); // selector
|
|
||||||
|
|
||||||
return Json(albums);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("all")]
|
|
||||||
[NoCache]
|
|
||||||
public async Task<ActionResult> All()
|
|
||||||
{
|
|
||||||
var albums = await _storeContext.Albums
|
|
||||||
.Include(a => a.Genre)
|
|
||||||
.Include(a => a.Artist)
|
|
||||||
.OrderBy(a => a.Title)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return Json(albums.Select(a => Mapper.Map(a, new AlbumResultDto())));
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("mostPopular")]
|
|
||||||
[NoCache]
|
|
||||||
public async Task<ActionResult> MostPopular(int count = 6)
|
|
||||||
{
|
|
||||||
count = count > 0 && count < 20 ? count : 6;
|
|
||||||
var albums = await _storeContext.Albums
|
|
||||||
.OrderByDescending(a => a.OrderDetails.Count())
|
|
||||||
.Take(count)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
// TODO: Move the .Select() to end of albums query when EF supports it
|
|
||||||
return Json(albums.Select(a => Mapper.Map(a, new AlbumResultDto())));
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("{albumId:int}")]
|
|
||||||
[NoCache]
|
|
||||||
public async Task<ActionResult> Details(int albumId)
|
|
||||||
{
|
|
||||||
await _storeContext.Genres.LoadAsync();
|
|
||||||
await _storeContext.Artists.LoadAsync();
|
|
||||||
|
|
||||||
var album = await _storeContext.Albums
|
|
||||||
.Include(a => a.Artist)
|
|
||||||
.Include(a => a.Genre)
|
|
||||||
.Where(a => a.AlbumId == albumId)
|
|
||||||
.SingleOrDefaultAsync();
|
|
||||||
|
|
||||||
var albumResult = Mapper.Map(album, new AlbumResultDto());
|
|
||||||
|
|
||||||
// TODO: Add null checking and return 404 in that case
|
|
||||||
|
|
||||||
return Json(albumResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[Authorize("app-ManageStore")]
|
|
||||||
public async Task<ActionResult> CreateAlbum([FromBody]AlbumChangeDto album)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
// Return the model errors
|
|
||||||
return BadRequest(ModelState);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the changes to the DB
|
|
||||||
var dbAlbum = new Album();
|
|
||||||
_storeContext.Albums.Add(Mapper.Map(album, dbAlbum));
|
|
||||||
await _storeContext.SaveChangesAsync();
|
|
||||||
|
|
||||||
// TODO: Handle missing record, key violations, concurrency issues, etc.
|
|
||||||
|
|
||||||
return new ObjectResult(new {
|
|
||||||
Data = dbAlbum.AlbumId,
|
|
||||||
Message = "Album created successfully."
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPut("{albumId:int}/update")]
|
|
||||||
public async Task<ActionResult> UpdateAlbum(int albumId, [FromBody] AlbumChangeDto album)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
// Return the model errors
|
|
||||||
return BadRequest(ModelState);
|
|
||||||
}
|
|
||||||
|
|
||||||
var dbAlbum = await _storeContext.Albums.SingleOrDefaultAsync(a => a.AlbumId == albumId);
|
|
||||||
|
|
||||||
if (dbAlbum == null)
|
|
||||||
{
|
|
||||||
return new ObjectResult(new {
|
|
||||||
Message = string.Format("The album with ID {0} was not found.", albumId)
|
|
||||||
}) { StatusCode = 404 };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the changes to the DB
|
|
||||||
Mapper.Map(album, dbAlbum);
|
|
||||||
await _storeContext.SaveChangesAsync();
|
|
||||||
|
|
||||||
// TODO: Handle missing record, key violations, concurrency issues, etc.
|
|
||||||
|
|
||||||
return new ObjectResult (new {
|
|
||||||
Message = "Album updated successfully."
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpDelete("{albumId:int}")]
|
|
||||||
[Authorize("app-ManageStore")]
|
|
||||||
public async Task<ActionResult> DeleteAlbum(int albumId)
|
|
||||||
{
|
|
||||||
var album = await _storeContext.Albums.SingleOrDefaultAsync(a => a.AlbumId == albumId);
|
|
||||||
|
|
||||||
if (album != null)
|
|
||||||
{
|
|
||||||
_storeContext.Albums.Remove(album);
|
|
||||||
|
|
||||||
// Save the changes to the DB
|
|
||||||
await _storeContext.SaveChangesAsync();
|
|
||||||
|
|
||||||
// TODO: Handle missing record, key violations, concurrency issues, etc.
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ObjectResult (new {
|
|
||||||
Message = "Album deleted successfully."
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ModelMetadataType(typeof(Album))]
|
|
||||||
public class AlbumChangeDto : IValidatableObject
|
|
||||||
{
|
|
||||||
public int GenreId { get; set; }
|
|
||||||
|
|
||||||
public int ArtistId { get; set; }
|
|
||||||
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
public decimal Price { get; set; }
|
|
||||||
|
|
||||||
public string AlbumArtUrl { get; set; }
|
|
||||||
|
|
||||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
|
||||||
{
|
|
||||||
// An example of object-level (i.e., multi-property) validation
|
|
||||||
if (this.GenreId == 13 /* Indie */) {
|
|
||||||
switch (SentimentAnalysis.GetSentiment(Title)) {
|
|
||||||
case SentimentAnalysis.SentimentResult.Positive:
|
|
||||||
yield return new ValidationResult("Sounds too positive. Indie music requires more ambiguity.");
|
|
||||||
break;
|
|
||||||
case SentimentAnalysis.SentimentResult.Negative:
|
|
||||||
yield return new ValidationResult("Sounds too negative. Indie music requires more ambiguity.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AlbumResultDto : AlbumChangeDto
|
|
||||||
{
|
|
||||||
public AlbumResultDto()
|
|
||||||
{
|
|
||||||
Artist = new ArtistResultDto();
|
|
||||||
Genre = new GenreResultDto();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int AlbumId { get; set; }
|
|
||||||
|
|
||||||
public ArtistResultDto Artist { get; private set; }
|
|
||||||
|
|
||||||
public GenreResultDto Genre { get; private set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ArtistResultDto
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GenreResultDto
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using MusicStore.Models;
|
|
||||||
|
|
||||||
namespace MusicStore.Apis
|
|
||||||
{
|
|
||||||
[Route("api/artists")]
|
|
||||||
public class ArtistsApiController : Controller
|
|
||||||
{
|
|
||||||
private readonly MusicStoreContext _storeContext;
|
|
||||||
|
|
||||||
public ArtistsApiController(MusicStoreContext storeContext)
|
|
||||||
{
|
|
||||||
_storeContext = storeContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("lookup")]
|
|
||||||
public async Task<ActionResult> Lookup()
|
|
||||||
{
|
|
||||||
var artists = await _storeContext.Artists
|
|
||||||
.OrderBy(a => a.Name)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return Json(artists);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using MusicStore.Models;
|
|
||||||
using MusicStore.Infrastructure;
|
|
||||||
|
|
||||||
namespace MusicStore.Apis
|
|
||||||
{
|
|
||||||
[Route("api/genres")]
|
|
||||||
public class GenresApiController : Controller
|
|
||||||
{
|
|
||||||
private readonly MusicStoreContext _storeContext;
|
|
||||||
|
|
||||||
public GenresApiController(MusicStoreContext storeContext)
|
|
||||||
{
|
|
||||||
_storeContext = storeContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public async Task<ActionResult> GenreList()
|
|
||||||
{
|
|
||||||
var genres = await _storeContext.Genres
|
|
||||||
//.Include(g => g.Albums)
|
|
||||||
.OrderBy(g => g.Name)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return Json(genres);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("genre-lookup")]
|
|
||||||
public async Task<ActionResult> Lookup()
|
|
||||||
{
|
|
||||||
var genres = await _storeContext.Genres
|
|
||||||
.Select(g => new { g.GenreId, g.Name })
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return Json(genres);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("menu")]
|
|
||||||
public async Task<ActionResult> GenreMenuList(int count = 9)
|
|
||||||
{
|
|
||||||
count = count > 0 && count < 20 ? count : 9;
|
|
||||||
|
|
||||||
var genres = await _storeContext.Genres
|
|
||||||
.OrderByDescending(g =>
|
|
||||||
g.Albums.Sum(a =>
|
|
||||||
a.OrderDetails.Sum(od => od.Quantity)))
|
|
||||||
.Take(count)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return Json(genres);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("{genreId:int}/albums")]
|
|
||||||
[NoCache]
|
|
||||||
public async Task<ActionResult> GenreAlbums(int genreId)
|
|
||||||
{
|
|
||||||
var albums = await _storeContext.Albums
|
|
||||||
.Where(a => a.GenreId == genreId)
|
|
||||||
//.Include(a => a.Genre)
|
|
||||||
//.Include(a => a.Artist)
|
|
||||||
//.OrderBy(a => a.Genre.Name)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
return Json(albums);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public class ExternalLoginConfirmationViewModel
|
|
||||||
{
|
|
||||||
[Required]
|
|
||||||
[Display(Name = "User name")]
|
|
||||||
public string UserName { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManageUserViewModel
|
|
||||||
{
|
|
||||||
[Required]
|
|
||||||
[DataType(DataType.Password)]
|
|
||||||
[Display(Name = "Current password")]
|
|
||||||
public string OldPassword { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
|
|
||||||
[DataType(DataType.Password)]
|
|
||||||
[Display(Name = "New password")]
|
|
||||||
public string NewPassword { get; set; }
|
|
||||||
|
|
||||||
[DataType(DataType.Password)]
|
|
||||||
[Display(Name = "Confirm new password")]
|
|
||||||
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
|
|
||||||
public string ConfirmPassword { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LoginViewModel
|
|
||||||
{
|
|
||||||
[Required]
|
|
||||||
[Display(Name = "User name")]
|
|
||||||
public string UserName { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[DataType(DataType.Password)]
|
|
||||||
[Display(Name = "Password")]
|
|
||||||
public string Password { get; set; }
|
|
||||||
|
|
||||||
[Display(Name = "Remember me?")]
|
|
||||||
public bool RememberMe { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RegisterViewModel
|
|
||||||
{
|
|
||||||
[Required]
|
|
||||||
[Display(Name = "User name")]
|
|
||||||
public string UserName { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
|
|
||||||
[DataType(DataType.Password)]
|
|
||||||
[Display(Name = "Password")]
|
|
||||||
public string Password { get; set; }
|
|
||||||
|
|
||||||
[DataType(DataType.Password)]
|
|
||||||
[Display(Name = "Confirm password")]
|
|
||||||
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
|
|
||||||
public string ConfirmPassword { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public class Album
|
|
||||||
{
|
|
||||||
public Album()
|
|
||||||
{
|
|
||||||
// TODO: Temporary hack to populate the orderdetails until EF does this automatically.
|
|
||||||
OrderDetails = new List<OrderDetail>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ScaffoldColumn(false)]
|
|
||||||
public int AlbumId { get; set; }
|
|
||||||
|
|
||||||
public int GenreId { get; set; }
|
|
||||||
|
|
||||||
public int ArtistId { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[StringLength(160, MinimumLength = 2)]
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[RangeAttribute(typeof(decimal), "0.01", "100")] // Long-form constructor to work around https://github.com/dotnet/coreclr/issues/2172
|
|
||||||
[DataType(DataType.Currency)]
|
|
||||||
public decimal Price { get; set; }
|
|
||||||
|
|
||||||
[Display(Name = "Album Art URL")]
|
|
||||||
[StringLength(1024)]
|
|
||||||
public string AlbumArtUrl { get; set; }
|
|
||||||
|
|
||||||
public virtual Genre Genre { get; set; }
|
|
||||||
|
|
||||||
public virtual Artist Artist { get; set; }
|
|
||||||
|
|
||||||
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public class Artist
|
|
||||||
{
|
|
||||||
public int ArtistId { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public class CartItem
|
|
||||||
{
|
|
||||||
[Key]
|
|
||||||
public int CartItemId { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string CartId { get; set; }
|
|
||||||
public int AlbumId { get; set; }
|
|
||||||
public int Count { get; set; }
|
|
||||||
|
|
||||||
[DataType(DataType.DateTime)]
|
|
||||||
public DateTime DateCreated { get; set; }
|
|
||||||
|
|
||||||
public virtual Album Album { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public class Genre
|
|
||||||
{
|
|
||||||
public Genre()
|
|
||||||
{
|
|
||||||
Albums = new List<Album>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GenreId { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public string Description { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public virtual ICollection<Album> Albums { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public class ApplicationUser : IdentityUser { }
|
|
||||||
|
|
||||||
public class MusicStoreContext : IdentityDbContext<ApplicationUser>
|
|
||||||
{
|
|
||||||
public MusicStoreContext(DbContextOptions options) : base(options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbSet<Album> Albums { get; set; }
|
|
||||||
public DbSet<Artist> Artists { get; set; }
|
|
||||||
public DbSet<Order> Orders { get; set; }
|
|
||||||
public DbSet<Genre> Genres { get; set; }
|
|
||||||
public DbSet<CartItem> CartItems { get; set; }
|
|
||||||
public DbSet<OrderDetail> OrderDetails { get; set; }
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder builder)
|
|
||||||
{
|
|
||||||
// Configure pluralization
|
|
||||||
builder.Entity<Album>().ToTable("Albums");
|
|
||||||
builder.Entity<Artist>().ToTable("Artists");
|
|
||||||
builder.Entity<Order>().ToTable("Orders");
|
|
||||||
builder.Entity<Genre>().ToTable("Genres");
|
|
||||||
builder.Entity<CartItem>().ToTable("CartItems");
|
|
||||||
builder.Entity<OrderDetail>().ToTable("OrderDetails");
|
|
||||||
|
|
||||||
base.OnModelCreating(builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
//[Bind(Include = "FirstName,LastName,Address,City,State,PostalCode,Country,Phone,Email")]
|
|
||||||
public class Order
|
|
||||||
{
|
|
||||||
public Order()
|
|
||||||
{
|
|
||||||
OrderDetails = new List<OrderDetail>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ScaffoldColumn(false)]
|
|
||||||
public int OrderId { get; set; }
|
|
||||||
|
|
||||||
[ScaffoldColumn(false)]
|
|
||||||
public DateTime OrderDate { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[ScaffoldColumn(false)]
|
|
||||||
public string Username { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[Display(Name = "First Name")]
|
|
||||||
[StringLength(160)]
|
|
||||||
public string FirstName { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[Display(Name = "Last Name")]
|
|
||||||
[StringLength(160)]
|
|
||||||
public string LastName { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[StringLength(70, MinimumLength = 3)]
|
|
||||||
public string Address { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[StringLength(40)]
|
|
||||||
public string City { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[StringLength(40)]
|
|
||||||
public string State { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[Display(Name = "Postal Code")]
|
|
||||||
[StringLength(10, MinimumLength = 5)]
|
|
||||||
public string PostalCode { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[StringLength(40)]
|
|
||||||
public string Country { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[StringLength(24)]
|
|
||||||
[DataType(DataType.PhoneNumber)]
|
|
||||||
public string Phone { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[Display(Name = "Email Address")]
|
|
||||||
[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",
|
|
||||||
ErrorMessage = "Email is not valid.")]
|
|
||||||
[DataType(DataType.EmailAddress)]
|
|
||||||
public string Email { get; set; }
|
|
||||||
|
|
||||||
[ScaffoldColumn(false)]
|
|
||||||
public decimal Total { get; set; }
|
|
||||||
|
|
||||||
public ICollection<OrderDetail> OrderDetails { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public class OrderDetail
|
|
||||||
{
|
|
||||||
public int OrderDetailId { get; set; }
|
|
||||||
public int OrderId { get; set; }
|
|
||||||
public int AlbumId { get; set; }
|
|
||||||
public int Quantity { get; set; }
|
|
||||||
public decimal UnitPrice { get; set; }
|
|
||||||
|
|
||||||
public virtual Album Album { get; set; }
|
|
||||||
public virtual Order Order { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,915 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public static class SampleData
|
|
||||||
{
|
|
||||||
const string imgUrl = "/images/placeholder.png";
|
|
||||||
|
|
||||||
public static async Task InitializeMusicStoreDatabaseAsync(IServiceProvider serviceProvider)
|
|
||||||
{
|
|
||||||
using (var db = serviceProvider.GetService<MusicStoreContext>())
|
|
||||||
{
|
|
||||||
if (await db.Database.EnsureCreatedAsync())
|
|
||||||
{
|
|
||||||
await InsertTestData(serviceProvider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task InsertTestData(IServiceProvider serviceProvider)
|
|
||||||
{
|
|
||||||
var albums = GetAlbums(imgUrl, Genres, Artists);
|
|
||||||
await AddOrUpdateAsync(serviceProvider, g => g.GenreId, Genres.Select(genre => genre.Value));
|
|
||||||
await AddOrUpdateAsync(serviceProvider, a => a.ArtistId, Artists.Select(artist => artist.Value));
|
|
||||||
await AddOrUpdateAsync(serviceProvider, a => a.AlbumId, albums);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO [EF] This may be replaced by a first class mechanism in EF
|
|
||||||
private static async Task AddOrUpdateAsync<TEntity>(
|
|
||||||
IServiceProvider serviceProvider,
|
|
||||||
Func<TEntity, object> propertyToMatch, IEnumerable<TEntity> entities)
|
|
||||||
where TEntity : class
|
|
||||||
{
|
|
||||||
// Query in a separate context so that we can attach existing entities as modified
|
|
||||||
List<TEntity> existingData;
|
|
||||||
|
|
||||||
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
|
|
||||||
using (var db = scope.ServiceProvider.GetService<MusicStoreContext>())
|
|
||||||
{
|
|
||||||
existingData = db.Set<TEntity>().ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
|
|
||||||
using (var db = scope.ServiceProvider.GetService<MusicStoreContext>())
|
|
||||||
{
|
|
||||||
foreach (var item in entities)
|
|
||||||
{
|
|
||||||
db.Entry(item).State = existingData.Any(g => propertyToMatch(g).Equals(propertyToMatch(item)))
|
|
||||||
? EntityState.Modified
|
|
||||||
: EntityState.Added;
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Album[] GetAlbums(string imgUrl, Dictionary<string, Genre> genres, Dictionary<string, Artist> artists)
|
|
||||||
{
|
|
||||||
var albums = new Album[]
|
|
||||||
{
|
|
||||||
new Album { Title = "The Best Of The Men At Work", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Men At Work"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "...And Justice For All", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "עד גבול האור", Genre = genres["World"], Price = 8.99M, Artist = artists["אריק אינשטיין"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Black Light Syndrome", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Terry Bozzio, Tony Levin & Steve Stevens"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "10,000 Days", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "11i", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Supreme Beings of Leisure"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "1960", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Soul-Junk"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "4x4=12 ", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["deadmau5"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A Copland Celebration, Vol. I", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Symphony Orchestra"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A Lively Mind", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Paul Oakenfold"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A Matter of Life and Death", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A Real Dead One", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A Real Live One", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A Rush of Blood to the Head", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Coldplay"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A Soprano Inspired", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Britten Sinfonia, Ivor Bolton & Lesley Garrett"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A Winter Symphony", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Abbey Road", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ace Of Spades", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Motörhead"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Achtung Baby", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Acústico MTV", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Adams, John: The Chairman Dances", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Edo de Waart & San Francisco Symphony"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Adrenaline", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deftones"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ænima", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Afrociberdelia", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Science & Nação Zumbi"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "After the Goldrush", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Neil Young"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Airdrawn Dagger", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Sasha"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Album Title Goes Here", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["deadmau5"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Alcohol Fueled Brewtality Live! [Disc 1]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Label Society"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Alcohol Fueled Brewtality Live! [Disc 2]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Label Society"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Alive 2007", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Daft Punk"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "All I Ask of You", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Amen (So Be It)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paddy Casey"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Animal Vehicle", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Axis of Awesome"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ao Vivo [IMPORT]", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Zeca Pagodinho"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Apocalyptic Love", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Slash"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Appetite for Destruction", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Are You Experienced?", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Jimi Hendrix"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Arquivo II", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Arquivo Os Paralamas Do Sucesso", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "A-Sides", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Soundgarden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Audioslave", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Audioslave"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Automatic for the People", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["R.E.M."], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Axé Bahia 2001", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Babel", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Mumford & Sons"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bach: Goldberg Variations", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Wilhelm Kempff"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bach: The Brandenburg Concertos", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Orchestra of The Age of Enlightenment"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bach: The Cello Suites", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Yo-Yo Ma"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bach: Toccata & Fugue in D Minor", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Ton Koopman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bad Motorfinger", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Soundgarden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Balls to the Wall", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Accept"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Banadeek Ta'ala", Genre = genres["World"], Price = 8.99M, Artist = artists["Amr Diab"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Barbie Girl", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Aqua"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bark at the Moon (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bartok: Violin & Viola Concertos", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Yehudi Menuhin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Barulhinho Bom", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Marisa Monte"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "BBC Sessions [Disc 1] [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "BBC Sessions [Disc 2] [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Be Here Now", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Oasis"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bedrock 11 Compiled & Mixed", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["John Digweed"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Berlioz: Symphonie Fantastique", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Michael Tilson Thomas"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Beyond Good And Evil", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Cult"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Big Bad Wolf ", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Armand Van Helden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Big Ones", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Aerosmith"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Black Album", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Black Sabbath Vol. 4 (Remaster)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Sabbath"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Black Sabbath", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Sabbath"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Black", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Blackwater Park", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Opeth"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Blizzard of Ozz", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Blood", Genre = genres["Rock"], Price = 8.99M, Artist = artists["In This Moment"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Blue Moods", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Incognito"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Blue", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Weezer"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bongo Fury", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Frank Zappa & Captain Beefheart"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Boys & Girls", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alabama Shakes"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Brave New World", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "B-Sides 1980-1990", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Bunkka", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Paul Oakenfold"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "By The Way", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Red Hot Chili Peppers"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Cake: B-Sides and Rarities", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Cake"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Californication", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Red Hot Chili Peppers"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Carmina Burana", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Boston Symphony Orchestra & Seiji Ozawa"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Carried to Dust (Bonus Track Version)", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Calexico"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Carry On", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Chris Cornell"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Cássia Eller - Sem Limite [Disc 1]", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cássia Eller"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Chemical Wedding", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Bruce Dickinson"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Chill: Brazil (Disc 1)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Marcos Valle"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Chill: Brazil (Disc 2)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Antônio Carlos Jobim"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Chocolate Starfish And The Hot Dog Flavored Water", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Limp Bizkit"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Chronicle, Vol. 1", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Creedence Clearwater Revival"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Chronicle, Vol. 2", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Creedence Clearwater Revival"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ciao, Baby", Genre = genres["Rock"], Price = 8.99M, Artist = artists["TheStart"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Cidade Negra - Hits", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cidade Negra"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Classic Munkle: Turbo Edition", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Munkle"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Classics: The Best of Sarah Brightman", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Coda", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Come Away With Me", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Norah Jones"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Come Taste The Band", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Comfort Eagle", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Cake"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Common Reaction", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Uh Huh Her "], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Compositores", Genre = genres["Rock"], Price = 8.99M, Artist = artists["O Terço"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Contraband", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Velvet Revolver"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Core", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Stone Temple Pilots"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Cornerstone", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Styx"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Cosmicolor", Genre = genres["Rap"], Price = 8.99M, Artist = artists["M-Flo"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Cross", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Justice"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Culture of Fear", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Thievery Corporation"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Da Lama Ao Caos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Science & Nação Zumbi"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Dakshina", Genre = genres["World"], Price = 8.99M, Artist = artists["Deva Premal"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Dark Side of the Moon", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Death Magnetic", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Deep End of Down", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Above the Fold"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Deep Purple In Rock", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Deixa Entrar", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Falamansa"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Deja Vu", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Crosby, Stills, Nash, and Young"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Di Korpu Ku Alma", Genre = genres["World"], Price = 8.99M, Artist = artists["Lura"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Diary of a Madman (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Diary of a Madman", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Dirt", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alice in Chains"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Diver Down", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Djavan Ao Vivo - Vol. 02", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Djavan"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Djavan Ao Vivo - Vol. 1", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Djavan"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Drum'n'bass for Papa", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Plug"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Duluth", Genre = genres["Country"], Price = 8.99M, Artist = artists["Trampled By Turtles"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Dummy", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Portishead"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Duos II", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Luciana Souza/Romero Lubambo"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Earl Scruggs and Friends", Genre = genres["Country"], Price = 8.99M, Artist = artists["Earl Scruggs"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Eden", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "El Camino", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Black Keys"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Elegant Gypsy", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Al di Meola"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Elements Of Life", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Tiësto"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Elis Regina-Minha História", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Elis Regina"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Emergency On Planet Earth", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Jamiroquai"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Emotion", Genre = genres["World"], Price = 8.99M, Artist = artists["Papa Wemba"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "English Renaissance", Genre = genres["Classical"], Price = 8.99M, Artist = artists["The King's Singers"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Every Kind of Light", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Posies"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Faceless", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Godsmack"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Facelift", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alice in Chains"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Fair Warning", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Fear of a Black Planet", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Public Enemy"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Fear Of The Dark", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Feels Like Home", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Norah Jones"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Fireball", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Fly", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "For Those About To Rock We Salute You", Genre = genres["Rock"], Price = 8.99M, Artist = artists["AC/DC"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Four", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Blues Traveler"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Frank", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Amy Winehouse"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Further Down the Spiral", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Nine Inch Nails"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Garage Inc. (Disc 1)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Garage Inc. (Disc 2)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Garbage", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Garbage"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Good News For People Who Love Bad News", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Modest Mouse"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Gordon", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Barenaked Ladies"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Górecki: Symphony No. 3", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Adrian Leaper & Doreen de Feis"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Greatest Hits I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Greatest Hits II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Greatest Hits", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Duck Sauce"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Greatest Hits", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Lenny Kravitz"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Greatest Hits", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Lenny Kravitz"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Greatest Kiss", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Kiss"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Greetings from Michigan", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Sufjan Stevens"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Group Therapy", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Above & Beyond"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Handel: The Messiah (Highlights)", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Scholars Baroque Ensemble"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Haydn: Symphonies 99 - 104", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Royal Philharmonic Orchestra"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Heart of the Night", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Spyro Gyra"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Heart On", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Eagles of Death Metal"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Holy Diver", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Dio"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Homework", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Daft Punk"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Hot Rocks, 1964-1971 (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Houses Of The Holy", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "How To Dismantle An Atomic Bomb", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Human", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Projected"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Hunky Dory", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Bowie"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Hymns", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Projected"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Hysteria", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Def Leppard"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "In Absentia", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Porcupine Tree"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "In Between", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Paul Van Dyk"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "In Rainbows", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Radiohead"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "In Step", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Stevie Ray Vaughan & Double Trouble"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "In the court of the Crimson King", Genre = genres["Rock"], Price = 8.99M, Artist = artists["King Crimson"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "In Through The Out Door", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "In Your Honor [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "In Your Honor [Disc 2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Indestructible", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rancid"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Infinity", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Journey"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Into The Light", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Coverdale"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Introspective", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Pet Shop Boys"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Iron Maiden", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "ISAM", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Amon Tobin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "IV", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Jagged Little Pill", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Alanis Morissette"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Jagged Little Pill", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alanis Morissette"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Jorge Ben Jor 25 Anos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Jorge Ben"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Jota Quest-1995", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Jota Quest"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Kick", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["INXS"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Kill 'Em All", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Kind of Blue", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "King For A Day Fool For A Lifetime", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Faith No More"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Kiss", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Carly Rae Jepsen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Last Call", Genre = genres["Country"], Price = 8.99M, Artist = artists["Cayouche"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Le Freak", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Chic"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Le Tigre", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Le Tigre"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Led Zeppelin I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Led Zeppelin II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Led Zeppelin III", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Let There Be Rock", Genre = genres["Rock"], Price = 8.99M, Artist = artists["AC/DC"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Little Earthquakes", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Tori Amos"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Live [Disc 1]", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Live [Disc 2]", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Live After Death", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Live At Donington 1992 (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Live At Donington 1992 (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Live on Earth", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["The Cat Empire"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Live On Two Legs [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Living After Midnight", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Judas Priest"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Living", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paddy Casey"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Load", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Love Changes Everything", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "MacArthur Park Suite", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Donna Summer"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Machine Head", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Magical Mystery Tour", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Mais Do Mesmo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Legião Urbana"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Maquinarama", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Skank"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Marasim", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Jagjit Singh"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Mascagni: Cavalleria Rusticana", Genre = genres["Classical"], Price = 8.99M, Artist = artists["James Levine"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Master of Puppets", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Mechanics & Mathematics", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Venus Hum"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Mental Jewelry", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Live"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Metallics", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "meteora", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Linkin Park"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Meus Momentos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Gonzaguinha"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Mezmerize", Genre = genres["Metal"], Price = 8.99M, Artist = artists["System Of A Down"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Mezzanine", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Massive Attack"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Miles Ahead", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Milton Nascimento Ao Vivo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Milton Nascimento"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Minas", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Milton Nascimento"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Minha Historia", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Buarque"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Misplaced Childhood", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Marillion"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "MK III The Final Concerts [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Morning Dance", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Spyro Gyra"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Motley Crue Greatest Hits", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Mötley Crüe"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Moving Pictures", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rush"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Mozart: Chamber Music", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Nash Ensemble"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Mozart: Symphonies Nos. 40 & 41", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Berliner Philharmoniker"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Murder Ballads", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Nick Cave and the Bad Seeds"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Music For The Jilted Generation", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["The Prodigy"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "My Generation - The Very Best Of The Who", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Who"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "My Name is Skrillex", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Skrillex"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Na Pista", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cláudio Zoli"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Nevermind", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Nirvana"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "New Adventures In Hi-Fi", Genre = genres["Rock"], Price = 8.99M, Artist = artists["R.E.M."], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "New Divide", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Linkin Park"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "New York Dolls", Genre = genres["Punk"], Price = 8.99M, Artist = artists["New York Dolls"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "News Of The World", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Nielsen: The Six Symphonies", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Göteborgs Symfoniker & Neeme Järvi"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Night At The Opera", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Night Castle", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Trans-Siberian Orchestra"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Nkolo", Genre = genres["World"], Price = 8.99M, Artist = artists["Lokua Kanza"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "No More Tears (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "No Prayer For The Dying", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "No Security", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "O Brother, Where Art Thou?", Genre = genres["Country"], Price = 8.99M, Artist = artists["Alison Krauss"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "O Samba Poconé", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Skank"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "O(+>", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Prince"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Oceania", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Smashing Pumpkins"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Off the Deep End", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Weird Al"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "OK Computer", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Radiohead"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Olodum", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Olodum"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "One Love", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["David Guetta"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Operation: Mindcrime", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Queensrÿche"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Opiate", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Outbreak", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Dennis Chambers"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Pachelbel: Canon & Gigue", Genre = genres["Classical"], Price = 8.99M, Artist = artists["English Concert & Trevor Pinnock"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Paid in Full", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Eric B. and Rakim"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Para Siempre", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Vicente Fernandez"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Pause", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Four Tet"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Peace Sells... but Who's Buying", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Megadeth"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Physical Graffiti [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Physical Graffiti [Disc 2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Physical Graffiti", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Piece Of Mind", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Pinkerton", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Weezer"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Plays Metallica By Four Cellos", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Apocalyptica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Pop", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Powerslave", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Prenda Minha", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Caetano Veloso"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Presence", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Pretty Hate Machine", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Nine Inch Nails"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Prisoner", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Jezabels"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Privateering", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Mark Knopfler"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Prokofiev: Romeo & Juliet", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Michael Tilson Thomas"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Prokofiev: Symphony No.1", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sergei Prokofiev & Yuri Temirkanov"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "PSY's Best 6th Part 1", Genre = genres["Pop"], Price = 8.99M, Artist = artists["PSY"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Purcell: The Fairy Queen", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Classical Players"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Purpendicular", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Purple", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Stone Temple Pilots"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Quanta Gente Veio Ver (Live)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Gilberto Gil"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Quanta Gente Veio ver--Bônus De Carnaval", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Gilberto Gil"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Quiet Songs", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Aisha Duo"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Raices", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Los Tigres del Norte"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Raising Hell", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Run DMC"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Raoul and the Kings of Spain ", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tears For Fears"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Rattle And Hum", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Raul Seixas", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Raul Seixas"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Recovery [Explicit]", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Eminem"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Reign In Blood", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Slayer"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Relayed", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Yes"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "ReLoad", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Respighi:Pines of Rome", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Eugene Ormandy"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Restless and Wild", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Accept"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Retrospective I (1974-1980)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rush"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Revelations", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Audioslave"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Revolver", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ride the Lighting ", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ride The Lightning", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ring My Bell", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Anita Ward"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Riot Act", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Rise of the Phoenix", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Before the Dawn"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Rock In Rio [CD1]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Rock In Rio [CD2]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Rock In Rio [CD2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Roda De Funk", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Funk Como Le Gusta"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Room for Squares", Genre = genres["Pop"], Price = 8.99M, Artist = artists["John Mayer"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Root Down", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Jimmy Smith"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Rounds", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Four Tet"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Rubber Factory", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Black Keys"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Rust in Peace", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Megadeth"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Sambas De Enredo 2001", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Santana - As Years Go By", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Santana Live", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Saturday Night Fever", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Bee Gees"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Scary Monsters and Nice Sprites", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Skrillex"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Scheherazade", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Chicago Symphony Orchestra & Fritz Reiner"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "SCRIABIN: Vers la flamme", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Christopher O'Riley"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Second Coming", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Stone Roses"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Serie Sem Limite (Disc 1)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Tim Maia"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Serie Sem Limite (Disc 2)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Tim Maia"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Serious About Men", Genre = genres["Rap"], Price = 8.99M, Artist = artists["The Rubberbandits"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Seventh Son of a Seventh Son", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Short Bus", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Filter"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Sibelius: Finlandia", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Berliner Philharmoniker"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Singles Collection", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Bowie"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Six Degrees of Inner Turbulence", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Dream Theater"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Slave To The Empire", Genre = genres["Metal"], Price = 8.99M, Artist = artists["T&N"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Slaves And Masters", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Slouching Towards Bethlehem", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Robert James"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Smash", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Offspring"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Something Special", Genre = genres["Country"], Price = 8.99M, Artist = artists["Dolly Parton"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Somewhere in Time", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Song(s) You Know By Heart", Genre = genres["Country"], Price = 8.99M, Artist = artists["Jimmy Buffett"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Sound of Music", Genre = genres["Punk"], Price = 8.99M, Artist = artists["Adicts"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "South American Getaway", Genre = genres["Classical"], Price = 8.99M, Artist = artists["The 12 Cellists of The Berlin Philharmonic"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Sozinho Remix Ao Vivo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Caetano Veloso"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Speak of the Devil", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Spiritual State", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Nujabes"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "St. Anger", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Still Life", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Opeth"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Stop Making Sense", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Talking Heads"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Stormbringer", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Stranger than Fiction", Genre = genres["Punk"], Price = 8.99M, Artist = artists["Bad Religion"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Strauss: Waltzes", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Eugene Ormandy"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Supermodified", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Amon Tobin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Supernatural", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Surfing with the Alien (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Joe Satriani"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Switched-On Bach", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Wendy Carlos"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Symphony", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Szymanowski: Piano Works, Vol. 1", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Martin Roscoe"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Tchaikovsky: The Nutcracker", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Symphony Orchestra"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ted Nugent", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ted Nugent"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Teflon Don", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Rick Ross"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Tell Another Joke at the Ol' Choppin' Block", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Danielson Famile"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Temple of the Dog", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Temple of the Dog"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Ten", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Texas Flood", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Stevie Ray Vaughan"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Battle Rages On", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Beast Live", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paul D'Ianno"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Best Of 1980-1990", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Best of 1990–2000", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Best of Beethoven", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Nicolaus Esterhazy Sinfonia"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Best Of Billy Cobham", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Billy Cobham"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Best of Ed Motta", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Ed Motta"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Best Of Van Halen, Vol. I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Bridge", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Melanie Fiona"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Cage", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tygers of Pan Tang"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Chicago Transit Authority", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Chicago "], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Chronic", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Dr. Dre"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Colour And The Shape", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Crane Wife", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["The Decemberists"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Cream Of Clapton", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Cure", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Cure"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Dark Side Of The Moon", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Divine Conspiracy", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Epica"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Doors", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Doors"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Dream of the Blue Turtles", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Sting"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Essential Miles Davis [Disc 1]", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Essential Miles Davis [Disc 2]", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Final Concerts (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Final Frontier", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Head and the Heart", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Head and the Heart"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Joshua Tree", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Last Night of the Proms", Genre = genres["Classical"], Price = 8.99M, Artist = artists["BBC Concert Orchestra"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Lumineers", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Lumineers"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Number of The Beast", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Number of The Beast", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Police Greatest Hits", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Police"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Song Remains The Same (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Song Remains The Same (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Southern Harmony and Musical Companion", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Spade", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Butch Walker & The Black Widows"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Stone Roses", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Stone Roses"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Suburbs", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Arcade Fire"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Three Tenors Disc1/Disc2", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Carreras, Pavarotti, Domingo"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Trees They Grow So High", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The Wall", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "The X Factor", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Them Crooked Vultures", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Them Crooked Vultures"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "This Is Happening", Genre = genres["Rock"], Price = 8.99M, Artist = artists["LCD Soundsystem"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Thunder, Lightning, Strike", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Go! Team"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Time to Say Goodbye", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Time, Love & Tenderness", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Michael Bolton"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Tomorrow Starts Today", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Mobile"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Tribute", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Tuesday Night Music Club", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Sheryl Crow"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Umoja", Genre = genres["Rock"], Price = 8.99M, Artist = artists["BLØF"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Under the Pink", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Tori Amos"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Undertow", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Un-Led-Ed", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Dread Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Unplugged [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Kiss"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Unplugged", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Unplugged", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Untrue", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Burial"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Use Your Illusion I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Use Your Illusion II", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Use Your Illusion II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Van Halen III", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Van Halen", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Version 2.0", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Garbage"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Vinicius De Moraes", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Vinícius De Moraes"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Virtual XI", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Voodoo Lounge", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Vozes do MPB", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Vs.", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Wagner: Favourite Overtures", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sir Georg Solti & Wiener Philharmoniker"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Walking Into Clarksdale", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Page & Plant"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Wapi Yo", Genre = genres["World"], Price = 8.99M, Artist = artists["Lokua Kanza"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "War", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Warner 25 Anos", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Antônio Carlos Jobim"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Wasteland R&Btheque", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Raunchy"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Watermark", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Enya"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "We Were Exploding Anyway", Genre = genres["Rock"], Price = 8.99M, Artist = artists["65daysofstatic"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Weill: The Seven Deadly Sins", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Orchestre de l'Opéra de Lyon"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "White Pony", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deftones"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Who's Next", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Who"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Wish You Were Here", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "With Oden on Our Side", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Amon Amarth"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Worlds", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Aaron Goldberg"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Worship Music", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Anthrax"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "X&Y", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Coldplay"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Xinti", Genre = genres["World"], Price = 8.99M, Artist = artists["Sara Tavares"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Yano", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Yano"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Yesterday Once More Disc 1/Disc 2", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Carpenters"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Zooropa", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
|
||||||
new Album { Title = "Zoso", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var album in albums)
|
|
||||||
{
|
|
||||||
album.ArtistId = album.Artist.ArtistId;
|
|
||||||
album.GenreId = album.Genre.GenreId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return albums;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Dictionary<string, Artist> artists;
|
|
||||||
public static Dictionary<string, Artist> Artists
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (artists == null)
|
|
||||||
{
|
|
||||||
var artistsList = new Artist[]
|
|
||||||
{
|
|
||||||
new Artist { Name = "65daysofstatic" },
|
|
||||||
new Artist { Name = "Aaron Goldberg" },
|
|
||||||
new Artist { Name = "Above & Beyond" },
|
|
||||||
new Artist { Name = "Above the Fold" },
|
|
||||||
new Artist { Name = "AC/DC" },
|
|
||||||
new Artist { Name = "Accept" },
|
|
||||||
new Artist { Name = "Adicts" },
|
|
||||||
new Artist { Name = "Adrian Leaper & Doreen de Feis" },
|
|
||||||
new Artist { Name = "Aerosmith" },
|
|
||||||
new Artist { Name = "Aisha Duo" },
|
|
||||||
new Artist { Name = "Al di Meola" },
|
|
||||||
new Artist { Name = "Alabama Shakes" },
|
|
||||||
new Artist { Name = "Alanis Morissette" },
|
|
||||||
new Artist { Name = "Alberto Turco & Nova Schola Gregoriana" },
|
|
||||||
new Artist { Name = "Alice in Chains" },
|
|
||||||
new Artist { Name = "Alison Krauss" },
|
|
||||||
new Artist { Name = "Amon Amarth" },
|
|
||||||
new Artist { Name = "Amon Tobin" },
|
|
||||||
new Artist { Name = "Amr Diab" },
|
|
||||||
new Artist { Name = "Amy Winehouse" },
|
|
||||||
new Artist { Name = "Anita Ward" },
|
|
||||||
new Artist { Name = "Anthrax" },
|
|
||||||
new Artist { Name = "Antônio Carlos Jobim" },
|
|
||||||
new Artist { Name = "Apocalyptica" },
|
|
||||||
new Artist { Name = "Aqua" },
|
|
||||||
new Artist { Name = "Armand Van Helden" },
|
|
||||||
new Artist { Name = "Arcade Fire" },
|
|
||||||
new Artist { Name = "Audioslave" },
|
|
||||||
new Artist { Name = "Bad Religion" },
|
|
||||||
new Artist { Name = "Barenaked Ladies" },
|
|
||||||
new Artist { Name = "BBC Concert Orchestra" },
|
|
||||||
new Artist { Name = "Bee Gees" },
|
|
||||||
new Artist { Name = "Before the Dawn" },
|
|
||||||
new Artist { Name = "Berliner Philharmoniker" },
|
|
||||||
new Artist { Name = "Billy Cobham" },
|
|
||||||
new Artist { Name = "Black Label Society" },
|
|
||||||
new Artist { Name = "Black Sabbath" },
|
|
||||||
new Artist { Name = "BLØF" },
|
|
||||||
new Artist { Name = "Blues Traveler" },
|
|
||||||
new Artist { Name = "Boston Symphony Orchestra & Seiji Ozawa" },
|
|
||||||
new Artist { Name = "Britten Sinfonia, Ivor Bolton & Lesley Garrett" },
|
|
||||||
new Artist { Name = "Bruce Dickinson" },
|
|
||||||
new Artist { Name = "Buddy Guy" },
|
|
||||||
new Artist { Name = "Burial" },
|
|
||||||
new Artist { Name = "Butch Walker & The Black Widows" },
|
|
||||||
new Artist { Name = "Caetano Veloso" },
|
|
||||||
new Artist { Name = "Cake" },
|
|
||||||
new Artist { Name = "Calexico" },
|
|
||||||
new Artist { Name = "Carly Rae Jepsen" },
|
|
||||||
new Artist { Name = "Carreras, Pavarotti, Domingo" },
|
|
||||||
new Artist { Name = "Cássia Eller" },
|
|
||||||
new Artist { Name = "Cayouche" },
|
|
||||||
new Artist { Name = "Chic" },
|
|
||||||
new Artist { Name = "Chicago " },
|
|
||||||
new Artist { Name = "Chicago Symphony Orchestra & Fritz Reiner" },
|
|
||||||
new Artist { Name = "Chico Buarque" },
|
|
||||||
new Artist { Name = "Chico Science & Nação Zumbi" },
|
|
||||||
new Artist { Name = "Choir Of Westminster Abbey & Simon Preston" },
|
|
||||||
new Artist { Name = "Chris Cornell" },
|
|
||||||
new Artist { Name = "Christopher O'Riley" },
|
|
||||||
new Artist { Name = "Cidade Negra" },
|
|
||||||
new Artist { Name = "Cláudio Zoli" },
|
|
||||||
new Artist { Name = "Coldplay" },
|
|
||||||
new Artist { Name = "Creedence Clearwater Revival" },
|
|
||||||
new Artist { Name = "Crosby, Stills, Nash, and Young" },
|
|
||||||
new Artist { Name = "Daft Punk" },
|
|
||||||
new Artist { Name = "Danielson Famile" },
|
|
||||||
new Artist { Name = "David Bowie" },
|
|
||||||
new Artist { Name = "David Coverdale" },
|
|
||||||
new Artist { Name = "David Guetta" },
|
|
||||||
new Artist { Name = "deadmau5" },
|
|
||||||
new Artist { Name = "Deep Purple" },
|
|
||||||
new Artist { Name = "Def Leppard" },
|
|
||||||
new Artist { Name = "Deftones" },
|
|
||||||
new Artist { Name = "Dennis Chambers" },
|
|
||||||
new Artist { Name = "Deva Premal" },
|
|
||||||
new Artist { Name = "Dio" },
|
|
||||||
new Artist { Name = "Djavan" },
|
|
||||||
new Artist { Name = "Dolly Parton" },
|
|
||||||
new Artist { Name = "Donna Summer" },
|
|
||||||
new Artist { Name = "Dr. Dre" },
|
|
||||||
new Artist { Name = "Dread Zeppelin" },
|
|
||||||
new Artist { Name = "Dream Theater" },
|
|
||||||
new Artist { Name = "Duck Sauce" },
|
|
||||||
new Artist { Name = "Earl Scruggs" },
|
|
||||||
new Artist { Name = "Ed Motta" },
|
|
||||||
new Artist { Name = "Edo de Waart & San Francisco Symphony" },
|
|
||||||
new Artist { Name = "Elis Regina" },
|
|
||||||
new Artist { Name = "Eminem" },
|
|
||||||
new Artist { Name = "English Concert & Trevor Pinnock" },
|
|
||||||
new Artist { Name = "Enya" },
|
|
||||||
new Artist { Name = "Epica" },
|
|
||||||
new Artist { Name = "Eric B. and Rakim" },
|
|
||||||
new Artist { Name = "Eric Clapton" },
|
|
||||||
new Artist { Name = "Eugene Ormandy" },
|
|
||||||
new Artist { Name = "Faith No More" },
|
|
||||||
new Artist { Name = "Falamansa" },
|
|
||||||
new Artist { Name = "Filter" },
|
|
||||||
new Artist { Name = "Foo Fighters" },
|
|
||||||
new Artist { Name = "Four Tet" },
|
|
||||||
new Artist { Name = "Frank Zappa & Captain Beefheart" },
|
|
||||||
new Artist { Name = "Fretwork" },
|
|
||||||
new Artist { Name = "Funk Como Le Gusta" },
|
|
||||||
new Artist { Name = "Garbage" },
|
|
||||||
new Artist { Name = "Gerald Moore" },
|
|
||||||
new Artist { Name = "Gilberto Gil" },
|
|
||||||
new Artist { Name = "Godsmack" },
|
|
||||||
new Artist { Name = "Gonzaguinha" },
|
|
||||||
new Artist { Name = "Göteborgs Symfoniker & Neeme Järvi" },
|
|
||||||
new Artist { Name = "Guns N' Roses" },
|
|
||||||
new Artist { Name = "Gustav Mahler" },
|
|
||||||
new Artist { Name = "In This Moment" },
|
|
||||||
new Artist { Name = "Incognito" },
|
|
||||||
new Artist { Name = "INXS" },
|
|
||||||
new Artist { Name = "Iron Maiden" },
|
|
||||||
new Artist { Name = "Jagjit Singh" },
|
|
||||||
new Artist { Name = "James Levine" },
|
|
||||||
new Artist { Name = "Jamiroquai" },
|
|
||||||
new Artist { Name = "Jimi Hendrix" },
|
|
||||||
new Artist { Name = "Jimmy Buffett" },
|
|
||||||
new Artist { Name = "Jimmy Smith" },
|
|
||||||
new Artist { Name = "Joe Satriani" },
|
|
||||||
new Artist { Name = "John Digweed" },
|
|
||||||
new Artist { Name = "John Mayer" },
|
|
||||||
new Artist { Name = "Jorge Ben" },
|
|
||||||
new Artist { Name = "Jota Quest" },
|
|
||||||
new Artist { Name = "Journey" },
|
|
||||||
new Artist { Name = "Judas Priest" },
|
|
||||||
new Artist { Name = "Julian Bream" },
|
|
||||||
new Artist { Name = "Justice" },
|
|
||||||
new Artist { Name = "Orchestre de l'Opéra de Lyon" },
|
|
||||||
new Artist { Name = "King Crimson" },
|
|
||||||
new Artist { Name = "Kiss" },
|
|
||||||
new Artist { Name = "LCD Soundsystem" },
|
|
||||||
new Artist { Name = "Le Tigre" },
|
|
||||||
new Artist { Name = "Led Zeppelin" },
|
|
||||||
new Artist { Name = "Legião Urbana" },
|
|
||||||
new Artist { Name = "Lenny Kravitz" },
|
|
||||||
new Artist { Name = "Les Arts Florissants & William Christie" },
|
|
||||||
new Artist { Name = "Limp Bizkit" },
|
|
||||||
new Artist { Name = "Linkin Park" },
|
|
||||||
new Artist { Name = "Live" },
|
|
||||||
new Artist { Name = "Lokua Kanza" },
|
|
||||||
new Artist { Name = "London Symphony Orchestra" },
|
|
||||||
new Artist { Name = "Los Tigres del Norte" },
|
|
||||||
new Artist { Name = "Luciana Souza/Romero Lubambo" },
|
|
||||||
new Artist { Name = "Lulu Santos" },
|
|
||||||
new Artist { Name = "Lura" },
|
|
||||||
new Artist { Name = "Marcos Valle" },
|
|
||||||
new Artist { Name = "Marillion" },
|
|
||||||
new Artist { Name = "Marisa Monte" },
|
|
||||||
new Artist { Name = "Mark Knopfler" },
|
|
||||||
new Artist { Name = "Martin Roscoe" },
|
|
||||||
new Artist { Name = "Massive Attack" },
|
|
||||||
new Artist { Name = "Maurizio Pollini" },
|
|
||||||
new Artist { Name = "Megadeth" },
|
|
||||||
new Artist { Name = "Mela Tenenbaum, Pro Musica Prague & Richard Kapp" },
|
|
||||||
new Artist { Name = "Melanie Fiona" },
|
|
||||||
new Artist { Name = "Men At Work" },
|
|
||||||
new Artist { Name = "Metallica" },
|
|
||||||
new Artist { Name = "M-Flo" },
|
|
||||||
new Artist { Name = "Michael Bolton" },
|
|
||||||
new Artist { Name = "Michael Tilson Thomas" },
|
|
||||||
new Artist { Name = "Miles Davis" },
|
|
||||||
new Artist { Name = "Milton Nascimento" },
|
|
||||||
new Artist { Name = "Mobile" },
|
|
||||||
new Artist { Name = "Modest Mouse" },
|
|
||||||
new Artist { Name = "Mötley Crüe" },
|
|
||||||
new Artist { Name = "Motörhead" },
|
|
||||||
new Artist { Name = "Mumford & Sons" },
|
|
||||||
new Artist { Name = "Munkle" },
|
|
||||||
new Artist { Name = "Nash Ensemble" },
|
|
||||||
new Artist { Name = "Neil Young" },
|
|
||||||
new Artist { Name = "New York Dolls" },
|
|
||||||
new Artist { Name = "Nick Cave and the Bad Seeds" },
|
|
||||||
new Artist { Name = "Nicolaus Esterhazy Sinfonia" },
|
|
||||||
new Artist { Name = "Nine Inch Nails" },
|
|
||||||
new Artist { Name = "Nirvana" },
|
|
||||||
new Artist { Name = "Norah Jones" },
|
|
||||||
new Artist { Name = "Nujabes" },
|
|
||||||
new Artist { Name = "O Terço" },
|
|
||||||
new Artist { Name = "Oasis" },
|
|
||||||
new Artist { Name = "Olodum" },
|
|
||||||
new Artist { Name = "Opeth" },
|
|
||||||
new Artist { Name = "Orchestra of The Age of Enlightenment" },
|
|
||||||
new Artist { Name = "Os Paralamas Do Sucesso" },
|
|
||||||
new Artist { Name = "Ozzy Osbourne" },
|
|
||||||
new Artist { Name = "Paddy Casey" },
|
|
||||||
new Artist { Name = "Page & Plant" },
|
|
||||||
new Artist { Name = "Papa Wemba" },
|
|
||||||
new Artist { Name = "Paul D'Ianno" },
|
|
||||||
new Artist { Name = "Paul Oakenfold" },
|
|
||||||
new Artist { Name = "Paul Van Dyk" },
|
|
||||||
new Artist { Name = "Pearl Jam" },
|
|
||||||
new Artist { Name = "Pet Shop Boys" },
|
|
||||||
new Artist { Name = "Pink Floyd" },
|
|
||||||
new Artist { Name = "Plug" },
|
|
||||||
new Artist { Name = "Porcupine Tree" },
|
|
||||||
new Artist { Name = "Portishead" },
|
|
||||||
new Artist { Name = "Prince" },
|
|
||||||
new Artist { Name = "Projected" },
|
|
||||||
new Artist { Name = "PSY" },
|
|
||||||
new Artist { Name = "Public Enemy" },
|
|
||||||
new Artist { Name = "Queen" },
|
|
||||||
new Artist { Name = "Queensrÿche" },
|
|
||||||
new Artist { Name = "R.E.M." },
|
|
||||||
new Artist { Name = "Radiohead" },
|
|
||||||
new Artist { Name = "Rancid" },
|
|
||||||
new Artist { Name = "Raul Seixas" },
|
|
||||||
new Artist { Name = "Raunchy" },
|
|
||||||
new Artist { Name = "Red Hot Chili Peppers" },
|
|
||||||
new Artist { Name = "Rick Ross" },
|
|
||||||
new Artist { Name = "Robert James" },
|
|
||||||
new Artist { Name = "London Classical Players" },
|
|
||||||
new Artist { Name = "Royal Philharmonic Orchestra" },
|
|
||||||
new Artist { Name = "Run DMC" },
|
|
||||||
new Artist { Name = "Rush" },
|
|
||||||
new Artist { Name = "Santana" },
|
|
||||||
new Artist { Name = "Sara Tavares" },
|
|
||||||
new Artist { Name = "Sarah Brightman" },
|
|
||||||
new Artist { Name = "Sasha" },
|
|
||||||
new Artist { Name = "Scholars Baroque Ensemble" },
|
|
||||||
new Artist { Name = "Scorpions" },
|
|
||||||
new Artist { Name = "Sergei Prokofiev & Yuri Temirkanov" },
|
|
||||||
new Artist { Name = "Sheryl Crow" },
|
|
||||||
new Artist { Name = "Sir Georg Solti & Wiener Philharmoniker" },
|
|
||||||
new Artist { Name = "Skank" },
|
|
||||||
new Artist { Name = "Skrillex" },
|
|
||||||
new Artist { Name = "Slash" },
|
|
||||||
new Artist { Name = "Slayer" },
|
|
||||||
new Artist { Name = "Soul-Junk" },
|
|
||||||
new Artist { Name = "Soundgarden" },
|
|
||||||
new Artist { Name = "Spyro Gyra" },
|
|
||||||
new Artist { Name = "Stevie Ray Vaughan & Double Trouble" },
|
|
||||||
new Artist { Name = "Stevie Ray Vaughan" },
|
|
||||||
new Artist { Name = "Sting" },
|
|
||||||
new Artist { Name = "Stone Temple Pilots" },
|
|
||||||
new Artist { Name = "Styx" },
|
|
||||||
new Artist { Name = "Sufjan Stevens" },
|
|
||||||
new Artist { Name = "Supreme Beings of Leisure" },
|
|
||||||
new Artist { Name = "System Of A Down" },
|
|
||||||
new Artist { Name = "T&N" },
|
|
||||||
new Artist { Name = "Talking Heads" },
|
|
||||||
new Artist { Name = "Tears For Fears" },
|
|
||||||
new Artist { Name = "Ted Nugent" },
|
|
||||||
new Artist { Name = "Temple of the Dog" },
|
|
||||||
new Artist { Name = "Terry Bozzio, Tony Levin & Steve Stevens" },
|
|
||||||
new Artist { Name = "The 12 Cellists of The Berlin Philharmonic" },
|
|
||||||
new Artist { Name = "The Axis of Awesome" },
|
|
||||||
new Artist { Name = "The Beatles" },
|
|
||||||
new Artist { Name = "The Black Crowes" },
|
|
||||||
new Artist { Name = "The Black Keys" },
|
|
||||||
new Artist { Name = "The Carpenters" },
|
|
||||||
new Artist { Name = "The Cat Empire" },
|
|
||||||
new Artist { Name = "The Cult" },
|
|
||||||
new Artist { Name = "The Cure" },
|
|
||||||
new Artist { Name = "The Decemberists" },
|
|
||||||
new Artist { Name = "The Doors" },
|
|
||||||
new Artist { Name = "The Eagles of Death Metal" },
|
|
||||||
new Artist { Name = "The Go! Team" },
|
|
||||||
new Artist { Name = "The Head and the Heart" },
|
|
||||||
new Artist { Name = "The Jezabels" },
|
|
||||||
new Artist { Name = "The King's Singers" },
|
|
||||||
new Artist { Name = "The Lumineers" },
|
|
||||||
new Artist { Name = "The Offspring" },
|
|
||||||
new Artist { Name = "The Police" },
|
|
||||||
new Artist { Name = "The Posies" },
|
|
||||||
new Artist { Name = "The Prodigy" },
|
|
||||||
new Artist { Name = "The Rolling Stones" },
|
|
||||||
new Artist { Name = "The Rubberbandits" },
|
|
||||||
new Artist { Name = "The Smashing Pumpkins" },
|
|
||||||
new Artist { Name = "The Stone Roses" },
|
|
||||||
new Artist { Name = "The Who" },
|
|
||||||
new Artist { Name = "Them Crooked Vultures" },
|
|
||||||
new Artist { Name = "TheStart" },
|
|
||||||
new Artist { Name = "Thievery Corporation" },
|
|
||||||
new Artist { Name = "Tiësto" },
|
|
||||||
new Artist { Name = "Tim Maia" },
|
|
||||||
new Artist { Name = "Ton Koopman" },
|
|
||||||
new Artist { Name = "Tool" },
|
|
||||||
new Artist { Name = "Tori Amos" },
|
|
||||||
new Artist { Name = "Trampled By Turtles" },
|
|
||||||
new Artist { Name = "Trans-Siberian Orchestra" },
|
|
||||||
new Artist { Name = "Tygers of Pan Tang" },
|
|
||||||
new Artist { Name = "U2" },
|
|
||||||
new Artist { Name = "UB40" },
|
|
||||||
new Artist { Name = "Uh Huh Her " },
|
|
||||||
new Artist { Name = "Van Halen" },
|
|
||||||
new Artist { Name = "Various Artists" },
|
|
||||||
new Artist { Name = "Velvet Revolver" },
|
|
||||||
new Artist { Name = "Venus Hum" },
|
|
||||||
new Artist { Name = "Vicente Fernandez" },
|
|
||||||
new Artist { Name = "Vinícius De Moraes" },
|
|
||||||
new Artist { Name = "Weezer" },
|
|
||||||
new Artist { Name = "Weird Al" },
|
|
||||||
new Artist { Name = "Wendy Carlos" },
|
|
||||||
new Artist { Name = "Wilhelm Kempff" },
|
|
||||||
new Artist { Name = "Yano" },
|
|
||||||
new Artist { Name = "Yehudi Menuhin" },
|
|
||||||
new Artist { Name = "Yes" },
|
|
||||||
new Artist { Name = "Yo-Yo Ma" },
|
|
||||||
new Artist { Name = "Zeca Pagodinho" },
|
|
||||||
new Artist { Name = "אריק אינשטיין"}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO [EF] Swap to store generated keys when available
|
|
||||||
int artistId = 1;
|
|
||||||
artists = new Dictionary<string, Artist>();
|
|
||||||
foreach (Artist artist in artistsList)
|
|
||||||
{
|
|
||||||
artist.ArtistId = artistId++;
|
|
||||||
artists.Add(artist.Name, artist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return artists;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Dictionary<string, Genre> genres;
|
|
||||||
public static Dictionary<string, Genre> Genres
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (genres == null)
|
|
||||||
{
|
|
||||||
var genresList = new Genre[]
|
|
||||||
{
|
|
||||||
new Genre { Name = "Pop" },
|
|
||||||
new Genre { Name = "Rock" },
|
|
||||||
new Genre { Name = "Jazz" },
|
|
||||||
new Genre { Name = "Metal" },
|
|
||||||
new Genre { Name = "Electronic" },
|
|
||||||
new Genre { Name = "Blues" },
|
|
||||||
new Genre { Name = "Latin" },
|
|
||||||
new Genre { Name = "Rap" },
|
|
||||||
new Genre { Name = "Classical" },
|
|
||||||
new Genre { Name = "Alternative" },
|
|
||||||
new Genre { Name = "Country" },
|
|
||||||
new Genre { Name = "R&B" },
|
|
||||||
new Genre { Name = "Indie" },
|
|
||||||
new Genre { Name = "Punk" },
|
|
||||||
new Genre { Name = "World" }
|
|
||||||
};
|
|
||||||
|
|
||||||
genres = new Dictionary<string, Genre>();
|
|
||||||
// TODO [EF] Swap to store generated keys when available
|
|
||||||
int genreId = 1;
|
|
||||||
foreach (Genre genre in genresList)
|
|
||||||
{
|
|
||||||
genre.GenreId = genreId++;
|
|
||||||
|
|
||||||
// TODO [EF] Remove when null values are supported by update pipeline
|
|
||||||
genre.Description = genre.Name + " is great music (if you like it).";
|
|
||||||
|
|
||||||
genres.Add(genre.Name, genre);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return genres;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
// Obviously this is not a serious sentiment analyser. It is only here to provide an amusing demonstration of cross-property
|
|
||||||
// validation in AlbumsApiController.
|
|
||||||
public static class SentimentAnalysis
|
|
||||||
{
|
|
||||||
private static string[] positiveSentimentWords = new[] { "happy", "fun", "joy", "love", "delight", "bunny", "bunnies", "asp.net" };
|
|
||||||
|
|
||||||
private static string[] negativeSentimentWords = new[] { "sad", "pain", "despair", "hate", "scorn", "death", "package management" };
|
|
||||||
|
|
||||||
public static SentimentResult GetSentiment(string text) {
|
|
||||||
var numPositiveWords = CountWordOccurrences(text, positiveSentimentWords);
|
|
||||||
var numNegativeWords = CountWordOccurrences(text, negativeSentimentWords);
|
|
||||||
if (numPositiveWords > numNegativeWords) {
|
|
||||||
return SentimentResult.Positive;
|
|
||||||
} else if (numNegativeWords > numPositiveWords) {
|
|
||||||
return SentimentResult.Negative;
|
|
||||||
} else {
|
|
||||||
return SentimentResult.Neutral;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int CountWordOccurrences(string text, string[] words)
|
|
||||||
{
|
|
||||||
// Very simplistic matching technique for this sample. Not scalable and not really even correct.
|
|
||||||
return new Regex(string.Join("|", words), RegexOptions.IgnoreCase).Matches(text).Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SentimentResult {
|
|
||||||
Negative,
|
|
||||||
Neutral,
|
|
||||||
Positive,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace MusicStore.Models
|
|
||||||
{
|
|
||||||
public partial class ShoppingCart
|
|
||||||
{
|
|
||||||
MusicStoreContext _db;
|
|
||||||
string ShoppingCartId { get; set; }
|
|
||||||
|
|
||||||
public ShoppingCart(MusicStoreContext db)
|
|
||||||
{
|
|
||||||
_db = db;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context)
|
|
||||||
{
|
|
||||||
var cart = new ShoppingCart(db);
|
|
||||||
cart.ShoppingCartId = cart.GetCartId(context);
|
|
||||||
return cart;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddToCart(Album album)
|
|
||||||
{
|
|
||||||
// Get the matching cart and album instances
|
|
||||||
var cartItem = _db.CartItems.SingleOrDefault(
|
|
||||||
c => c.CartId == ShoppingCartId
|
|
||||||
&& c.AlbumId == album.AlbumId);
|
|
||||||
|
|
||||||
if (cartItem == null)
|
|
||||||
{
|
|
||||||
// TODO [EF] Swap to store generated key once we support identity pattern
|
|
||||||
var nextCartItemId = _db.CartItems.Any()
|
|
||||||
? _db.CartItems.Max(c => c.CartItemId) + 1
|
|
||||||
: 1;
|
|
||||||
|
|
||||||
// Create a new cart item if no cart item exists
|
|
||||||
cartItem = new CartItem
|
|
||||||
{
|
|
||||||
CartItemId = nextCartItemId,
|
|
||||||
AlbumId = album.AlbumId,
|
|
||||||
CartId = ShoppingCartId,
|
|
||||||
Count = 1,
|
|
||||||
DateCreated = DateTime.Now
|
|
||||||
};
|
|
||||||
|
|
||||||
_db.CartItems.Add(cartItem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If the item does exist in the cart, then add one to the quantity
|
|
||||||
cartItem.Count++;
|
|
||||||
|
|
||||||
// TODO [EF] Remove this line once change detection is available
|
|
||||||
_db.Update(cartItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RemoveFromCart(int id)
|
|
||||||
{
|
|
||||||
// Get the cart
|
|
||||||
var cartItem = _db.CartItems.Single(
|
|
||||||
cart => cart.CartId == ShoppingCartId
|
|
||||||
&& cart.CartItemId == id);
|
|
||||||
|
|
||||||
int itemCount = 0;
|
|
||||||
|
|
||||||
if (cartItem != null)
|
|
||||||
{
|
|
||||||
if (cartItem.Count > 1)
|
|
||||||
{
|
|
||||||
cartItem.Count--;
|
|
||||||
|
|
||||||
// TODO [EF] Remove this line once change detection is available
|
|
||||||
_db.Update(cartItem);
|
|
||||||
|
|
||||||
itemCount = cartItem.Count;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_db.CartItems.Remove(cartItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EmptyCart()
|
|
||||||
{
|
|
||||||
var cartItems = _db.CartItems.Where(cart => cart.CartId == ShoppingCartId);
|
|
||||||
|
|
||||||
foreach (var cartItem in cartItems)
|
|
||||||
{
|
|
||||||
_db.Remove(cartItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<CartItem> GetCartItems()
|
|
||||||
{
|
|
||||||
var cartItems = _db.CartItems.Where(cart => cart.CartId == ShoppingCartId).ToList();
|
|
||||||
//TODO: Auto population of the related album data not available until EF feature is lighted up.
|
|
||||||
foreach (var cartItem in cartItems)
|
|
||||||
{
|
|
||||||
cartItem.Album = _db.Albums.Single(a => a.AlbumId == cartItem.AlbumId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cartItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetCount()
|
|
||||||
{
|
|
||||||
// Get the count of each item in the cart and sum them up
|
|
||||||
int? count = (from cartItems in _db.CartItems
|
|
||||||
where cartItems.CartId == ShoppingCartId
|
|
||||||
select (int?)cartItems.Count).Sum();
|
|
||||||
|
|
||||||
// Return 0 if all entries are null
|
|
||||||
return count ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public decimal GetTotal()
|
|
||||||
{
|
|
||||||
// Multiply album price by count of that album to get
|
|
||||||
// the current price for each of those albums in the cart
|
|
||||||
// sum all album price totals to get the cart total
|
|
||||||
|
|
||||||
// TODO Collapse to a single query once EF supports querying related data
|
|
||||||
decimal total = 0;
|
|
||||||
foreach (var item in _db.CartItems.Where(c => c.CartId == ShoppingCartId))
|
|
||||||
{
|
|
||||||
var album = _db.Albums.Single(a => a.AlbumId == item.AlbumId);
|
|
||||||
total += item.Count * album.Price;
|
|
||||||
}
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int CreateOrder(Order order)
|
|
||||||
{
|
|
||||||
decimal orderTotal = 0;
|
|
||||||
|
|
||||||
var cartItems = GetCartItems();
|
|
||||||
|
|
||||||
// TODO [EF] Swap to store generated identity key when supported
|
|
||||||
var nextId = _db.OrderDetails.Any()
|
|
||||||
? _db.OrderDetails.Max(o => o.OrderDetailId) + 1
|
|
||||||
: 1;
|
|
||||||
|
|
||||||
// Iterate over the items in the cart, adding the order details for each
|
|
||||||
foreach (var item in cartItems)
|
|
||||||
{
|
|
||||||
//var album = _db.Albums.Find(item.AlbumId);
|
|
||||||
var album = _db.Albums.Single(a => a.AlbumId == item.AlbumId);
|
|
||||||
|
|
||||||
var orderDetail = new OrderDetail
|
|
||||||
{
|
|
||||||
OrderDetailId = nextId,
|
|
||||||
AlbumId = item.AlbumId,
|
|
||||||
OrderId = order.OrderId,
|
|
||||||
UnitPrice = album.Price,
|
|
||||||
Quantity = item.Count,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set the order total of the shopping cart
|
|
||||||
orderTotal += (item.Count * album.Price);
|
|
||||||
|
|
||||||
_db.OrderDetails.Add(orderDetail);
|
|
||||||
|
|
||||||
nextId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the order's total to the orderTotal count
|
|
||||||
order.Total = orderTotal;
|
|
||||||
|
|
||||||
// Empty the shopping cart
|
|
||||||
EmptyCart();
|
|
||||||
|
|
||||||
// Return the OrderId as the confirmation number
|
|
||||||
return order.OrderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're using HttpContextBase to allow access to cookies.
|
|
||||||
public string GetCartId(HttpContext context)
|
|
||||||
{
|
|
||||||
var sessionCookie = context.Request.Cookies["Session"];
|
|
||||||
string cartId = null;
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(sessionCookie))
|
|
||||||
{
|
|
||||||
//A GUID to hold the cartId.
|
|
||||||
cartId = Guid.NewGuid().ToString();
|
|
||||||
|
|
||||||
// Send cart Id as a cookie to the client.
|
|
||||||
context.Response.Cookies.Append("Session", cartId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cartId = sessionCookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cartId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace MusicStore.Controllers
|
|
||||||
{
|
|
||||||
public class HomeController : Controller
|
|
||||||
{
|
|
||||||
public IActionResult Index()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult Error()
|
|
||||||
{
|
|
||||||
return View("~/Views/Shared/Error.cshtml");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using System;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
|
|
||||||
namespace MusicStore.Infrastructure
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
|
||||||
public sealed class NoCacheAttribute : ActionFilterAttribute
|
|
||||||
{
|
|
||||||
public override void OnResultExecuting(ResultExecutingContext context)
|
|
||||||
{
|
|
||||||
context.HttpContext.Response.Headers["Cache-Control"] = "no-cache, no-store, max-age=0";
|
|
||||||
context.HttpContext.Response.Headers["Pragma"] = "no-cache";
|
|
||||||
context.HttpContext.Response.Headers["Expires"] = "-1";
|
|
||||||
|
|
||||||
base.OnResultExecuting(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MusicStore.Infrastructure
|
|
||||||
{
|
|
||||||
public interface IPagedList<T>
|
|
||||||
{
|
|
||||||
IEnumerable<T> Data { get; }
|
|
||||||
|
|
||||||
int Page { get; }
|
|
||||||
|
|
||||||
int PageSize { get; }
|
|
||||||
|
|
||||||
int TotalCount { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class PagedList<T> : IPagedList<T>
|
|
||||||
{
|
|
||||||
public PagedList(IEnumerable<T> data, int page, int pageSize, int totalCount)
|
|
||||||
{
|
|
||||||
Data = data;
|
|
||||||
Page = page;
|
|
||||||
PageSize = pageSize;
|
|
||||||
TotalCount = totalCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<T> Data { get; private set; }
|
|
||||||
|
|
||||||
public int Page { get; private set; }
|
|
||||||
|
|
||||||
public int PageSize { get; private set; }
|
|
||||||
|
|
||||||
public int TotalCount { get; private set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PagedListExtensions
|
|
||||||
{
|
|
||||||
public static IPagedList<T> ToPagedList<T>(this IQueryable<T> query, int page, int pageSize)
|
|
||||||
{
|
|
||||||
if (query == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("query");
|
|
||||||
}
|
|
||||||
|
|
||||||
var pagingConfig = new PagingConfig(page, pageSize);
|
|
||||||
var skipCount = ValidatePagePropertiesAndGetSkipCount(pagingConfig);
|
|
||||||
|
|
||||||
var data = query
|
|
||||||
.Skip(skipCount)
|
|
||||||
.Take(pagingConfig.PageSize)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (skipCount > 0 && data.Count == 0)
|
|
||||||
{
|
|
||||||
// Requested page has no records, just return the first page
|
|
||||||
pagingConfig.Page = 1;
|
|
||||||
data = query
|
|
||||||
.Take(pagingConfig.PageSize)
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PagedList<T>(data, pagingConfig.Page, pagingConfig.PageSize, query.Count());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Task<IPagedList<TModel>> ToPagedListAsync<TModel, TProperty>(this IQueryable<TModel> query, int page, int pageSize, string sortExpression, Expression<Func<TModel, TProperty>> defaultSortExpression, SortDirection defaultSortDirection = SortDirection.Ascending)
|
|
||||||
where TModel : class
|
|
||||||
{
|
|
||||||
return ToPagedListAsync<TModel, TProperty, TModel>(query, page, pageSize, sortExpression, defaultSortExpression, defaultSortDirection, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<IPagedList<TResult>> ToPagedListAsync<TModel, TProperty, TResult>(this IQueryable<TModel> query, int page, int pageSize, string sortExpression, Expression<Func<TModel, TProperty>> defaultSortExpression, SortDirection defaultSortDirection, Func<TModel, TResult> selector)
|
|
||||||
where TModel : class
|
|
||||||
where TResult : class
|
|
||||||
{
|
|
||||||
if (query == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("query");
|
|
||||||
}
|
|
||||||
|
|
||||||
var pagingConfig = new PagingConfig(page, pageSize);
|
|
||||||
var skipCount = ValidatePagePropertiesAndGetSkipCount(pagingConfig);
|
|
||||||
var dataQuery = query;
|
|
||||||
|
|
||||||
if (defaultSortExpression != null)
|
|
||||||
{
|
|
||||||
dataQuery = dataQuery
|
|
||||||
.SortBy(sortExpression, defaultSortExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = await dataQuery
|
|
||||||
.Skip(skipCount)
|
|
||||||
.Take(pagingConfig.PageSize)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (skipCount > 0 && data.Count == 0)
|
|
||||||
{
|
|
||||||
// Requested page has no records, just return the first page
|
|
||||||
pagingConfig.Page = 1;
|
|
||||||
data = await dataQuery
|
|
||||||
.Take(pagingConfig.PageSize)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = await query.CountAsync();
|
|
||||||
|
|
||||||
var resultData = selector != null
|
|
||||||
? data.Select(selector)
|
|
||||||
: data.Cast<TResult>();
|
|
||||||
|
|
||||||
return new PagedList<TResult>(resultData, pagingConfig.Page, pagingConfig.PageSize, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int ValidatePagePropertiesAndGetSkipCount(PagingConfig pagingConfig)
|
|
||||||
{
|
|
||||||
if (pagingConfig.Page < 1)
|
|
||||||
{
|
|
||||||
pagingConfig.Page = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pagingConfig.PageSize < 10)
|
|
||||||
{
|
|
||||||
pagingConfig.PageSize = 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pagingConfig.PageSize > 100)
|
|
||||||
{
|
|
||||||
pagingConfig.PageSize = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pagingConfig.PageSize * (pagingConfig.Page - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class PagingConfig
|
|
||||||
{
|
|
||||||
public PagingConfig(int page, int pageSize)
|
|
||||||
{
|
|
||||||
Page = page;
|
|
||||||
PageSize = pageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Page { get; set; }
|
|
||||||
|
|
||||||
public int PageSize { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MusicStore.Infrastructure
|
|
||||||
{
|
|
||||||
public enum SortDirection
|
|
||||||
{
|
|
||||||
Ascending,
|
|
||||||
Descending
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
|
||||||
|
|
||||||
namespace MusicStore.Infrastructure
|
|
||||||
{
|
|
||||||
public static class SortExpression
|
|
||||||
{
|
|
||||||
private const string SORT_DIRECTION_DESC = " DESC";
|
|
||||||
|
|
||||||
public static IQueryable<TModel> SortBy<TModel, TProperty>(this IQueryable<TModel> query, string sortExpression, Expression<Func<TModel, TProperty>> defaultSortExpression, SortDirection defaultSortDirection = SortDirection.Ascending) where TModel : class
|
|
||||||
{
|
|
||||||
return SortBy(query, sortExpression ?? Create(defaultSortExpression, defaultSortDirection));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Create<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression, SortDirection sortDirection = SortDirection.Ascending) where TModel : class
|
|
||||||
{
|
|
||||||
var expressionText = ExpressionHelper.GetExpressionText(expression);
|
|
||||||
// TODO: Validate the expression depth, etc.
|
|
||||||
|
|
||||||
var sortExpression = expressionText;
|
|
||||||
|
|
||||||
if (sortDirection == SortDirection.Descending)
|
|
||||||
{
|
|
||||||
sortExpression += SORT_DIRECTION_DESC;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string sortExpression) where T : class
|
|
||||||
{
|
|
||||||
if (source == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("source");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (String.IsNullOrWhiteSpace(sortExpression))
|
|
||||||
{
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
sortExpression = sortExpression.Trim();
|
|
||||||
var isDescending = false;
|
|
||||||
|
|
||||||
// DataSource control passes the sort parameter with a direction
|
|
||||||
// if the direction is descending
|
|
||||||
if (sortExpression.EndsWith(SORT_DIRECTION_DESC, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
isDescending = true;
|
|
||||||
var descIndex = sortExpression.Length - SORT_DIRECTION_DESC.Length;
|
|
||||||
sortExpression = sortExpression.Substring(0, descIndex).Trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(sortExpression))
|
|
||||||
{
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty);
|
|
||||||
|
|
||||||
// Build up the property expression, e.g.: (m => m.Foo.Bar)
|
|
||||||
var sortExpressionParts = sortExpression.Split('.');
|
|
||||||
Expression propertyExpression = parameter;
|
|
||||||
foreach (var property in sortExpressionParts)
|
|
||||||
{
|
|
||||||
propertyExpression = Expression.Property(propertyExpression, property);
|
|
||||||
}
|
|
||||||
|
|
||||||
LambdaExpression lambda = Expression.Lambda(propertyExpression, parameter);
|
|
||||||
|
|
||||||
var methodName = (isDescending) ? "OrderByDescending" : "OrderBy";
|
|
||||||
|
|
||||||
Expression methodCallExpression = Expression.Call(
|
|
||||||
typeof(Queryable),
|
|
||||||
methodName,
|
|
||||||
new[] { source.ElementType, propertyExpression.Type },
|
|
||||||
source.Expression,
|
|
||||||
Expression.Quote(lambda));
|
|
||||||
|
|
||||||
return (IQueryable<T>)source.Provider.CreateQuery(methodCallExpression);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<Import Project="..\..\..\build\dependencies.props" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.AngularServices\Microsoft.AspNetCore.AngularServices.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="$(AspNetCoreVersion)" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="$(AspNetCoreVersion)" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(AspNetCoreVersion)" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(AspNetCoreVersion)" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SQLite" Version="$(AspNetCoreVersion)" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(AspNetCoreVersion)" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(AspNetCoreVersion)" />
|
|
||||||
<PackageReference Include="AutoMapper" Version="$(AutoMapperVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
|
||||||
<Exec Command="npm install" />
|
|
||||||
<Exec Command="gulp" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
using AutoMapper;
|
|
||||||
using MusicStore.Apis;
|
|
||||||
using MusicStore.Models;
|
|
||||||
|
|
||||||
namespace MusicStore
|
|
||||||
{
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddMvc().AddJsonOptions(options =>
|
|
||||||
{
|
|
||||||
options.SerializerSettings.ContractResolver = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add EF services to the service container
|
|
||||||
services.AddEntityFramework()
|
|
||||||
.AddEntityFrameworkSqlite()
|
|
||||||
.AddDbContext<MusicStoreContext>(options => {
|
|
||||||
options.UseSqlite("Data Source=music-db.sqlite");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add Identity services to the services container
|
|
||||||
services.AddIdentity<ApplicationUser, IdentityRole>()
|
|
||||||
.AddEntityFrameworkStores<MusicStoreContext>()
|
|
||||||
.AddDefaultTokenProviders();
|
|
||||||
|
|
||||||
// Configure Auth
|
|
||||||
services.Configure<AuthorizationOptions>(options =>
|
|
||||||
{
|
|
||||||
options.AddPolicy("app-ManageStore", new AuthorizationPolicyBuilder().RequireClaim("app-ManageStore", "Allowed").Build());
|
|
||||||
});
|
|
||||||
|
|
||||||
Mapper.Initialize(cfg =>
|
|
||||||
{
|
|
||||||
cfg.CreateMap<AlbumChangeDto, Album>();
|
|
||||||
cfg.CreateMap<Album, AlbumChangeDto>();
|
|
||||||
cfg.CreateMap<Album, AlbumResultDto>();
|
|
||||||
cfg.CreateMap<AlbumResultDto, Album>();
|
|
||||||
cfg.CreateMap<Artist, ArtistResultDto>();
|
|
||||||
cfg.CreateMap<ArtistResultDto, Artist>();
|
|
||||||
cfg.CreateMap<Genre, GenreResultDto>();
|
|
||||||
cfg.CreateMap<GenreResultDto, Genre>();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|
||||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env)
|
|
||||||
{
|
|
||||||
app.UseDeveloperExceptionPage();
|
|
||||||
|
|
||||||
// Initialize the sample data
|
|
||||||
SampleData.InitializeMusicStoreDatabaseAsync(app.ApplicationServices).Wait();
|
|
||||||
|
|
||||||
app.UseStaticFiles();
|
|
||||||
loggerFactory.AddConsole();
|
|
||||||
|
|
||||||
// Add MVC to the request pipeline.
|
|
||||||
app.UseMvc(routes =>
|
|
||||||
{
|
|
||||||
// Matches requests that correspond to an existent controller/action pair
|
|
||||||
routes.MapRoute(
|
|
||||||
name: "default",
|
|
||||||
template: "{controller=Home}/{action=Index}/{id?}");
|
|
||||||
|
|
||||||
// Matches any other request that doesn't appear to have a filename extension (defined as 'having a dot in the last URI segment').
|
|
||||||
// This means you'll correctly get 404s for /some/dir/non-existent-image.png instead of returning the SPA HTML.
|
|
||||||
// However, it means requests like /customers/isaac.newton will *not* be mapped into the SPA, so if you need to accept
|
|
||||||
// URIs like that you'll need to match all URIs, e.g.:
|
|
||||||
// routes.MapRoute("spa-fallback", "{*anything}", new { controller = "Home", action = "Index" });
|
|
||||||
// (which of course will match /customers/isaac.png too, so in that case it would serve the PNG image at that URL if one is on disk,
|
|
||||||
// or the SPA HTML if not).
|
|
||||||
routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
var host = new WebHostBuilder()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseKestrel()
|
|
||||||
.UseStartup<Startup>()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
host.Run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
@{
|
|
||||||
ViewData["Title"] = "Home Page";
|
|
||||||
}
|
|
||||||
|
|
||||||
<cache vary-by="@Context.Request.Path">
|
|
||||||
<app asp-prerender-module="wwwroot/ng-app/boot-server">Loading...</app>
|
|
||||||
@await Html.PrimeCacheAsync(Url.Action("GenreMenuList", "GenresApi"))
|
|
||||||
@await Html.PrimeCacheAsync(Url.Action("MostPopular", "AlbumsApi"))
|
|
||||||
</cache>
|
|
||||||
|
|
||||||
@section scripts {
|
|
||||||
<script src="~/lib/angular2/bundles/angular2-polyfills.js"></script>
|
|
||||||
<script src="~/lib/traceur/bin/traceur-runtime.js"></script>
|
|
||||||
<script src="~/lib/es6-module-loader/dist/es6-module-loader-sans-promises.js"></script>
|
|
||||||
<script src="~/lib/systemjs/dist/system.src.js"></script>
|
|
||||||
<script src="~/system.config.js"></script>
|
|
||||||
<script src="~/lib/rxjs/bundles/Rx.js"></script>
|
|
||||||
<script src="~/lib/angular2/bundles/angular2.dev.js"></script>
|
|
||||||
<script src="~/lib/angular2/bundles/router.dev.js"></script>
|
|
||||||
<script src="~/lib/angular2/bundles/http.dev.js"></script>
|
|
||||||
<script src="~/lib/angular2-aspnet/bundles/angular2-aspnet.js"></script>
|
|
||||||
<script>System.import('./ng-app/boot-client');</script>
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
@{
|
|
||||||
ViewData["Title"] = "Error";
|
|
||||||
}
|
|
||||||
|
|
||||||
<h1 class="text-danger">Error.</h1>
|
|
||||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Music Store</title>
|
|
||||||
<base href="/" />
|
|
||||||
|
|
||||||
<environment names="Development">
|
|
||||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
|
|
||||||
<link rel="stylesheet" href="~/css/site.css" />
|
|
||||||
</environment>
|
|
||||||
<environment names="Staging,Production">
|
|
||||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/css/bootstrap.min.css"
|
|
||||||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
|
|
||||||
asp-fallback-test-class="hidden" asp-fallback-test-property="visibility" asp-fallback-test-value="hidden" />
|
|
||||||
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
|
||||||
</environment>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
@RenderBody()
|
|
||||||
|
|
||||||
<environment names="Development">
|
|
||||||
<script src="~/lib/jquery/dist/jquery.js"></script>
|
|
||||||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
|
|
||||||
</environment>
|
|
||||||
<environment names="Staging,Production">
|
|
||||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"
|
|
||||||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
|
|
||||||
asp-fallback-test="window.jQuery">
|
|
||||||
</script>
|
|
||||||
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/bootstrap.min.js"
|
|
||||||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
|
|
||||||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal">
|
|
||||||
</script>
|
|
||||||
</environment>
|
|
||||||
|
|
||||||
@RenderSection("scripts", required: false)
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
@using MusicStore
|
|
||||||
@using Microsoft.AspNetCore.AngularServices
|
|
||||||
@addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
|
|
||||||
@addTagHelper "*, Microsoft.AspNetCore.SpaServices"
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
@{
|
|
||||||
Layout = "_Layout";
|
|
||||||
}
|
|
||||||
53
samples/angular/MusicStore/gulpfile.js
vendored
53
samples/angular/MusicStore/gulpfile.js
vendored
@@ -1,53 +0,0 @@
|
|||||||
/// <binding AfterBuild='build' Clean='clean' />
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var path = require('path');
|
|
||||||
var gulp = require('gulp');
|
|
||||||
var del = require('del');
|
|
||||||
var typescript = require('gulp-typescript');
|
|
||||||
var inlineNg2Template = require('gulp-inline-ng2-template');
|
|
||||||
var sourcemaps = require('gulp-sourcemaps');
|
|
||||||
|
|
||||||
var webroot = "./wwwroot/";
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
libBase: 'node_modules',
|
|
||||||
lib: [
|
|
||||||
require.resolve('bootstrap/dist/css/bootstrap.css'),
|
|
||||||
path.dirname(require.resolve('bootstrap/dist/fonts/glyphicons-halflings-regular.woff')) + '/**',
|
|
||||||
require.resolve('angular2/bundles/angular2-polyfills.js'),
|
|
||||||
require.resolve('traceur/bin/traceur-runtime.js'),
|
|
||||||
require.resolve('es6-module-loader/dist/es6-module-loader-sans-promises.js'),
|
|
||||||
require.resolve('systemjs/dist/system.src.js'),
|
|
||||||
require.resolve('angular2/bundles/angular2.dev.js'),
|
|
||||||
require.resolve('angular2/bundles/router.dev.js'),
|
|
||||||
require.resolve('angular2/bundles/http.dev.js'),
|
|
||||||
require.resolve('angular2-aspnet/bundles/angular2-aspnet.js'),
|
|
||||||
require.resolve('jquery/dist/jquery.js'),
|
|
||||||
require.resolve('bootstrap/dist/js/bootstrap.js'),
|
|
||||||
require.resolve('rxjs/bundles/Rx.js')
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
gulp.task('build.lib', function () {
|
|
||||||
return gulp.src(config.lib, { base: config.libBase })
|
|
||||||
.pipe(gulp.dest(webroot + 'lib'));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('build', ['build.lib'], function () {
|
|
||||||
var tsProject = typescript.createProject('./tsconfig.json', { typescript: require('typescript') });
|
|
||||||
var tsSrcInlined = gulp.src([webroot + '**/*.ts', 'typings/**/*.d.ts'], { base: webroot })
|
|
||||||
.pipe(inlineNg2Template({ base: webroot }));
|
|
||||||
return tsSrcInlined
|
|
||||||
.pipe(sourcemaps.init())
|
|
||||||
.pipe(typescript(tsProject))
|
|
||||||
.pipe(sourcemaps.write())
|
|
||||||
.pipe(gulp.dest(webroot));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('clean', function () {
|
|
||||||
return del([webroot + 'lib']);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('default', ['build']);
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "MusicStore",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"dependencies": {
|
|
||||||
"angular2": "2.0.0-beta.15",
|
|
||||||
"angular2-aspnet": "^0.0.6",
|
|
||||||
"angular2-universal": "0.98.1",
|
|
||||||
"angular2-express-engine": "0.11.1",
|
|
||||||
"angular2-hapi-engine": "0.11.1",
|
|
||||||
"aspnet-prerendering": "^1.0.1",
|
|
||||||
"bootstrap": "^3.3.5",
|
|
||||||
"css": "^2.2.1",
|
|
||||||
"es6-module-loader": "0.15.0",
|
|
||||||
"es6-shim": "^0.35.0",
|
|
||||||
"isomorphic-fetch": "^2.2.1",
|
|
||||||
"jquery": "^2.1.4",
|
|
||||||
"less": "^2.5.3",
|
|
||||||
"preboot": "2.0.5",
|
|
||||||
"rxjs": "5.0.0-beta.2",
|
|
||||||
"systemjs": "^0.19.3",
|
|
||||||
"traceur": "0.0.106",
|
|
||||||
"zone.js": "^0.6.10"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"del": "^2.0.2",
|
|
||||||
"gulp": "^3.9.0",
|
|
||||||
"gulp-inline-ng2-template": "0.0.7",
|
|
||||||
"gulp-sourcemaps": "^1.6.0",
|
|
||||||
"gulp-typescript": "^2.9.0",
|
|
||||||
"typescript": "^1.6.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es5",
|
|
||||||
"sourceMap": false,
|
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"noLib": false
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"node_modules"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "v4",
|
|
||||||
"repo": "borisyankov/DefinitelyTyped",
|
|
||||||
"ref": "master",
|
|
||||||
"path": "typings",
|
|
||||||
"bundle": "typings/tsd.d.ts",
|
|
||||||
"installed": {
|
|
||||||
"es6-shim/es6-shim.d.ts": {
|
|
||||||
"commit": "ec9eb4b28c74665a602c22db3457f0a76fa0fa23"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,668 +0,0 @@
|
|||||||
// Type definitions for es6-shim v0.31.2
|
|
||||||
// Project: https://github.com/paulmillr/es6-shim
|
|
||||||
// Definitions by: Ron Buckton <http://github.com/rbuckton>
|
|
||||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
|
||||||
|
|
||||||
declare type PropertyKey = string | number | symbol;
|
|
||||||
|
|
||||||
interface IteratorResult<T> {
|
|
||||||
done: boolean;
|
|
||||||
value?: T;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IterableShim<T> {
|
|
||||||
/**
|
|
||||||
* Shim for an ES6 iterable. Not intended for direct use by user code.
|
|
||||||
*/
|
|
||||||
"_es6-shim iterator_"(): Iterator<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Iterator<T> {
|
|
||||||
next(value?: any): IteratorResult<T>;
|
|
||||||
return?(value?: any): IteratorResult<T>;
|
|
||||||
throw?(e?: any): IteratorResult<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IterableIteratorShim<T> extends IterableShim<T>, Iterator<T> {
|
|
||||||
/**
|
|
||||||
* Shim for an ES6 iterable iterator. Not intended for direct use by user code.
|
|
||||||
*/
|
|
||||||
"_es6-shim iterator_"(): IterableIteratorShim<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface StringConstructor {
|
|
||||||
/**
|
|
||||||
* Return the String value whose elements are, in order, the elements in the List elements.
|
|
||||||
* If length is 0, the empty string is returned.
|
|
||||||
*/
|
|
||||||
fromCodePoint(...codePoints: number[]): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* String.raw is intended for use as a tag function of a Tagged Template String. When called
|
|
||||||
* as such the first argument will be a well formed template call site object and the rest
|
|
||||||
* parameter will contain the substitution values.
|
|
||||||
* @param template A well-formed template string call site representation.
|
|
||||||
* @param substitutions A set of substitution values.
|
|
||||||
*/
|
|
||||||
raw(template: TemplateStringsArray, ...substitutions: any[]): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface String {
|
|
||||||
/**
|
|
||||||
* Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point
|
|
||||||
* value of the UTF-16 encoded code point starting at the string element at position pos in
|
|
||||||
* the String resulting from converting this object to a String.
|
|
||||||
* If there is no element at that position, the result is undefined.
|
|
||||||
* If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos.
|
|
||||||
*/
|
|
||||||
codePointAt(pos: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if searchString appears as a substring of the result of converting this
|
|
||||||
* object to a String, at one or more positions that are
|
|
||||||
* greater than or equal to position; otherwise, returns false.
|
|
||||||
* @param searchString search string
|
|
||||||
* @param position If position is undefined, 0 is assumed, so as to search all of the String.
|
|
||||||
*/
|
|
||||||
includes(searchString: string, position?: number): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the sequence of elements of searchString converted to a String is the
|
|
||||||
* same as the corresponding elements of this object (converted to a String) starting at
|
|
||||||
* endPosition – length(this). Otherwise returns false.
|
|
||||||
*/
|
|
||||||
endsWith(searchString: string, endPosition?: number): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a String value that is made from count copies appended together. If count is 0,
|
|
||||||
* T is the empty String is returned.
|
|
||||||
* @param count number of copies to append
|
|
||||||
*/
|
|
||||||
repeat(count: number): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the sequence of elements of searchString converted to a String is the
|
|
||||||
* same as the corresponding elements of this object (converted to a String) starting at
|
|
||||||
* position. Otherwise returns false.
|
|
||||||
*/
|
|
||||||
startsWith(searchString: string, position?: number): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an <a> HTML anchor element and sets the name attribute to the text value
|
|
||||||
* @param name
|
|
||||||
*/
|
|
||||||
anchor(name: string): string;
|
|
||||||
|
|
||||||
/** Returns a <big> HTML element */
|
|
||||||
big(): string;
|
|
||||||
|
|
||||||
/** Returns a <blink> HTML element */
|
|
||||||
blink(): string;
|
|
||||||
|
|
||||||
/** Returns a <b> HTML element */
|
|
||||||
bold(): string;
|
|
||||||
|
|
||||||
/** Returns a <tt> HTML element */
|
|
||||||
fixed(): string
|
|
||||||
|
|
||||||
/** Returns a <font> HTML element and sets the color attribute value */
|
|
||||||
fontcolor(color: string): string
|
|
||||||
|
|
||||||
/** Returns a <font> HTML element and sets the size attribute value */
|
|
||||||
fontsize(size: number): string;
|
|
||||||
|
|
||||||
/** Returns a <font> HTML element and sets the size attribute value */
|
|
||||||
fontsize(size: string): string;
|
|
||||||
|
|
||||||
/** Returns an <i> HTML element */
|
|
||||||
italics(): string;
|
|
||||||
|
|
||||||
/** Returns an <a> HTML element and sets the href attribute value */
|
|
||||||
link(url: string): string;
|
|
||||||
|
|
||||||
/** Returns a <small> HTML element */
|
|
||||||
small(): string;
|
|
||||||
|
|
||||||
/** Returns a <strike> HTML element */
|
|
||||||
strike(): string;
|
|
||||||
|
|
||||||
/** Returns a <sub> HTML element */
|
|
||||||
sub(): string;
|
|
||||||
|
|
||||||
/** Returns a <sup> HTML element */
|
|
||||||
sup(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shim for an ES6 iterable. Not intended for direct use by user code.
|
|
||||||
*/
|
|
||||||
"_es6-shim iterator_"(): IterableIteratorShim<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ArrayConstructor {
|
|
||||||
/**
|
|
||||||
* Creates an array from an array-like object.
|
|
||||||
* @param arrayLike An array-like object to convert to an array.
|
|
||||||
* @param mapfn A mapping function to call on every element of the array.
|
|
||||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
|
||||||
*/
|
|
||||||
from<T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): Array<U>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an array from an iterable object.
|
|
||||||
* @param iterable An iterable object to convert to an array.
|
|
||||||
* @param mapfn A mapping function to call on every element of the array.
|
|
||||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
|
||||||
*/
|
|
||||||
from<T, U>(iterable: IterableShim<T>, mapfn: (v: T, k: number) => U, thisArg?: any): Array<U>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an array from an array-like object.
|
|
||||||
* @param arrayLike An array-like object to convert to an array.
|
|
||||||
*/
|
|
||||||
from<T>(arrayLike: ArrayLike<T>): Array<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an array from an iterable object.
|
|
||||||
* @param iterable An iterable object to convert to an array.
|
|
||||||
*/
|
|
||||||
from<T>(iterable: IterableShim<T>): Array<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new array from a set of elements.
|
|
||||||
* @param items A set of elements to include in the new array object.
|
|
||||||
*/
|
|
||||||
of<T>(...items: T[]): Array<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Array<T> {
|
|
||||||
/**
|
|
||||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
|
||||||
* otherwise.
|
|
||||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
|
||||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
|
||||||
* immediately returns that element value. Otherwise, find returns undefined.
|
|
||||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
|
||||||
* predicate. If it is not provided, undefined is used instead.
|
|
||||||
*/
|
|
||||||
find(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): T;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the index of the first element in the array where predicate is true, and undefined
|
|
||||||
* otherwise.
|
|
||||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
|
||||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
|
||||||
* immediately returns that element value. Otherwise, find returns undefined.
|
|
||||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
|
||||||
* predicate. If it is not provided, undefined is used instead.
|
|
||||||
*/
|
|
||||||
findIndex(predicate: (value: T) => boolean, thisArg?: any): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the this object after filling the section identified by start and end with value
|
|
||||||
* @param value value to fill array section with
|
|
||||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
|
||||||
* length+start where length is the length of the array.
|
|
||||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
|
||||||
* length+end.
|
|
||||||
*/
|
|
||||||
fill(value: T, start?: number, end?: number): T[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the this object after copying a section of the array identified by start and end
|
|
||||||
* to the same array starting at position target
|
|
||||||
* @param target If target is negative, it is treated as length+target where length is the
|
|
||||||
* length of the array.
|
|
||||||
* @param start If start is negative, it is treated as length+start. If end is negative, it
|
|
||||||
* is treated as length+end.
|
|
||||||
* @param end If not specified, length of the this object is used as its default value.
|
|
||||||
*/
|
|
||||||
copyWithin(target: number, start: number, end?: number): T[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of key, value pairs for every entry in the array
|
|
||||||
*/
|
|
||||||
entries(): IterableIteratorShim<[number, T]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an list of keys in the array
|
|
||||||
*/
|
|
||||||
keys(): IterableIteratorShim<number>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an list of values in the array
|
|
||||||
*/
|
|
||||||
values(): IterableIteratorShim<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shim for an ES6 iterable. Not intended for direct use by user code.
|
|
||||||
*/
|
|
||||||
"_es6-shim iterator_"(): IterableIteratorShim<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface NumberConstructor {
|
|
||||||
/**
|
|
||||||
* The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1
|
|
||||||
* that is representable as a Number value, which is approximately:
|
|
||||||
* 2.2204460492503130808472633361816 x 10−16.
|
|
||||||
*/
|
|
||||||
EPSILON: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if passed value is finite.
|
|
||||||
* Unlike the global isFininte, Number.isFinite doesn't forcibly convert the parameter to a
|
|
||||||
* number. Only finite values of the type number, result in true.
|
|
||||||
* @param number A numeric value.
|
|
||||||
*/
|
|
||||||
isFinite(number: number): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the value passed is an integer, false otherwise.
|
|
||||||
* @param number A numeric value.
|
|
||||||
*/
|
|
||||||
isInteger(number: number): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a Boolean value that indicates whether a value is the reserved value NaN (not a
|
|
||||||
* number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter
|
|
||||||
* to a number. Only values of the type number, that are also NaN, result in true.
|
|
||||||
* @param number A numeric value.
|
|
||||||
*/
|
|
||||||
isNaN(number: number): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the value passed is a safe integer.
|
|
||||||
* @param number A numeric value.
|
|
||||||
*/
|
|
||||||
isSafeInteger(number: number): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the largest integer n such that n and n + 1 are both exactly representable as
|
|
||||||
* a Number value.
|
|
||||||
* The value of Number.MIN_SAFE_INTEGER is 9007199254740991 2^53 − 1.
|
|
||||||
*/
|
|
||||||
MAX_SAFE_INTEGER: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the smallest integer n such that n and n − 1 are both exactly representable as
|
|
||||||
* a Number value.
|
|
||||||
* The value of Number.MIN_SAFE_INTEGER is −9007199254740991 (−(2^53 − 1)).
|
|
||||||
*/
|
|
||||||
MIN_SAFE_INTEGER: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a string to a floating-point number.
|
|
||||||
* @param string A string that contains a floating-point number.
|
|
||||||
*/
|
|
||||||
parseFloat(string: string): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts A string to an integer.
|
|
||||||
* @param s A string to convert into a number.
|
|
||||||
* @param radix A value between 2 and 36 that specifies the base of the number in numString.
|
|
||||||
* If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.
|
|
||||||
* All other strings are considered decimal.
|
|
||||||
*/
|
|
||||||
parseInt(string: string, radix?: number): number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ObjectConstructor {
|
|
||||||
/**
|
|
||||||
* Copy the values of all of the enumerable own properties from one or more source objects to a
|
|
||||||
* target object. Returns the target object.
|
|
||||||
* @param target The target object to copy to.
|
|
||||||
* @param sources One or more source objects to copy properties from.
|
|
||||||
*/
|
|
||||||
assign(target: any, ...sources: any[]): any;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the values are the same value, false otherwise.
|
|
||||||
* @param value1 The first value.
|
|
||||||
* @param value2 The second value.
|
|
||||||
*/
|
|
||||||
is(value1: any, value2: any): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the prototype of a specified object o to object proto or null. Returns the object o.
|
|
||||||
* @param o The object to change its prototype.
|
|
||||||
* @param proto The value of the new prototype or null.
|
|
||||||
* @remarks Requires `__proto__` support.
|
|
||||||
*/
|
|
||||||
setPrototypeOf(o: any, proto: any): any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RegExp {
|
|
||||||
/**
|
|
||||||
* Returns a string indicating the flags of the regular expression in question. This field is read-only.
|
|
||||||
* The characters in this string are sequenced and concatenated in the following order:
|
|
||||||
*
|
|
||||||
* - "g" for global
|
|
||||||
* - "i" for ignoreCase
|
|
||||||
* - "m" for multiline
|
|
||||||
* - "u" for unicode
|
|
||||||
* - "y" for sticky
|
|
||||||
*
|
|
||||||
* If no flags are set, the value is the empty string.
|
|
||||||
*/
|
|
||||||
flags: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Math {
|
|
||||||
/**
|
|
||||||
* Returns the number of leading zero bits in the 32-bit binary representation of a number.
|
|
||||||
* @param x A numeric expression.
|
|
||||||
*/
|
|
||||||
clz32(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the result of 32-bit multiplication of two numbers.
|
|
||||||
* @param x First number
|
|
||||||
* @param y Second number
|
|
||||||
*/
|
|
||||||
imul(x: number, y: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the sign of the x, indicating whether x is positive, negative or zero.
|
|
||||||
* @param x The numeric expression to test
|
|
||||||
*/
|
|
||||||
sign(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the base 10 logarithm of a number.
|
|
||||||
* @param x A numeric expression.
|
|
||||||
*/
|
|
||||||
log10(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the base 2 logarithm of a number.
|
|
||||||
* @param x A numeric expression.
|
|
||||||
*/
|
|
||||||
log2(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the natural logarithm of 1 + x.
|
|
||||||
* @param x A numeric expression.
|
|
||||||
*/
|
|
||||||
log1p(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the result of (e^x - 1) of x (e raised to the power of x, where e is the base of
|
|
||||||
* the natural logarithms).
|
|
||||||
* @param x A numeric expression.
|
|
||||||
*/
|
|
||||||
expm1(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the hyperbolic cosine of a number.
|
|
||||||
* @param x A numeric expression that contains an angle measured in radians.
|
|
||||||
*/
|
|
||||||
cosh(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the hyperbolic sine of a number.
|
|
||||||
* @param x A numeric expression that contains an angle measured in radians.
|
|
||||||
*/
|
|
||||||
sinh(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the hyperbolic tangent of a number.
|
|
||||||
* @param x A numeric expression that contains an angle measured in radians.
|
|
||||||
*/
|
|
||||||
tanh(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the inverse hyperbolic cosine of a number.
|
|
||||||
* @param x A numeric expression that contains an angle measured in radians.
|
|
||||||
*/
|
|
||||||
acosh(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the inverse hyperbolic sine of a number.
|
|
||||||
* @param x A numeric expression that contains an angle measured in radians.
|
|
||||||
*/
|
|
||||||
asinh(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the inverse hyperbolic tangent of a number.
|
|
||||||
* @param x A numeric expression that contains an angle measured in radians.
|
|
||||||
*/
|
|
||||||
atanh(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the square root of the sum of squares of its arguments.
|
|
||||||
* @param values Values to compute the square root for.
|
|
||||||
* If no arguments are passed, the result is +0.
|
|
||||||
* If there is only one argument, the result is the absolute value.
|
|
||||||
* If any argument is +Infinity or -Infinity, the result is +Infinity.
|
|
||||||
* If any argument is NaN, the result is NaN.
|
|
||||||
* If all arguments are either +0 or −0, the result is +0.
|
|
||||||
*/
|
|
||||||
hypot(...values: number[]): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the integral part of the a numeric expression, x, removing any fractional digits.
|
|
||||||
* If x is already an integer, the result is x.
|
|
||||||
* @param x A numeric expression.
|
|
||||||
*/
|
|
||||||
trunc(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the nearest single precision float representation of a number.
|
|
||||||
* @param x A numeric expression.
|
|
||||||
*/
|
|
||||||
fround(x: number): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an implementation-dependent approximation to the cube root of number.
|
|
||||||
* @param x A numeric expression.
|
|
||||||
*/
|
|
||||||
cbrt(x: number): number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PromiseLike<T> {
|
|
||||||
/**
|
|
||||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
|
||||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of which ever callback is executed.
|
|
||||||
*/
|
|
||||||
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
|
|
||||||
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the completion of an asynchronous operation
|
|
||||||
*/
|
|
||||||
interface Promise<T> {
|
|
||||||
/**
|
|
||||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
|
||||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of which ever callback is executed.
|
|
||||||
*/
|
|
||||||
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;
|
|
||||||
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attaches a callback for only the rejection of the Promise.
|
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
|
||||||
* @returns A Promise for the completion of the callback.
|
|
||||||
*/
|
|
||||||
catch(onrejected?: (reason: any) => T | PromiseLike<T>): Promise<T>;
|
|
||||||
catch(onrejected?: (reason: any) => void): Promise<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PromiseConstructor {
|
|
||||||
/**
|
|
||||||
* A reference to the prototype.
|
|
||||||
*/
|
|
||||||
prototype: Promise<any>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new Promise.
|
|
||||||
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
|
|
||||||
* a resolve callback used resolve the promise with a value or the result of another promise,
|
|
||||||
* and a reject callback used to reject the promise with a provided reason or error.
|
|
||||||
*/
|
|
||||||
new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
|
||||||
* resolve, or rejected when any Promise is rejected.
|
|
||||||
* @param values An array of Promises.
|
|
||||||
* @returns A new Promise.
|
|
||||||
*/
|
|
||||||
all<T>(values: IterableShim<T | PromiseLike<T>>): Promise<T[]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
|
|
||||||
* or rejected.
|
|
||||||
* @param values An array of Promises.
|
|
||||||
* @returns A new Promise.
|
|
||||||
*/
|
|
||||||
race<T>(values: IterableShim<T | PromiseLike<T>>): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new rejected promise for the provided reason.
|
|
||||||
* @param reason The reason the promise was rejected.
|
|
||||||
* @returns A new rejected Promise.
|
|
||||||
*/
|
|
||||||
reject(reason: any): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new rejected promise for the provided reason.
|
|
||||||
* @param reason The reason the promise was rejected.
|
|
||||||
* @returns A new rejected Promise.
|
|
||||||
*/
|
|
||||||
reject<T>(reason: any): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new resolved promise for the provided value.
|
|
||||||
* @param value A promise.
|
|
||||||
* @returns A promise whose internal state matches the provided promise.
|
|
||||||
*/
|
|
||||||
resolve<T>(value: T | PromiseLike<T>): Promise<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new resolved promise .
|
|
||||||
* @returns A resolved promise.
|
|
||||||
*/
|
|
||||||
resolve(): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var Promise: PromiseConstructor;
|
|
||||||
|
|
||||||
interface Map<K, V> {
|
|
||||||
clear(): void;
|
|
||||||
delete(key: K): boolean;
|
|
||||||
forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg?: any): void;
|
|
||||||
get(key: K): V;
|
|
||||||
has(key: K): boolean;
|
|
||||||
set(key: K, value?: V): Map<K, V>;
|
|
||||||
size: number;
|
|
||||||
entries(): IterableIteratorShim<[K, V]>;
|
|
||||||
keys(): IterableIteratorShim<K>;
|
|
||||||
values(): IterableIteratorShim<V>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface MapConstructor {
|
|
||||||
new <K, V>(): Map<K, V>;
|
|
||||||
new <K, V>(iterable: IterableShim<[K, V]>): Map<K, V>;
|
|
||||||
prototype: Map<any, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var Map: MapConstructor;
|
|
||||||
|
|
||||||
interface Set<T> {
|
|
||||||
add(value: T): Set<T>;
|
|
||||||
clear(): void;
|
|
||||||
delete(value: T): boolean;
|
|
||||||
forEach(callbackfn: (value: T, index: T, set: Set<T>) => void, thisArg?: any): void;
|
|
||||||
has(value: T): boolean;
|
|
||||||
size: number;
|
|
||||||
entries(): IterableIteratorShim<[T, T]>;
|
|
||||||
keys(): IterableIteratorShim<T>;
|
|
||||||
values(): IterableIteratorShim<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SetConstructor {
|
|
||||||
new <T>(): Set<T>;
|
|
||||||
new <T>(iterable: IterableShim<T>): Set<T>;
|
|
||||||
prototype: Set<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var Set: SetConstructor;
|
|
||||||
|
|
||||||
interface WeakMap<K, V> {
|
|
||||||
delete(key: K): boolean;
|
|
||||||
get(key: K): V;
|
|
||||||
has(key: K): boolean;
|
|
||||||
set(key: K, value?: V): WeakMap<K, V>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface WeakMapConstructor {
|
|
||||||
new <K, V>(): WeakMap<K, V>;
|
|
||||||
new <K, V>(iterable: IterableShim<[K, V]>): WeakMap<K, V>;
|
|
||||||
prototype: WeakMap<any, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var WeakMap: WeakMapConstructor;
|
|
||||||
|
|
||||||
interface WeakSet<T> {
|
|
||||||
add(value: T): WeakSet<T>;
|
|
||||||
delete(value: T): boolean;
|
|
||||||
has(value: T): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface WeakSetConstructor {
|
|
||||||
new <T>(): WeakSet<T>;
|
|
||||||
new <T>(iterable: IterableShim<T>): WeakSet<T>;
|
|
||||||
prototype: WeakSet<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var WeakSet: WeakSetConstructor;
|
|
||||||
|
|
||||||
declare namespace Reflect {
|
|
||||||
function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
|
|
||||||
function construct(target: Function, argumentsList: ArrayLike<any>): any;
|
|
||||||
function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
|
|
||||||
function deleteProperty(target: any, propertyKey: PropertyKey): boolean;
|
|
||||||
function enumerate(target: any): IterableIteratorShim<any>;
|
|
||||||
function get(target: any, propertyKey: PropertyKey, receiver?: any): any;
|
|
||||||
function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor;
|
|
||||||
function getPrototypeOf(target: any): any;
|
|
||||||
function has(target: any, propertyKey: PropertyKey): boolean;
|
|
||||||
function isExtensible(target: any): boolean;
|
|
||||||
function ownKeys(target: any): Array<PropertyKey>;
|
|
||||||
function preventExtensions(target: any): boolean;
|
|
||||||
function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean;
|
|
||||||
function setPrototypeOf(target: any, proto: any): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "es6-shim" {
|
|
||||||
var String: StringConstructor;
|
|
||||||
var Array: ArrayConstructor;
|
|
||||||
var Number: NumberConstructor;
|
|
||||||
var Math: Math;
|
|
||||||
var Object: ObjectConstructor;
|
|
||||||
var Map: MapConstructor;
|
|
||||||
var Set: SetConstructor;
|
|
||||||
var WeakMap: WeakMapConstructor;
|
|
||||||
var WeakSet: WeakSetConstructor;
|
|
||||||
var Promise: PromiseConstructor;
|
|
||||||
namespace Reflect {
|
|
||||||
function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
|
|
||||||
function construct(target: Function, argumentsList: ArrayLike<any>): any;
|
|
||||||
function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
|
|
||||||
function deleteProperty(target: any, propertyKey: PropertyKey): boolean;
|
|
||||||
function enumerate(target: any): Iterator<any>;
|
|
||||||
function get(target: any, propertyKey: PropertyKey, receiver?: any): any;
|
|
||||||
function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor;
|
|
||||||
function getPrototypeOf(target: any): any;
|
|
||||||
function has(target: any, propertyKey: PropertyKey): boolean;
|
|
||||||
function isExtensible(target: any): boolean;
|
|
||||||
function ownKeys(target: any): Array<PropertyKey>;
|
|
||||||
function preventExtensions(target: any): boolean;
|
|
||||||
function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean;
|
|
||||||
function setPrototypeOf(target: any, proto: any): boolean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2
samples/angular/MusicStore/typings/tsd.d.ts
vendored
2
samples/angular/MusicStore/typings/tsd.d.ts
vendored
@@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
/// <reference path="es6-shim/es6-shim.d.ts" />
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is a workaround for angular2-universal-preview version 0.84.2 relying on the declaration of
|
|
||||||
// Node's 'url' module. Ideally it would not declare dependencies on Node APIs except where it also supplies
|
|
||||||
// the definitions itself.
|
|
||||||
|
|
||||||
declare module 'url' {
|
|
||||||
export interface Url {}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
body {
|
|
||||||
padding-top: 50px;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
@base: #f938ab;
|
|
||||||
|
|
||||||
.box-shadow(@style, @c) when (iscolor(@c)) {
|
|
||||||
-webkit-box-shadow: @style @c;
|
|
||||||
box-shadow: @style @c;
|
|
||||||
}
|
|
||||||
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
|
|
||||||
.box-shadow(@style, rgba(0, 0, 0, @alpha));
|
|
||||||
}
|
|
||||||
.box {
|
|
||||||
color: saturate(@base, 5%);
|
|
||||||
border-color: lighten(@base, 30%);
|
|
||||||
div { .box-shadow(0 0 5px, 30%) }
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 248 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,8 +0,0 @@
|
|||||||
import { bootstrap } from 'angular2/platform/browser';
|
|
||||||
import { FormBuilder } from 'angular2/common';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import { Http, HTTP_PROVIDERS } from 'angular2/http';
|
|
||||||
import { CACHE_PRIMED_HTTP_PROVIDERS } from 'angular2-aspnet';
|
|
||||||
import { App } from './components/app/app';
|
|
||||||
|
|
||||||
bootstrap(App, [router.ROUTER_BINDINGS, HTTP_PROVIDERS, CACHE_PRIMED_HTTP_PROVIDERS, FormBuilder]);
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import 'angular2-universal/polyfills';
|
|
||||||
import { FormBuilder } from 'angular2/common';
|
|
||||||
import * as ngCore from 'angular2/core';
|
|
||||||
import * as ngRouter from 'angular2/router';
|
|
||||||
import * as ngUniversal from 'angular2-universal';
|
|
||||||
import { BASE_URL, ORIGIN_URL, REQUEST_URL } from 'angular2-universal/common';
|
|
||||||
import { App } from './components/app/app';
|
|
||||||
|
|
||||||
export default function (params: any): Promise<{ html: string, globals?: any }> {
|
|
||||||
const serverBindings = [
|
|
||||||
ngCore.provide(BASE_URL, { useValue: '/' }),
|
|
||||||
ngCore.provide(ORIGIN_URL, { useValue: params.origin }),
|
|
||||||
ngCore.provide(REQUEST_URL, { useValue: params.url }),
|
|
||||||
ngUniversal.NODE_HTTP_PROVIDERS,
|
|
||||||
ngUniversal.NODE_ROUTER_PROVIDERS,
|
|
||||||
FormBuilder
|
|
||||||
];
|
|
||||||
|
|
||||||
return ngUniversal.bootloader({
|
|
||||||
directives: [App],
|
|
||||||
providers: serverBindings,
|
|
||||||
async: true,
|
|
||||||
preboot: false,
|
|
||||||
// TODO: Render just the <app> component instead of wrapping it inside an extra HTML document
|
|
||||||
// Waiting on https://github.com/angular/universal/issues/347
|
|
||||||
template: '<!DOCTYPE html>\n<html><head></head><body><app></app></body></html>'
|
|
||||||
}).serializeApplication().then(html => {
|
|
||||||
return { html };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<h1>Store Manager</h1>
|
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import { AlbumsList } from '../albums-list/albums-list';
|
|
||||||
import { AlbumDetails } from '../album-details/album-details';
|
|
||||||
import { AlbumEdit } from '../album-edit/album-edit';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'admin-home',
|
|
||||||
templateUrl: './ng-app/components/admin/admin-home/admin-home.html',
|
|
||||||
directives: [router.ROUTER_DIRECTIVES]
|
|
||||||
})
|
|
||||||
@router.RouteConfig([
|
|
||||||
{ path: 'albums', name: 'Albums', component: AlbumsList },
|
|
||||||
{ path: 'album/details/:albumId', name: 'AlbumDetails', component: AlbumDetails },
|
|
||||||
{ path: 'album/edit/:albumId', name: 'AlbumEdit', component: AlbumEdit }
|
|
||||||
])
|
|
||||||
export class AdminHome {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<div class="modal fade">
|
|
||||||
<div class="modal-dialog" *ngIf="album">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
||||||
<h4 class="modal-title">Delete {{ album.Title }}</h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>Really delete <strong>{{ album.Title }}</strong> by <strong>{{ album.Artist.Name }}</strong>?</p>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-danger">Confirm Delete</button>
|
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div><!-- /.modal-content -->
|
|
||||||
</div><!-- /.modal-dialog -->
|
|
||||||
</div><!-- /.modal -->
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'album-delete-prompt',
|
|
||||||
templateUrl: './ng-app/components/admin/album-delete-prompt/album-delete-prompt.html'
|
|
||||||
})
|
|
||||||
export class AlbumDeletePrompt {
|
|
||||||
public album: models.Album;
|
|
||||||
|
|
||||||
constructor(@ng.Inject(ng.ElementRef) private _elementRef: ng.ElementRef) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public show(album: models.Album) {
|
|
||||||
this.album = album;
|
|
||||||
|
|
||||||
// Consider rewriting this using Angular's "Renderer" API so as to avoid direct DOM access
|
|
||||||
(<any>window).jQuery(".modal", this._elementRef.nativeElement).modal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
<h2>Album <small>Details</small></h2>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<form class="form-horizontal" role="form" *ngIf="albumData">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label">Artist</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="form-control-static">{{ albumData.Artist.Name }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label">Genre</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="form-control-static">{{ albumData.Genre.Name }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label">Title</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="form-control-static">{{ albumData.Title }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label">Price</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="form-control-static">{{ albumData.Price | currency:'USD':true }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label">Album Art URL</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="form-control-static">{{ albumData.AlbumArtUrl }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label">Album Art</label>
|
|
||||||
<div class="col-md-10">
|
|
||||||
<img alt="{{ albumData.Title }}" src="{{ albumData.AlbumArtUrl }}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-md-offset-2 col-md-10">
|
|
||||||
<a class="btn btn-primary" [routerLink]="['/Admin/AlbumEdit', { albumId: albumData.AlbumId }]">Edit</a>
|
|
||||||
<button type="button" class="btn btn-danger" (click)="deleteprompt.show(albumData)">Delete</button>
|
|
||||||
<a class="btn btn-default" [routerLink]="['/Admin/Albums']">Back to List</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<album-delete-prompt #deleteprompt></album-delete-prompt>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
import { Http, HTTP_BINDINGS } from 'angular2/http';
|
|
||||||
import { AlbumDeletePrompt } from '../album-delete-prompt/album-delete-prompt';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'album-details',
|
|
||||||
templateUrl: './ng-app/components/admin/album-details/album-details.html',
|
|
||||||
directives: [router.ROUTER_DIRECTIVES, AlbumDeletePrompt]
|
|
||||||
})
|
|
||||||
export class AlbumDetails {
|
|
||||||
public albumData: models.Album;
|
|
||||||
|
|
||||||
constructor(http: Http, routeParam: router.RouteParams) {
|
|
||||||
http.get('/api/albums/' + routeParam.params['albumId']).subscribe(result => {
|
|
||||||
this.albumData = result.json();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
<h2>Album <small>Edit</small></h2>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<form class="form-horizontal" [ngFormModel]="form" (ngSubmit)="onSubmitModelBased()">
|
|
||||||
<form-field label="Artist" [validate]="form.controls.ArtistId">
|
|
||||||
<select class="form-control" ngControl="ArtistId">
|
|
||||||
<option value="0">-- choose Artist --</option>
|
|
||||||
<option *ngFor="#artist of artists" [value]="artist.ArtistId">{{ artist.Name }}</option>
|
|
||||||
</select>
|
|
||||||
</form-field>
|
|
||||||
|
|
||||||
<form-field label="Genre" [validate]="form.controls.GenreId">
|
|
||||||
<select class="form-control" ngControl="GenreId">
|
|
||||||
<option value="0">-- choose Genre --</option>
|
|
||||||
<option *ngFor="#genre of genres" [value]="genre.GenreId">{{ genre.Name }}</option>
|
|
||||||
</select>
|
|
||||||
</form-field>
|
|
||||||
|
|
||||||
<form-field label="Title" [validate]="form.controls.Title">
|
|
||||||
<input class="form-control" type="text" ngControl="Title">
|
|
||||||
</form-field>
|
|
||||||
|
|
||||||
<form-field label="Price" [validate]="form.controls.Price">
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-addon">$</span>
|
|
||||||
<input class="form-control" type="text" ngControl="Price">
|
|
||||||
</div>
|
|
||||||
</form-field>
|
|
||||||
|
|
||||||
<form-field label="Album Art URL" [validate]="form.controls.AlbumArtUrl">
|
|
||||||
<input class="form-control" ngControl="AlbumArtUrl">
|
|
||||||
</form-field>
|
|
||||||
|
|
||||||
<form-field label="Album Art">
|
|
||||||
<img src="{{ form.controls.AlbumArtUrl.value }}">
|
|
||||||
</form-field>
|
|
||||||
|
|
||||||
<form-field>
|
|
||||||
<div *ngIf="changesSaved" class="alert alert-success"><b>Done!</b> Your changes were saved.</div>
|
|
||||||
<div *ngFor="#errorMessage of formErrors" class="alert alert-danger">{{ errorMessage }}</div>
|
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
|
||||||
<button type="button" class="btn btn-danger" (click)="deleteprompt.show(originalAlbum)">Delete</button>
|
|
||||||
<a class="btn btn-default" [routerLink]="['/Admin/Albums']">Back to List</a>
|
|
||||||
</form-field>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<album-delete-prompt #deleteprompt></album-delete-prompt>
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { Control, ControlGroup, FormBuilder, Validators, FORM_DIRECTIVES } from 'angular2/common';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
import { Http, HTTP_BINDINGS, Headers, Response } from 'angular2/http';
|
|
||||||
import { AlbumDeletePrompt } from '../album-delete-prompt/album-delete-prompt';
|
|
||||||
import { FormField } from '../form-field/form-field';
|
|
||||||
import * as AspNet from 'angular2-aspnet';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'album-edit',
|
|
||||||
templateUrl: './ng-app/components/admin/album-edit/album-edit.html',
|
|
||||||
directives: [router.ROUTER_DIRECTIVES, AlbumDeletePrompt, FormField, FORM_DIRECTIVES]
|
|
||||||
})
|
|
||||||
export class AlbumEdit {
|
|
||||||
public form: ControlGroup;
|
|
||||||
public artists: models.Artist[];
|
|
||||||
public genres: models.Genre[];
|
|
||||||
public originalAlbum: models.Album;
|
|
||||||
public changesSaved: boolean;
|
|
||||||
public formErrors: string[] = [];
|
|
||||||
|
|
||||||
private _http: Http;
|
|
||||||
|
|
||||||
constructor(fb: FormBuilder, http: Http, routeParam: router.RouteParams) {
|
|
||||||
this._http = http;
|
|
||||||
|
|
||||||
var albumId = parseInt(routeParam.params['albumId']);
|
|
||||||
http.get('/api/albums/' + albumId).subscribe(result => {
|
|
||||||
var json = result.json();
|
|
||||||
this.originalAlbum = json;
|
|
||||||
(<Control>this.form.controls['Title']).updateValue(json.Title);
|
|
||||||
(<Control>this.form.controls['Price']).updateValue(json.Price);
|
|
||||||
(<Control>this.form.controls['ArtistId']).updateValue(json.ArtistId);
|
|
||||||
(<Control>this.form.controls['GenreId']).updateValue(json.GenreId);
|
|
||||||
(<Control>this.form.controls['AlbumArtUrl']).updateValue(json.AlbumArtUrl);
|
|
||||||
});
|
|
||||||
|
|
||||||
http.get('/api/artists/lookup').subscribe(result => {
|
|
||||||
this.artists = result.json();
|
|
||||||
});
|
|
||||||
|
|
||||||
http.get('/api/genres/genre-lookup').subscribe(result => {
|
|
||||||
this.genres = result.json();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.form = fb.group(<any>{
|
|
||||||
AlbumId: fb.control(albumId),
|
|
||||||
ArtistId: fb.control(0, Validators.required),
|
|
||||||
GenreId: fb.control(0, Validators.required),
|
|
||||||
Title: fb.control('', Validators.required),
|
|
||||||
Price: fb.control('', Validators.compose([Validators.required, AlbumEdit._validatePrice])),
|
|
||||||
AlbumArtUrl: fb.control('', Validators.required)
|
|
||||||
});
|
|
||||||
|
|
||||||
this.form.valueChanges.subscribe(() => {
|
|
||||||
this.changesSaved = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onSubmitModelBased() {
|
|
||||||
// Force all fields to show any validation errors even if they haven't been touched
|
|
||||||
Object.keys(this.form.controls).forEach(controlName => {
|
|
||||||
this.form.controls[controlName].markAsTouched();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.form.valid) {
|
|
||||||
var controls = this.form.controls;
|
|
||||||
var albumId = this.originalAlbum.AlbumId;
|
|
||||||
|
|
||||||
this._putJson(`/api/albums/${ albumId }/update`, this.form.value).subscribe(successResponse => {
|
|
||||||
this.changesSaved = true;
|
|
||||||
}, errorResponse => {
|
|
||||||
AspNet.Validation.showValidationErrors(errorResponse, this.form);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static _validatePrice(control: Control): { [key: string]: boolean } {
|
|
||||||
return /^\d+\.\d+$/.test(control.value) ? null : { Price: true };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need feedback on whether this really is the easiest way to PUT some JSON
|
|
||||||
private _putJson(url: string, body: any): Observable<Response> {
|
|
||||||
return this._http.put(url, JSON.stringify(body), {
|
|
||||||
headers: new Headers({ 'Content-Type': 'application/json' })
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private ngDoCheck() {
|
|
||||||
this.formErrors = this.form.dirty ? Object.keys(this.form.errors || {}) : [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<h2>Albums</h2>
|
|
||||||
|
|
||||||
<album-delete-prompt #deleteprompt></album-delete-prompt>
|
|
||||||
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th><a>Genre</a></th>
|
|
||||||
<th><a>Artist</a></th>
|
|
||||||
<th><a (click)="sortBy('Title')">Title</a></th>
|
|
||||||
<th><a (click)="sortBy('Price')">Price</a></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr *ngFor="#row of rows">
|
|
||||||
<td>{{ row.Genre.Name }}</td>
|
|
||||||
<td>{{ row.Artist.Name }}</td>
|
|
||||||
<td>{{ row.Title }}</td>
|
|
||||||
<td>{{ row.Price | currency:'USD':true }}</td>
|
|
||||||
<td>
|
|
||||||
<div class="btn-group btn-group-xs">
|
|
||||||
<a class="btn btn-default" [routerLink]="['/Admin/AlbumDetails', { albumId: row.AlbumId }]">Details</a>
|
|
||||||
<a class="btn btn-default" [routerLink]="['/Admin/AlbumEdit', { albumId: row.AlbumId }]">Edit</a>
|
|
||||||
<a class="btn btn-default" (click)="deleteprompt.show(row)">Delete</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div class="btn-group">
|
|
||||||
<button class="btn btn-default" [disabled]="!canGoBack" (click)="goToPage(1)">First</button>
|
|
||||||
<button class="btn btn-default" [disabled]="!canGoBack" (click)="goToPage(pageIndex - 1)">Previous</button>
|
|
||||||
<button class="btn" *ngFor="#page of pageLinks"
|
|
||||||
[ngClass]="{ 'btn-info': page.isCurrent, 'btn-default': !page.isCurrent }"
|
|
||||||
(click)="goToPage(page.index)">
|
|
||||||
{{ page.text }}
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-default" [disabled]="!canGoForward" (click)="goToPage(pageIndex + 1)">Next</button>
|
|
||||||
<button class="btn btn-default" [disabled]="!canGoForward" (click)="goToLast()">Last</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>{{ totalCount }} total albums</p>
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import { Http, HTTP_BINDINGS } from 'angular2/http';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
import { AlbumDeletePrompt } from '../album-delete-prompt/album-delete-prompt';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'albums-list',
|
|
||||||
templateUrl: './ng-app/components/admin/albums-list/albums-list.html',
|
|
||||||
directives: [router.ROUTER_DIRECTIVES, AlbumDeletePrompt]
|
|
||||||
})
|
|
||||||
export class AlbumsList {
|
|
||||||
public rows: models.Album[];
|
|
||||||
public canGoBack: boolean;
|
|
||||||
public canGoForward: boolean;
|
|
||||||
public pageLinks: any[];
|
|
||||||
public totalCount: number;
|
|
||||||
public get pageIndex() {
|
|
||||||
return this._pageIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _http: Http;
|
|
||||||
private _pageIndex = 1;
|
|
||||||
private _sortBy = "Title";
|
|
||||||
private _sortByDesc = false;
|
|
||||||
|
|
||||||
constructor(http: Http) {
|
|
||||||
this._http = http;
|
|
||||||
this.refreshData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public sortBy(col: string) {
|
|
||||||
this._sortByDesc = col === this._sortBy ? !this._sortByDesc : false;
|
|
||||||
this._sortBy = col;
|
|
||||||
this.refreshData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public goToPage(pageIndex: number) {
|
|
||||||
this._pageIndex = pageIndex;
|
|
||||||
this.refreshData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public goToLast() {
|
|
||||||
this.goToPage(this.pageLinks[this.pageLinks.length - 1].index);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshData() {
|
|
||||||
var sortBy = this._sortBy + (this._sortByDesc ? ' DESC' : '');
|
|
||||||
this._http.get(`/api/albums?page=${ this._pageIndex }&pageSize=50&sortBy=${ sortBy }`).subscribe(result => {
|
|
||||||
var json = result.json();
|
|
||||||
this.rows = json.Data;
|
|
||||||
|
|
||||||
var numPages = Math.ceil(json.TotalCount / json.PageSize);
|
|
||||||
this.pageLinks = [];
|
|
||||||
for (var i = 1; i <= numPages; i++) {
|
|
||||||
this.pageLinks.push({
|
|
||||||
index: i,
|
|
||||||
text: i.toString(),
|
|
||||||
isCurrent: i === json.Page
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.canGoBack = this.pageLinks.length && !this.pageLinks[0].isCurrent;
|
|
||||||
this.canGoForward = this.pageLinks.length && !this.pageLinks[this.pageLinks.length - 1].isCurrent;
|
|
||||||
this.totalCount = json.TotalCount;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<div class="form-group" [class.has-error]="errorMessages.length">
|
|
||||||
<label class="col-md-2 control-label">{{ label }}</label>
|
|
||||||
<div class="col-md-5">
|
|
||||||
<ng-content></ng-content>
|
|
||||||
<div class="alert alert-danger" role="alert" *ngIf="errorMessages.length">
|
|
||||||
<p *ngFor="#message of errorMessages">{{ message }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import { AbstractControl } from 'angular2/common';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'form-field',
|
|
||||||
properties: ['label', 'validate'],
|
|
||||||
templateUrl: './ng-app/components/admin/form-field/form-field.html'
|
|
||||||
})
|
|
||||||
export class FormField {
|
|
||||||
public errorMessages: string[] = [];
|
|
||||||
private validate: AbstractControl;
|
|
||||||
|
|
||||||
private ngDoCheck() {
|
|
||||||
var errors = (this.validate && this.validate.dirty && this.validate.errors) || {};
|
|
||||||
this.errorMessages = Object.keys(errors).map(key => {
|
|
||||||
return 'Error: ' + key;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<a class="navbar-brand" [routerLink]="['/Home']">Music Store</a>
|
|
||||||
</div>
|
|
||||||
<div class="collapse navbar-collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li><a [routerLink]="['/Home']">Home</a></li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown">Store <b class="caret"></b></a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li *ngFor="#genre of genres">
|
|
||||||
<a title="{{ genre.Description }}" [routerLink]="['/Genre', { genreId: genre.GenreId }]">
|
|
||||||
{{ genre.Name }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<li>
|
|
||||||
<a [routerLink]="['/GenresList']">More…</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><a [routerLink]="['/Admin/Albums']">Admin</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<div class="container body-content">
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
</div>
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import { Http, HTTP_BINDINGS } from 'angular2/http';
|
|
||||||
import { Home } from '../public/home/home';
|
|
||||||
import { AlbumDetails } from '../public/album-details/album-details';
|
|
||||||
import { GenreContents } from '../public/genre-contents/genre-contents';
|
|
||||||
import { GenresList } from '../public/genres-list/genres-list';
|
|
||||||
import { AdminHome } from '../admin/admin-home/admin-home';
|
|
||||||
import * as models from '../../models/models';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'app',
|
|
||||||
templateUrl: './ng-app/components/app/app.html',
|
|
||||||
styleUrls: ['./ng-app/components/app/app.css'],
|
|
||||||
directives: [router.ROUTER_DIRECTIVES]
|
|
||||||
})
|
|
||||||
@router.RouteConfig([
|
|
||||||
{ path: '/', component: Home, name: 'Home' },
|
|
||||||
{ path: '/album/:albumId', component: AlbumDetails, name: 'Album' },
|
|
||||||
{ path: '/genre/:genreId', component: GenreContents, name: 'Genre' },
|
|
||||||
{ path: '/genres', component: GenresList, name: 'GenresList' },
|
|
||||||
{ path: '/admin/...', component: AdminHome, name: 'Admin' }
|
|
||||||
])
|
|
||||||
export class App {
|
|
||||||
public genres: models.Genre[];
|
|
||||||
|
|
||||||
constructor(http: Http) {
|
|
||||||
http.get('/api/genres/menu').subscribe(result => {
|
|
||||||
this.genres = result.json();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<div *ngIf="albumData">
|
|
||||||
<h2>{{ albumData.Title }}</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<img alt="{{ albumData.Title }}" src="{{ albumData.AlbumArtUrl }}">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div id="album-details">
|
|
||||||
<p>
|
|
||||||
<em>Genre:</em>
|
|
||||||
{{ albumData.Genre.Name }}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<em>Artist:</em>
|
|
||||||
{{ albumData.Artist.Name }}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<em>Price:</em>
|
|
||||||
{{ albumData.Price | currency:'USD':true }}
|
|
||||||
</p>
|
|
||||||
<p class="button">
|
|
||||||
<!-- TODO: Shopping cart functionality -->
|
|
||||||
Add to cart
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import { Http } from 'angular2/http';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'album-details',
|
|
||||||
templateUrl: './ng-app/components/public/album-details/album-details.html'
|
|
||||||
})
|
|
||||||
export class AlbumDetails {
|
|
||||||
public albumData: models.Album;
|
|
||||||
|
|
||||||
constructor(http: Http, routeParam: router.RouteParams) {
|
|
||||||
http.get('/api/albums/' + routeParam.params['albumId']).subscribe(result => {
|
|
||||||
this.albumData = result.json();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<a [routerLink]="['/Album', { albumId: albumData.AlbumId }]">
|
|
||||||
<img alt="{{ albumData.Title }}" src="{{ albumData.AlbumArtUrl }}">
|
|
||||||
<h4>{{ albumData.Title }}</h4>
|
|
||||||
</a>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'album-tile',
|
|
||||||
properties: ['albumData'],
|
|
||||||
templateUrl: './ng-app/components/public/album-tile/album-tile.html',
|
|
||||||
directives: [router.ROUTER_DIRECTIVES]
|
|
||||||
})
|
|
||||||
export class AlbumTile {
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<h3>Albums</h3>
|
|
||||||
|
|
||||||
<ul class="list-unstyled">
|
|
||||||
<li *ngFor="#album of albums" class="col-lg-2 col-md-2 col-sm-2 col-xs-4 container">
|
|
||||||
<album-tile [albumData]="album"></album-tile>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import { Http } from 'angular2/http';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
import { AlbumTile } from '../album-tile/album-tile';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'genre-contents',
|
|
||||||
templateUrl: './ng-app/components/public/genre-contents/genre-contents.html',
|
|
||||||
directives: [AlbumTile]
|
|
||||||
})
|
|
||||||
export class GenreContents {
|
|
||||||
public albums: models.Album[];
|
|
||||||
|
|
||||||
constructor(http: Http, routeParam: router.RouteParams) {
|
|
||||||
http.get(`/api/genres/${ routeParam.params['genreId'] }/albums`).subscribe(result => {
|
|
||||||
this.albums = result.json();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<h3>Browse Genres</h3>
|
|
||||||
|
|
||||||
<p *ngIf="genres">
|
|
||||||
Select from {{ genres.length }} genres:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul class="list-group">
|
|
||||||
<li *ngFor="#genre of genres" class="list-group-item">
|
|
||||||
<a title="{{genre.Description}}" [routerLink]="['/Genre', { genreId: genre.GenreId }]">
|
|
||||||
{{ genre.Name }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import * as router from 'angular2/router';
|
|
||||||
import { Http } from 'angular2/http';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'genres-list',
|
|
||||||
templateUrl: './ng-app/components/public/genres-list/genres-list.html',
|
|
||||||
directives: [router.ROUTER_DIRECTIVES]
|
|
||||||
})
|
|
||||||
export class GenresList {
|
|
||||||
public genres: models.Genre[];
|
|
||||||
|
|
||||||
constructor(http: Http) {
|
|
||||||
http.get('/api/genres').subscribe(result => {
|
|
||||||
this.genres = result.json();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<div class="jumbotron">
|
|
||||||
<h1>MVC Music Store</h1>
|
|
||||||
<img src="/Images/home-showcase.png">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="row list-unstyled" id="album-list">
|
|
||||||
<li *ngFor="#album of mostPopular" class="col-lg-2 col-md-2 col-sm-2 col-xs-4 container">
|
|
||||||
<album-tile [albumData]="album"></album-tile>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import * as ng from 'angular2/core';
|
|
||||||
import { Http } from 'angular2/http';
|
|
||||||
import { AlbumTile } from '../album-tile/album-tile';
|
|
||||||
import * as models from '../../../models/models';
|
|
||||||
|
|
||||||
@ng.Component({
|
|
||||||
selector: 'home',
|
|
||||||
templateUrl: './ng-app/components/public/home/home.html',
|
|
||||||
directives: [AlbumTile]
|
|
||||||
})
|
|
||||||
export class Home {
|
|
||||||
public mostPopular: models.Album[];
|
|
||||||
|
|
||||||
constructor(http: Http) {
|
|
||||||
http.get('/api/albums/mostPopular').subscribe(result => {
|
|
||||||
this.mostPopular = result.json();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
export interface Album {
|
|
||||||
AlbumId: number;
|
|
||||||
Title: string;
|
|
||||||
AlbumArtUrl: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Genre {
|
|
||||||
GenreId: number;
|
|
||||||
Name: string;
|
|
||||||
Description: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Artist {
|
|
||||||
ArtistId: number;
|
|
||||||
Name: string;
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
System.config({
|
|
||||||
defaultJSExtensions: true
|
|
||||||
});
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<system.webServer>
|
|
||||||
<handlers>
|
|
||||||
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
|
|
||||||
</handlers>
|
|
||||||
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" forwardWindowsAuthToken="false" startupTimeLimit="3600" />
|
|
||||||
</system.webServer>
|
|
||||||
</configuration>
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<Import Project="..\..\..\build\dependencies.props" />
|
<Import Project="..\..\..\build\common.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<OutputType>exe</OutputType>
|
<OutputType>exe</OutputType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.NodeServices;
|
using Microsoft.AspNetCore.NodeServices;
|
||||||
|
using Microsoft.AspNetCore.SpaServices.Prerendering;
|
||||||
|
|
||||||
namespace NodeServicesExamples.Controllers
|
namespace NodeServicesExamples.Controllers
|
||||||
{
|
{
|
||||||
@@ -34,6 +35,20 @@ namespace NodeServicesExamples.Controllers
|
|||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> Prerendering([FromServices] ISpaPrerenderer prerenderer)
|
||||||
|
{
|
||||||
|
var result = await prerenderer.RenderToString("./Node/prerenderPage");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(result.RedirectUrl))
|
||||||
|
{
|
||||||
|
return Redirect(result.RedirectUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewData["PrerenderedHtml"] = result.Html;
|
||||||
|
ViewData["PrerenderedGlobals"] = result.CreateGlobalsAssignmentScript();
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
public IActionResult Error()
|
public IActionResult Error()
|
||||||
{
|
{
|
||||||
return View("~/Views/Shared/Error.cshtml");
|
return View("~/Views/Shared/Error.cshtml");
|
||||||
|
|||||||
14
samples/misc/NodeServicesExamples/Node/prerenderPage.js
Normal file
14
samples/misc/NodeServicesExamples/Node/prerenderPage.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
var createServerRenderer = require('aspnet-prerendering').createServerRenderer;
|
||||||
|
|
||||||
|
module.exports = createServerRenderer(function(params) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
var message = 'The HTML was returned by the prerendering boot function. '
|
||||||
|
+ 'The boot function received the following params:'
|
||||||
|
+ '<pre>' + JSON.stringify(params, null, 4) + '</pre>';
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
html: '<h3>Hello, world!</h3>' + message,
|
||||||
|
globals: { sampleData: { nodeVersion: process.version } }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,22 +1,25 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<Import Project="..\..\..\build\dependencies.props" />
|
<Import Project="..\..\..\build\common.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.NodeServices\Microsoft.AspNetCore.NodeServices.csproj" />
|
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.SpaServices\Microsoft.AspNetCore.SpaServices.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(MicrosoftAspNetCoreDiagnosticsPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(MicrosoftAspNetCoreMvcPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace NodeServicesExamples
|
|||||||
|
|
||||||
// Enable Node Services
|
// Enable Node Services
|
||||||
services.AddNodeServices();
|
services.AddNodeServices();
|
||||||
|
services.AddSpaPrerenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
@@ -41,7 +42,6 @@ namespace NodeServicesExamples
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
loggerFactory.AddConsole();
|
|
||||||
app.UseMvc(routes =>
|
app.UseMvc(routes =>
|
||||||
{
|
{
|
||||||
routes.MapRoute(
|
routes.MapRoute(
|
||||||
@@ -53,6 +53,11 @@ namespace NodeServicesExamples
|
|||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var host = new WebHostBuilder()
|
var host = new WebHostBuilder()
|
||||||
|
.ConfigureLogging(factory =>
|
||||||
|
{
|
||||||
|
factory.AddConsole();
|
||||||
|
factory.AddDebug();
|
||||||
|
})
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
|
|||||||
@@ -9,4 +9,5 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a asp-action="ES2015Transpilation">ES2015 transpilation</a></li>
|
<li><a asp-action="ES2015Transpilation">ES2015 transpilation</a></li>
|
||||||
<li><a asp-action="Chart">Server-side chart rendering</a></li>
|
<li><a asp-action="Chart">Server-side chart rendering</a></li>
|
||||||
|
<li><a asp-action="Prerendering">Server-side SPA prerendering</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<h1>Server-side prerendering</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This sample demonstrates how you can invoke a JavaScript module that contains
|
||||||
|
prerendering logic for a Single-Page Application framework.
|
||||||
|
</p>
|
||||||
|
</p>
|
||||||
|
Your prerendering boot function will receive parameters that describe the page
|
||||||
|
being rendered and any data supplied by the .NET code. The return value should be
|
||||||
|
a promise that resolves with data to be injected into the page, such as the
|
||||||
|
rendered HTML and any global data that should be made available to client-side code.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
@Html.Raw(ViewData["PrerenderedHtml"])
|
||||||
|
|
||||||
|
<script>@Html.Raw(ViewData["PrerenderedGlobals"])</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Demonstrates how client-side code can receive data from the prerendering process
|
||||||
|
console.log('Received Node version from prerendering logic: ' + sampleData.nodeVersion);
|
||||||
|
</script>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
"name": "nodeservicesexamples",
|
"name": "nodeservicesexamples",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"aspnet-prerendering": "^2.0.6",
|
||||||
"babel-core": "^6.7.4",
|
"babel-core": "^6.7.4",
|
||||||
"babel-preset-es2015": "^6.6.0",
|
"babel-preset-es2015": "^6.6.0",
|
||||||
"node-chartist": "^1.0.2"
|
"node-chartist": "^1.0.2"
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace Webpack.ActionResults
|
|||||||
{
|
{
|
||||||
var nodeServices = context.HttpContext.RequestServices.GetRequiredService<INodeServices>();
|
var nodeServices = context.HttpContext.RequestServices.GetRequiredService<INodeServices>();
|
||||||
var hostEnv = context.HttpContext.RequestServices.GetRequiredService<IHostingEnvironment>();
|
var hostEnv = context.HttpContext.RequestServices.GetRequiredService<IHostingEnvironment>();
|
||||||
|
var applicationLifetime = context.HttpContext.RequestServices.GetRequiredService<IApplicationLifetime>();
|
||||||
var applicationBasePath = hostEnv.ContentRootPath;
|
var applicationBasePath = hostEnv.ContentRootPath;
|
||||||
var request = context.HttpContext.Request;
|
var request = context.HttpContext.Request;
|
||||||
var response = context.HttpContext.Response;
|
var response = context.HttpContext.Response;
|
||||||
@@ -34,6 +35,7 @@ namespace Webpack.ActionResults
|
|||||||
var prerenderedHtml = await Prerenderer.RenderToString(
|
var prerenderedHtml = await Prerenderer.RenderToString(
|
||||||
applicationBasePath,
|
applicationBasePath,
|
||||||
nodeServices,
|
nodeServices,
|
||||||
|
applicationLifetime.ApplicationStopping,
|
||||||
_moduleExport,
|
_moduleExport,
|
||||||
request.GetEncodedUrl(),
|
request.GetEncodedUrl(),
|
||||||
request.Path + request.QueryString.Value,
|
request.Path + request.QueryString.Value,
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
export default function (params: any): Promise<{ html: string, globals?: any }> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
|
|
||||||
// Here, you could put any logic that synchronously or asynchronously prerenders
|
|
||||||
// your SPA components. For example, see the boot-server.ts files in the AngularSpa
|
|
||||||
// and ReactReduxSpa templates for ways to prerender Angular and React components.
|
|
||||||
//
|
|
||||||
// If you wanted, you could use a property on the 'params.data' object to specify
|
|
||||||
// which SPA component or template to render.
|
|
||||||
|
|
||||||
const html = `
|
|
||||||
<h1>Hello</h1>
|
|
||||||
It works! You passed <b>${ JSON.stringify(params.data) }</b>
|
|
||||||
and are currently requesting <b>${ params.location.path }</b>`;
|
|
||||||
resolve({ html });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.SpaServices.Prerendering;
|
|
||||||
using Webpack.ActionResults;
|
|
||||||
|
|
||||||
namespace Webpack.Controllers
|
|
||||||
{
|
|
||||||
// This sample shows how you could invoke the prerendering APIs directly from an MVC
|
|
||||||
// action result.
|
|
||||||
public class FullPagePrerenderingController : Controller
|
|
||||||
{
|
|
||||||
private static JavaScriptModuleExport BootModule = new JavaScriptModuleExport("Clientside/PrerenderingSample")
|
|
||||||
{
|
|
||||||
// Because the boot module is written in TypeScript, we need to specify a webpack
|
|
||||||
// config so it can be built. If it was written in JavaScript, this would not be needed.
|
|
||||||
WebpackConfig = "webpack.config.js"
|
|
||||||
};
|
|
||||||
|
|
||||||
public IActionResult Index()
|
|
||||||
{
|
|
||||||
var dataToSupply = new { nowTime = DateTime.Now.Ticks };
|
|
||||||
return this.Prerender(BootModule, dataToSupply);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -32,7 +32,6 @@ namespace Webpack
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
loggerFactory.AddConsole();
|
|
||||||
app.UseMvc(routes =>
|
app.UseMvc(routes =>
|
||||||
{
|
{
|
||||||
routes.MapRoute(
|
routes.MapRoute(
|
||||||
@@ -44,6 +43,11 @@ namespace Webpack
|
|||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var host = new WebHostBuilder()
|
var host = new WebHostBuilder()
|
||||||
|
.ConfigureLogging(factory =>
|
||||||
|
{
|
||||||
|
factory.AddConsole();
|
||||||
|
factory.AddDebug();
|
||||||
|
})
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
<h1>Hello</h1>
|
<h1>Hello</h1>
|
||||||
Hi there. Enter some text: <input />
|
Hi there. Enter some text: <input />
|
||||||
|
|
||||||
<hr />
|
|
||||||
See also: <a asp-controller='FullPagePrerendering'>Full-page prerendering example</a>
|
|
||||||
|
|
||||||
@section scripts {
|
@section scripts {
|
||||||
<script src="dist/main.js"></script>
|
<script src="dist/main.js"></script>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<Import Project="..\..\..\build\dependencies.props" />
|
<Import Project="..\..\..\build\common.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -13,10 +13,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(MicrosoftAspNetCoreDiagnosticsPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(MicrosoftAspNetCoreMvcPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": ["es2015", "react"]
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user