├── ASP.NET Core API.postman_collection.json ├── Finished sample ├── CityInfo.API │ ├── CitiesDataStore.cs │ ├── CityInfo.API.csproj │ ├── Contexts │ │ └── CityInfoContext.cs │ ├── Controllers │ │ ├── CitiesController.cs │ │ ├── DummyController.cs │ │ └── PointsOfInterestController.cs │ ├── Entities │ │ ├── City.cs │ │ └── PointOfInterest.cs │ ├── Migrations │ │ ├── 20191206101024_CityInfoDBInitialMigration.Designer.cs │ │ ├── 20191206101024_CityInfoDBInitialMigration.cs │ │ ├── 20191206102741_CityInfoDBAddPoIDescription.Designer.cs │ │ ├── 20191206102741_CityInfoDBAddPoIDescription.cs │ │ ├── 20191206111047_SampleData.Designer.cs │ │ ├── 20191206111047_SampleData.cs │ │ └── CityInfoContextModelSnapshot.cs │ ├── Models │ │ ├── CityDto.cs │ │ ├── CityWithoutPointsOfInterestDto.cs │ │ ├── PointOfInterestDto.cs │ │ ├── PointOfInterestForCreationDto.cs │ │ └── PointOfInterestForUpdateDto.cs │ ├── Profiles │ │ ├── CityProfile.cs │ │ └── PointOfInterestProfile.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Services │ │ ├── CityInfoRepository.cs │ │ ├── CloudMailService.cs │ │ ├── ICityInfoRepository.cs │ │ ├── IMailService.cs │ │ └── LocalMailService.cs │ ├── Startup.cs │ ├── appsettings.Production.json │ ├── appsettings.json │ ├── bin │ │ └── Debug │ │ │ └── netcoreapp2.1 │ │ │ ├── CityInfo.API.deps.json │ │ │ ├── CityInfo.API.dll │ │ │ ├── CityInfo.API.pdb │ │ │ ├── CityInfo.API.runtimeconfig.dev.json │ │ │ ├── CityInfo.API.runtimeconfig.json │ │ │ ├── Properties │ │ │ └── launchSettings.json │ │ │ ├── appsettings.Production.json │ │ │ ├── appsettings.json │ │ │ ├── nlog-2019-12-04.log │ │ │ ├── nlog-2019-12-06.log │ │ │ └── nlog.config │ ├── nlog.config │ └── obj │ │ ├── CityInfo.API.csproj.nuget.cache │ │ ├── CityInfo.API.csproj.nuget.dgspec.json │ │ ├── CityInfo.API.csproj.nuget.g.props │ │ ├── CityInfo.API.csproj.nuget.g.targets │ │ ├── Debug │ │ └── netcoreapp2.1 │ │ │ ├── CityInfo.API.AssemblyInfo.cs │ │ │ ├── CityInfo.API.AssemblyInfoInputs.cache │ │ │ ├── CityInfo.API.RazorAssemblyInfo.cache │ │ │ ├── CityInfo.API.RazorAssemblyInfo.cs │ │ │ ├── CityInfo.API.RazorTargetAssemblyInfo.cache │ │ │ ├── CityInfo.API.assets.cache │ │ │ ├── CityInfo.API.csproj.FileListAbsolute.txt │ │ │ ├── CityInfo.API.csprojAssemblyReference.cache │ │ │ ├── CityInfo.API.dll │ │ │ └── CityInfo.API.pdb │ │ ├── Release │ │ └── netcoreapp2.1 │ │ │ ├── CityInfo.API.AssemblyInfo.cs │ │ │ ├── CityInfo.API.AssemblyInfoInputs.cache │ │ │ ├── CityInfo.API.RazorAssemblyInfo.cache │ │ │ ├── CityInfo.API.RazorAssemblyInfo.cs │ │ │ └── CityInfo.API.assets.cache │ │ └── project.assets.json └── CityInfo.sln ├── README.md └── Starter files └── startfromscratch.txt /ASP.NET Core API.postman_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "6b2286b0-2c27-44a0-aa78-4d54be8e5545", 4 | "name": "ASP.NET Core API", 5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 6 | }, 7 | "item": [ 8 | { 9 | "name": "GET Cities", 10 | "request": { 11 | "method": "GET", 12 | "header": [], 13 | "url": { 14 | "raw": "http://localhost:1028/api/cities", 15 | "protocol": "http", 16 | "host": [ 17 | "localhost" 18 | ], 19 | "port": "1028", 20 | "path": [ 21 | "api", 22 | "cities" 23 | ] 24 | } 25 | }, 26 | "response": [] 27 | }, 28 | { 29 | "name": "GET City", 30 | "request": { 31 | "method": "GET", 32 | "header": [], 33 | "url": { 34 | "raw": "http://localhost:1028/api/cities/1", 35 | "protocol": "http", 36 | "host": [ 37 | "localhost" 38 | ], 39 | "port": "1028", 40 | "path": [ 41 | "api", 42 | "cities", 43 | "1" 44 | ] 45 | } 46 | }, 47 | "response": [] 48 | }, 49 | { 50 | "name": "GET Points of Interest", 51 | "request": { 52 | "method": "GET", 53 | "header": [], 54 | "url": { 55 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest", 56 | "protocol": "http", 57 | "host": [ 58 | "localhost" 59 | ], 60 | "port": "1028", 61 | "path": [ 62 | "api", 63 | "cities", 64 | "1", 65 | "pointsofinterest" 66 | ] 67 | } 68 | }, 69 | "response": [] 70 | }, 71 | { 72 | "name": "GET Points of Interest (unexisting City)", 73 | "request": { 74 | "method": "GET", 75 | "header": [], 76 | "url": { 77 | "raw": "http://localhost:1028/api/cities/4/pointsofinterest", 78 | "protocol": "http", 79 | "host": [ 80 | "localhost" 81 | ], 82 | "port": "1028", 83 | "path": [ 84 | "api", 85 | "cities", 86 | "4", 87 | "pointsofinterest" 88 | ] 89 | }, 90 | "description": "Should return 404 NotFound" 91 | }, 92 | "response": [] 93 | }, 94 | { 95 | "name": "GET Point of Interest", 96 | "request": { 97 | "method": "GET", 98 | "header": [], 99 | "url": { 100 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 101 | "protocol": "http", 102 | "host": [ 103 | "localhost" 104 | ], 105 | "port": "1028", 106 | "path": [ 107 | "api", 108 | "cities", 109 | "1", 110 | "pointsofinterest", 111 | "1" 112 | ] 113 | } 114 | }, 115 | "response": [] 116 | }, 117 | { 118 | "name": "GET Point of Interest (unexisting City)", 119 | "request": { 120 | "method": "GET", 121 | "header": [], 122 | "url": { 123 | "raw": "http://localhost:1028/api/cities/4/pointsofinterest/1", 124 | "protocol": "http", 125 | "host": [ 126 | "localhost" 127 | ], 128 | "port": "1028", 129 | "path": [ 130 | "api", 131 | "cities", 132 | "4", 133 | "pointsofinterest", 134 | "1" 135 | ] 136 | }, 137 | "description": "Should return 404 NotFound" 138 | }, 139 | "response": [] 140 | }, 141 | { 142 | "name": "GET Point of Interest (unexisting Point of Interest)", 143 | "request": { 144 | "method": "GET", 145 | "header": [], 146 | "url": { 147 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/10", 148 | "protocol": "http", 149 | "host": [ 150 | "localhost" 151 | ], 152 | "port": "1028", 153 | "path": [ 154 | "api", 155 | "cities", 156 | "1", 157 | "pointsofinterest", 158 | "10" 159 | ] 160 | }, 161 | "description": "Should return 404 NotFound" 162 | }, 163 | "response": [] 164 | }, 165 | { 166 | "name": "GET Cities (XML)", 167 | "request": { 168 | "method": "GET", 169 | "header": [ 170 | { 171 | "key": "Accept", 172 | "value": "application/xml" 173 | } 174 | ], 175 | "url": { 176 | "raw": "http://localhost:1028/api/cities", 177 | "protocol": "http", 178 | "host": [ 179 | "localhost" 180 | ], 181 | "port": "1028", 182 | "path": [ 183 | "api", 184 | "cities" 185 | ] 186 | } 187 | }, 188 | "response": [] 189 | }, 190 | { 191 | "name": "POST Point of Interest", 192 | "request": { 193 | "method": "POST", 194 | "header": [ 195 | { 196 | "key": "Content-Type", 197 | "value": "application/json" 198 | } 199 | ], 200 | "body": { 201 | "mode": "raw", 202 | "raw": "{\n \"name\": \"Père Lachaise\",\n \"description\": \"Famous cemetery where Jim Morrison and Oscar Wilde are buried.\"\n}" 203 | }, 204 | "url": { 205 | "raw": "http://localhost:1028/api/cities/3/pointsofinterest", 206 | "protocol": "http", 207 | "host": [ 208 | "localhost" 209 | ], 210 | "port": "1028", 211 | "path": [ 212 | "api", 213 | "cities", 214 | "3", 215 | "pointsofinterest" 216 | ] 217 | } 218 | }, 219 | "response": [] 220 | }, 221 | { 222 | "name": "POST Point of Interest (can't deserialize)", 223 | "request": { 224 | "method": "POST", 225 | "header": [ 226 | { 227 | "key": "Content-Type", 228 | "value": "application/json" 229 | } 230 | ], 231 | "body": { 232 | "mode": "raw", 233 | "raw": "" 234 | }, 235 | "url": { 236 | "raw": "http://localhost:1028/api/cities/3/pointsofinterest", 237 | "protocol": "http", 238 | "host": [ 239 | "localhost" 240 | ], 241 | "port": "1028", 242 | "path": [ 243 | "api", 244 | "cities", 245 | "3", 246 | "pointsofinterest" 247 | ] 248 | } 249 | }, 250 | "response": [] 251 | }, 252 | { 253 | "name": "POST Point of Interest (missing name, long description)", 254 | "request": { 255 | "method": "POST", 256 | "header": [ 257 | { 258 | "key": "Content-Type", 259 | "value": "application/json" 260 | } 261 | ], 262 | "body": { 263 | "mode": "raw", 264 | "raw": "{\n \"invalidProperty\": 1,\n \"description\": \"Scallywag holystone landlubber or just lubber yardarm tackle Shiver me timbers cog heave down provost Admiral of the Black. Hornswaggle spanker man-of-war yo-ho-ho mutiny splice the main brace jack keelhaul fire ship Corsair. Bounty prow walk the plank lugsail port loot pirate bilge jib scuppers. Sutler lee matey sloop plunder splice the main brace interloper Yellow Jack maroon quarter. Draft Privateer run a shot across the bow chandler gaff broadside Pirate Round jolly boat skysail bilge. Chandler mutiny careen execution dock splice the main brace bring a spring upon her cable lass run a rig grog blossom smartly. Gangplank Davy Jones' Locker plunder overhaul draught pinnace blow the man down bring a spring upon her cable no prey, no pay keel. Gold Road gaff grapple sutler scurvy aft bilge come about coffer gunwalls. Scuttle list Davy Jones' Locker pinnace chase trysail draught Pirate Round Jolly Roger log.\"\n}\n" 265 | }, 266 | "url": { 267 | "raw": "http://localhost:1028/api/cities/3/pointsofinterest", 268 | "protocol": "http", 269 | "host": [ 270 | "localhost" 271 | ], 272 | "port": "1028", 273 | "path": [ 274 | "api", 275 | "cities", 276 | "3", 277 | "pointsofinterest" 278 | ] 279 | } 280 | }, 281 | "response": [] 282 | }, 283 | { 284 | "name": "POST Point of Interest (name == description)", 285 | "request": { 286 | "method": "POST", 287 | "header": [ 288 | { 289 | "key": "Content-Type", 290 | "value": "application/json" 291 | } 292 | ], 293 | "body": { 294 | "mode": "raw", 295 | "raw": "{\n \"name\": \"Père Lachaise\",\n \"description\": \"Père Lachaise\"\n}" 296 | }, 297 | "url": { 298 | "raw": "http://localhost:1028/api/cities/3/pointsofinterest", 299 | "protocol": "http", 300 | "host": [ 301 | "localhost" 302 | ], 303 | "port": "1028", 304 | "path": [ 305 | "api", 306 | "cities", 307 | "3", 308 | "pointsofinterest" 309 | ] 310 | } 311 | }, 312 | "response": [] 313 | }, 314 | { 315 | "name": "PUT Point of Interest", 316 | "request": { 317 | "method": "PUT", 318 | "header": [ 319 | { 320 | "key": "Content-Type", 321 | "value": "application/json" 322 | } 323 | ], 324 | "body": { 325 | "mode": "raw", 326 | "raw": "{\n \"name\": \"Updated - Central Park\",\n \"description\": \"Updated - The most visited urban park in the United States.\"\n}" 327 | }, 328 | "url": { 329 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 330 | "protocol": "http", 331 | "host": [ 332 | "localhost" 333 | ], 334 | "port": "1028", 335 | "path": [ 336 | "api", 337 | "cities", 338 | "1", 339 | "pointsofinterest", 340 | "1" 341 | ] 342 | } 343 | }, 344 | "response": [] 345 | }, 346 | { 347 | "name": "PUT Point of Interest (no description)", 348 | "request": { 349 | "method": "PUT", 350 | "header": [ 351 | { 352 | "key": "Content-Type", 353 | "value": "application/json" 354 | } 355 | ], 356 | "body": { 357 | "mode": "raw", 358 | "raw": "{\n \"name\": \"Updated again - Central Park\"\n}" 359 | }, 360 | "url": { 361 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 362 | "protocol": "http", 363 | "host": [ 364 | "localhost" 365 | ], 366 | "port": "1028", 367 | "path": [ 368 | "api", 369 | "cities", 370 | "1", 371 | "pointsofinterest", 372 | "1" 373 | ] 374 | } 375 | }, 376 | "response": [] 377 | }, 378 | { 379 | "name": "PATCH Point of Interest", 380 | "request": { 381 | "method": "PATCH", 382 | "header": [ 383 | { 384 | "key": "Content-Type", 385 | "value": "application/json" 386 | } 387 | ], 388 | "body": { 389 | "mode": "raw", 390 | "raw": "[\n {\n \"op\": \"replace\",\n \"path\": \"/name\",\n \"value\": \"Updated - Central Park\"\n }\n]" 391 | }, 392 | "url": { 393 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 394 | "protocol": "http", 395 | "host": [ 396 | "localhost" 397 | ], 398 | "port": "1028", 399 | "path": [ 400 | "api", 401 | "cities", 402 | "1", 403 | "pointsofinterest", 404 | "1" 405 | ] 406 | } 407 | }, 408 | "response": [] 409 | }, 410 | { 411 | "name": "PATCH Point of Interest (update multiple)", 412 | "request": { 413 | "method": "PATCH", 414 | "header": [ 415 | { 416 | "key": "Content-Type", 417 | "value": "application/json" 418 | } 419 | ], 420 | "body": { 421 | "mode": "raw", 422 | "raw": "[\n {\n \"op\": \"replace\",\n \"path\": \"/name\",\n \"value\": \"Updated - Central Park\"\n },\n {\n \"op\": \"replace\",\n \"path\": \"/description\",\n \"value\": \"Updated - Description\"\n }\n]" 423 | }, 424 | "url": { 425 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 426 | "protocol": "http", 427 | "host": [ 428 | "localhost" 429 | ], 430 | "port": "1028", 431 | "path": [ 432 | "api", 433 | "cities", 434 | "1", 435 | "pointsofinterest", 436 | "1" 437 | ] 438 | } 439 | }, 440 | "response": [] 441 | }, 442 | { 443 | "name": "PATCH Point of Interest (invalid property)", 444 | "request": { 445 | "method": "PATCH", 446 | "header": [ 447 | { 448 | "key": "Content-Type", 449 | "value": "application/json" 450 | } 451 | ], 452 | "body": { 453 | "mode": "raw", 454 | "raw": "[\n {\n \"op\": \"replace\",\n \"path\": \"/invalidproperty\",\n \"value\": \"Updated - Central Park\"\n }\n]" 455 | }, 456 | "url": { 457 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 458 | "protocol": "http", 459 | "host": [ 460 | "localhost" 461 | ], 462 | "port": "1028", 463 | "path": [ 464 | "api", 465 | "cities", 466 | "1", 467 | "pointsofinterest", 468 | "1" 469 | ] 470 | } 471 | }, 472 | "response": [] 473 | }, 474 | { 475 | "name": "PATCH Point of Interest (remove name)", 476 | "request": { 477 | "method": "PATCH", 478 | "header": [ 479 | { 480 | "key": "Content-Type", 481 | "value": "application/json" 482 | } 483 | ], 484 | "body": { 485 | "mode": "raw", 486 | "raw": "[\n {\n \"op\": \"remove\",\n \"path\": \"/name\"\n }\n]" 487 | }, 488 | "url": { 489 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 490 | "protocol": "http", 491 | "host": [ 492 | "localhost" 493 | ], 494 | "port": "1028", 495 | "path": [ 496 | "api", 497 | "cities", 498 | "1", 499 | "pointsofinterest", 500 | "1" 501 | ] 502 | } 503 | }, 504 | "response": [] 505 | }, 506 | { 507 | "name": "PATCH Point of Interest (update multiple, same value)", 508 | "request": { 509 | "method": "PATCH", 510 | "header": [ 511 | { 512 | "key": "Content-Type", 513 | "value": "application/json" 514 | } 515 | ], 516 | "body": { 517 | "mode": "raw", 518 | "raw": "[\n {\n \"op\": \"replace\",\n \"path\": \"/name\",\n \"value\": \"Updated - Central Park\"\n },\n {\n \"op\": \"replace\",\n \"path\": \"/description\",\n \"value\": \"Updated - Central Park\"\n }\n]" 519 | }, 520 | "url": { 521 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 522 | "protocol": "http", 523 | "host": [ 524 | "localhost" 525 | ], 526 | "port": "1028", 527 | "path": [ 528 | "api", 529 | "cities", 530 | "1", 531 | "pointsofinterest", 532 | "1" 533 | ] 534 | } 535 | }, 536 | "response": [] 537 | }, 538 | { 539 | "name": "DELETE Point of Interest", 540 | "request": { 541 | "method": "DELETE", 542 | "header": [], 543 | "body": { 544 | "mode": "raw", 545 | "raw": "" 546 | }, 547 | "url": { 548 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest/1", 549 | "protocol": "http", 550 | "host": [ 551 | "localhost" 552 | ], 553 | "port": "1028", 554 | "path": [ 555 | "api", 556 | "cities", 557 | "1", 558 | "pointsofinterest", 559 | "1" 560 | ] 561 | } 562 | }, 563 | "response": [] 564 | }, 565 | { 566 | "name": "GET Points of Interest", 567 | "request": { 568 | "method": "GET", 569 | "header": [], 570 | "url": { 571 | "raw": "http://localhost:1028/api/cities/1/pointsofinterest", 572 | "protocol": "http", 573 | "host": [ 574 | "localhost" 575 | ], 576 | "port": "1028", 577 | "path": [ 578 | "api", 579 | "cities", 580 | "1", 581 | "pointsofinterest" 582 | ] 583 | } 584 | }, 585 | "response": [] 586 | }, 587 | { 588 | "name": "Test database", 589 | "request": { 590 | "method": "GET", 591 | "header": [], 592 | "url": { 593 | "raw": "http://localhost:1028/api/testdatabase", 594 | "protocol": "http", 595 | "host": [ 596 | "localhost" 597 | ], 598 | "port": "1028", 599 | "path": [ 600 | "api", 601 | "testdatabase" 602 | ] 603 | } 604 | }, 605 | "response": [] 606 | } 607 | ], 608 | "protocolProfileBehavior": {} 609 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/CitiesDataStore.cs: -------------------------------------------------------------------------------- 1 | using CityInfo.API.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace CityInfo.API 8 | { 9 | public class CitiesDataStore 10 | { 11 | public static CitiesDataStore Current { get; } = new CitiesDataStore(); 12 | 13 | public List Cities { get; set; } 14 | 15 | public CitiesDataStore() 16 | { 17 | // init dummy data 18 | Cities = new List() 19 | { 20 | new CityDto() 21 | { 22 | Id = 1, 23 | Name = "New York City", 24 | Description = "The one with that big park.", 25 | PointsOfInterest = new List() 26 | { 27 | new PointOfInterestDto() { 28 | Id = 1, 29 | Name = "Central Park", 30 | Description = "The most visited urban park in the United States." }, 31 | new PointOfInterestDto() { 32 | Id = 2, 33 | Name = "Empire State Building", 34 | Description = "A 102-story skyscraper located in Midtown Manhattan." }, 35 | } 36 | }, 37 | new CityDto() 38 | { 39 | Id = 2, 40 | Name = "Antwerp", 41 | Description = "The one with the cathedral that was never really finished.", 42 | PointsOfInterest = new List() 43 | { 44 | new PointOfInterestDto() { 45 | Id = 3, 46 | Name = "Cathedral of Our Lady", 47 | Description = "A Gothic style cathedral, conceived by architects Jan and Pieter Appelmans." }, 48 | new PointOfInterestDto() { 49 | Id = 4, 50 | Name = "Antwerp Central Station", 51 | Description = "The the finest example of railway architecture in Belgium." }, 52 | } 53 | }, 54 | new CityDto() 55 | { 56 | Id= 3, 57 | Name = "Paris", 58 | Description = "The one with that big tower.", 59 | PointsOfInterest = new List() 60 | { 61 | new PointOfInterestDto() { 62 | Id = 5, 63 | Name = "Eiffel Tower", 64 | Description = "A wrought iron lattice tower on the Champ de Mars, named after engineer Gustave Eiffel." }, 65 | new PointOfInterestDto() { 66 | Id = 6, 67 | Name = "The Louvre", 68 | Description = "The world's largest museum." }, 69 | } 70 | } 71 | }; 72 | } 73 | 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/CityInfo.API.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Contexts/CityInfoContext.cs: -------------------------------------------------------------------------------- 1 | using CityInfo.API.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace CityInfo.API.Contexts 9 | { 10 | public class CityInfoContext : DbContext 11 | { 12 | public DbSet Cities { get; set; } 13 | public DbSet PointsOfInterest { get; set; } 14 | 15 | public CityInfoContext(DbContextOptions options) 16 | : base(options) 17 | { 18 | // Database.EnsureCreated(); 19 | } 20 | 21 | protected override void OnModelCreating(ModelBuilder modelBuilder) 22 | { 23 | modelBuilder.Entity() 24 | .HasData( 25 | new City() 26 | { 27 | Id = 1, 28 | Name = "New York City", 29 | Description = "The one with that big park." 30 | }, 31 | new City() 32 | { 33 | Id = 2, 34 | Name = "Antwerp", 35 | Description = "The one with the cathedral that was never really finished." 36 | }, 37 | new City() 38 | { 39 | Id = 3, 40 | Name = "Paris", 41 | Description = "The one with that big tower." 42 | }); 43 | 44 | 45 | modelBuilder.Entity() 46 | .HasData( 47 | new PointOfInterest() 48 | { 49 | Id = 1, 50 | CityId = 1, 51 | Name = "Central Park", 52 | Description = "The most visited urban park in the United States." 53 | 54 | }, 55 | new PointOfInterest() 56 | { 57 | Id = 2, 58 | CityId = 1, 59 | Name = "Empire State Building", 60 | Description = "A 102-story skyscraper located in Midtown Manhattan." 61 | }, 62 | new PointOfInterest() 63 | { 64 | Id = 3, 65 | CityId = 2, 66 | Name = "Cathedral", 67 | Description = "A Gothic style cathedral, conceived by architects Jan and Pieter Appelmans." 68 | }, 69 | new PointOfInterest() 70 | { 71 | Id = 4, 72 | CityId = 2, 73 | Name = "Antwerp Central Station", 74 | Description = "The the finest example of railway architecture in Belgium." 75 | }, 76 | new PointOfInterest() 77 | { 78 | Id = 5, 79 | CityId = 3, 80 | Name = "Eiffel Tower", 81 | Description = "A wrought iron lattice tower on the Champ de Mars, named after engineer Gustave Eiffel." 82 | }, 83 | new PointOfInterest() 84 | { 85 | Id = 6, 86 | CityId = 3, 87 | Name = "The Louvre", 88 | Description = "The world's largest museum." 89 | } 90 | ); 91 | 92 | base.OnModelCreating(modelBuilder); 93 | } 94 | 95 | //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 96 | //{ 97 | // optionsBuilder.UseSqlServer("connectionstring"); 98 | // base.OnConfiguring(optionsBuilder); 99 | //} 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Controllers/CitiesController.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using CityInfo.API.Models; 3 | using CityInfo.API.Services; 4 | using Microsoft.AspNetCore.Mvc; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace CityInfo.API.Controllers 11 | { 12 | [ApiController] 13 | [Route("api/cities")] 14 | public class CitiesController : ControllerBase 15 | { 16 | private readonly ICityInfoRepository _cityInfoRepository; 17 | private readonly IMapper _mapper; 18 | 19 | public CitiesController(ICityInfoRepository cityInfoRepository, 20 | IMapper mapper) 21 | { 22 | _cityInfoRepository = cityInfoRepository ?? 23 | throw new ArgumentNullException(nameof(cityInfoRepository)); 24 | _mapper = mapper ?? 25 | throw new ArgumentNullException(nameof(mapper)); 26 | } 27 | 28 | [HttpGet] 29 | public IActionResult GetCities() 30 | { 31 | var cityEntities = _cityInfoRepository.GetCities(); 32 | 33 | //var results = new List(); 34 | 35 | //foreach (var cityEntity in cityEntities) 36 | //{ 37 | // results.Add(new CityWithoutPointsOfInterestDto 38 | // { 39 | // Id = cityEntity.Id, 40 | // Description = cityEntity.Description, 41 | // Name = cityEntity.Name 42 | // }); 43 | //} 44 | 45 | return Ok(_mapper.Map>(cityEntities)); 46 | } 47 | 48 | [HttpGet("{id}")] 49 | public IActionResult GetCity(int id, bool includePointsOfInterest = false) 50 | { 51 | var city = _cityInfoRepository.GetCity(id, includePointsOfInterest); 52 | 53 | if (city == null) 54 | { 55 | return NotFound(); 56 | } 57 | 58 | if (includePointsOfInterest) 59 | { 60 | return Ok(_mapper.Map(city)); 61 | } 62 | 63 | return Ok(_mapper.Map(city)); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Controllers/DummyController.cs: -------------------------------------------------------------------------------- 1 | using CityInfo.API.Contexts; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace CityInfo.API.Controllers 9 | { 10 | [ApiController] 11 | [Route("api/testdatabase")] 12 | public class DummyController : ControllerBase 13 | { 14 | private readonly CityInfoContext _ctx; 15 | 16 | public DummyController(CityInfoContext ctx) 17 | { 18 | _ctx = ctx ?? throw new ArgumentNullException(nameof(ctx)); 19 | } 20 | 21 | [HttpGet] 22 | public IActionResult TestDatabase() 23 | { 24 | return Ok(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Controllers/PointsOfInterestController.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using CityInfo.API.Models; 3 | using CityInfo.API.Services; 4 | using Microsoft.AspNetCore.JsonPatch; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Threading.Tasks; 11 | 12 | namespace CityInfo.API.Controllers 13 | { 14 | [ApiController] 15 | [Route("api/cities/{cityId}/pointsofinterest")] 16 | public class PointsOfInterestController : ControllerBase 17 | { 18 | private readonly ILogger _logger; 19 | private readonly IMailService _mailService; 20 | private readonly ICityInfoRepository _cityInfoRepository; 21 | private readonly IMapper _mapper; 22 | 23 | public PointsOfInterestController(ILogger logger, 24 | IMailService mailService, ICityInfoRepository cityInfoRepository, 25 | IMapper mapper) 26 | { 27 | _logger = logger ?? 28 | throw new ArgumentNullException(nameof(logger)); 29 | _mailService = mailService ?? 30 | throw new ArgumentNullException(nameof(mailService)); 31 | _cityInfoRepository = cityInfoRepository ?? 32 | throw new ArgumentNullException(nameof(cityInfoRepository)); 33 | _mapper = mapper ?? 34 | throw new ArgumentNullException(nameof(mapper)); 35 | } 36 | 37 | [HttpGet] 38 | public IActionResult GetPointsOfInterest(int cityId) 39 | { 40 | try 41 | { 42 | // throw new Exception("Exception example."); 43 | if (!_cityInfoRepository.CityExists(cityId)) 44 | { 45 | _logger.LogInformation($"City with id {cityId} wasn't found when " + 46 | $"accessing points of interest."); 47 | return NotFound(); 48 | } 49 | 50 | var pointsOfInterestForCity = _cityInfoRepository.GetPointsOfInterestForCity(cityId); 51 | return Ok(_mapper.Map>(pointsOfInterestForCity)); 52 | } 53 | catch (Exception ex) 54 | { 55 | _logger.LogCritical($"Exception while getting points of interest for city with id {cityId}.", ex); 56 | return StatusCode(500, "A problem happened while handling your request."); 57 | } 58 | } 59 | 60 | [HttpGet("{id}", Name ="GetPointOfInterest")] 61 | public IActionResult GetPointOfInterest(int cityId, int id) 62 | { 63 | if (!_cityInfoRepository.CityExists(cityId)) 64 | { 65 | return NotFound(); 66 | } 67 | 68 | var pointOfInterest = _cityInfoRepository.GetPointOfInterestForCity(cityId, id); 69 | 70 | if (pointOfInterest == null) 71 | { 72 | return NotFound(); 73 | } 74 | 75 | return Ok(_mapper.Map(pointOfInterest)); 76 | } 77 | 78 | [HttpPost] 79 | public IActionResult CreatePointOfInterest(int cityId, 80 | [FromBody] PointOfInterestForCreationDto pointOfInterest) 81 | { 82 | if (pointOfInterest.Description == pointOfInterest.Name) 83 | { 84 | ModelState.AddModelError( 85 | "Description", 86 | "The provided description should be different from the name."); 87 | } 88 | 89 | if (!ModelState.IsValid) 90 | { 91 | return BadRequest(ModelState); 92 | } 93 | 94 | if (!_cityInfoRepository.CityExists(cityId)) 95 | { 96 | return NotFound(); 97 | } 98 | 99 | var finalPointOfInterest = _mapper.Map(pointOfInterest); 100 | 101 | _cityInfoRepository.AddPointOfInterestForCity(cityId, finalPointOfInterest); 102 | 103 | _cityInfoRepository.Save(); 104 | 105 | var createdPointOfInterestToReturn = _mapper 106 | .Map(finalPointOfInterest); 107 | 108 | return CreatedAtRoute( 109 | "GetPointOfInterest", 110 | new { cityId, id = createdPointOfInterestToReturn.Id }, 111 | createdPointOfInterestToReturn); 112 | } 113 | 114 | [HttpPut("{id}")] 115 | public IActionResult UpdatePointOfInterest(int cityId, int id, 116 | [FromBody] PointOfInterestForUpdateDto pointOfInterest) 117 | { 118 | if (pointOfInterest.Description == pointOfInterest.Name) 119 | { 120 | ModelState.AddModelError( 121 | "Description", 122 | "The provided description should be different from the name."); 123 | } 124 | 125 | if (!ModelState.IsValid) 126 | { 127 | return BadRequest(ModelState); 128 | } 129 | 130 | if (!_cityInfoRepository.CityExists(cityId)) 131 | { 132 | return NotFound(); 133 | } 134 | 135 | var pointOfInterestEntity = _cityInfoRepository 136 | .GetPointOfInterestForCity(cityId, id); 137 | if (pointOfInterestEntity == null) 138 | { 139 | return NotFound(); 140 | } 141 | 142 | _mapper.Map(pointOfInterest, pointOfInterestEntity); 143 | 144 | _cityInfoRepository.UpdatePointOfInterestForCity(cityId, pointOfInterestEntity); 145 | 146 | _cityInfoRepository.Save(); 147 | 148 | return NoContent(); 149 | } 150 | 151 | [HttpPatch("{id}")] 152 | public IActionResult PartiallyUpdatePointOfInterest(int cityId, int id, 153 | [FromBody] JsonPatchDocument patchDoc) 154 | { 155 | if (!_cityInfoRepository.CityExists(cityId)) 156 | { 157 | return NotFound(); 158 | } 159 | 160 | var pointOfInterestEntity = _cityInfoRepository 161 | .GetPointOfInterestForCity(cityId, id); 162 | if (pointOfInterestEntity == null) 163 | { 164 | return NotFound(); 165 | } 166 | 167 | var pointOfInterestToPatch = _mapper 168 | .Map(pointOfInterestEntity); 169 | 170 | patchDoc.ApplyTo(pointOfInterestToPatch, ModelState); 171 | 172 | if (!ModelState.IsValid) 173 | { 174 | return BadRequest(ModelState); 175 | } 176 | 177 | if (pointOfInterestToPatch.Description == pointOfInterestToPatch.Name) 178 | { 179 | ModelState.AddModelError( 180 | "Description", 181 | "The provided description should be different from the name."); 182 | } 183 | 184 | if (!TryValidateModel(pointOfInterestToPatch)) 185 | { 186 | return BadRequest(ModelState); 187 | } 188 | 189 | _mapper.Map(pointOfInterestToPatch, pointOfInterestEntity); 190 | 191 | _cityInfoRepository.UpdatePointOfInterestForCity(cityId, pointOfInterestEntity); 192 | 193 | _cityInfoRepository.Save(); 194 | 195 | return NoContent(); 196 | } 197 | 198 | [HttpDelete("{id}")] 199 | public IActionResult DeletePointOfInterest(int cityId, int id) 200 | { 201 | if (!_cityInfoRepository.CityExists(cityId)) 202 | { 203 | return NotFound(); 204 | } 205 | 206 | var pointOfInterestEntity = _cityInfoRepository 207 | .GetPointOfInterestForCity(cityId, id); 208 | if (pointOfInterestEntity == null) 209 | { 210 | return NotFound(); 211 | } 212 | 213 | _cityInfoRepository.DeletePointOfInterest(pointOfInterestEntity); 214 | 215 | _cityInfoRepository.Save(); 216 | 217 | _mailService.Send("Point of interest deleted.", 218 | $"Point of interest {pointOfInterestEntity.Name} with id {pointOfInterestEntity.Id} was deleted."); 219 | 220 | return NoContent(); 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Entities/City.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace CityInfo.API.Entities 9 | { 10 | public class City 11 | { 12 | [Key] 13 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 14 | public int Id { get; set; } 15 | [Required] 16 | [MaxLength(50)] 17 | public string Name { get; set; } 18 | [MaxLength(200)] 19 | public string Description { get; set; } 20 | 21 | public ICollection PointsOfInterest { get; set; } 22 | = new List(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Entities/PointOfInterest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace CityInfo.API.Entities 9 | { 10 | public class PointOfInterest 11 | { 12 | [Key] 13 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 14 | public int Id { get; set; } 15 | [Required] 16 | [MaxLength(50)] 17 | public string Name { get; set; } 18 | [MaxLength(200)] 19 | public string Description { get; set; } 20 | [ForeignKey("CityId")] 21 | public City City { get; set; } 22 | public int CityId { get; set; } 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Migrations/20191206101024_CityInfoDBInitialMigration.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using CityInfo.API.Contexts; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | 9 | namespace CityInfo.API.Migrations 10 | { 11 | [DbContext(typeof(CityInfoContext))] 12 | [Migration("20191206101024_CityInfoDBInitialMigration")] 13 | partial class CityInfoDBInitialMigration 14 | { 15 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 16 | { 17 | #pragma warning disable 612, 618 18 | modelBuilder 19 | .HasAnnotation("ProductVersion", "2.1.14-servicing-32113") 20 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 21 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 22 | 23 | modelBuilder.Entity("CityInfo.API.Entities.City", b => 24 | { 25 | b.Property("Id") 26 | .ValueGeneratedOnAdd() 27 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 28 | 29 | b.Property("Description") 30 | .HasMaxLength(200); 31 | 32 | b.Property("Name") 33 | .IsRequired() 34 | .HasMaxLength(50); 35 | 36 | b.HasKey("Id"); 37 | 38 | b.ToTable("Cities"); 39 | }); 40 | 41 | modelBuilder.Entity("CityInfo.API.Entities.PointOfInterest", b => 42 | { 43 | b.Property("Id") 44 | .ValueGeneratedOnAdd() 45 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 46 | 47 | b.Property("CityId"); 48 | 49 | b.Property("Name") 50 | .IsRequired() 51 | .HasMaxLength(50); 52 | 53 | b.HasKey("Id"); 54 | 55 | b.HasIndex("CityId"); 56 | 57 | b.ToTable("PointsOfInterest"); 58 | }); 59 | 60 | modelBuilder.Entity("CityInfo.API.Entities.PointOfInterest", b => 61 | { 62 | b.HasOne("CityInfo.API.Entities.City", "City") 63 | .WithMany("PointsOfInterest") 64 | .HasForeignKey("CityId") 65 | .OnDelete(DeleteBehavior.Cascade); 66 | }); 67 | #pragma warning restore 612, 618 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Migrations/20191206101024_CityInfoDBInitialMigration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Metadata; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace CityInfo.API.Migrations 5 | { 6 | public partial class CityInfoDBInitialMigration : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.CreateTable( 11 | name: "Cities", 12 | columns: table => new 13 | { 14 | Id = table.Column(nullable: false) 15 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 16 | Name = table.Column(maxLength: 50, nullable: false), 17 | Description = table.Column(maxLength: 200, nullable: true) 18 | }, 19 | constraints: table => 20 | { 21 | table.PrimaryKey("PK_Cities", x => x.Id); 22 | }); 23 | 24 | migrationBuilder.CreateTable( 25 | name: "PointsOfInterest", 26 | columns: table => new 27 | { 28 | Id = table.Column(nullable: false) 29 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 30 | Name = table.Column(maxLength: 50, nullable: false), 31 | CityId = table.Column(nullable: false) 32 | }, 33 | constraints: table => 34 | { 35 | table.PrimaryKey("PK_PointsOfInterest", x => x.Id); 36 | table.ForeignKey( 37 | name: "FK_PointsOfInterest_Cities_CityId", 38 | column: x => x.CityId, 39 | principalTable: "Cities", 40 | principalColumn: "Id", 41 | onDelete: ReferentialAction.Cascade); 42 | }); 43 | 44 | migrationBuilder.CreateIndex( 45 | name: "IX_PointsOfInterest_CityId", 46 | table: "PointsOfInterest", 47 | column: "CityId"); 48 | } 49 | 50 | protected override void Down(MigrationBuilder migrationBuilder) 51 | { 52 | migrationBuilder.DropTable( 53 | name: "PointsOfInterest"); 54 | 55 | migrationBuilder.DropTable( 56 | name: "Cities"); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Migrations/20191206102741_CityInfoDBAddPoIDescription.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using CityInfo.API.Contexts; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | 9 | namespace CityInfo.API.Migrations 10 | { 11 | [DbContext(typeof(CityInfoContext))] 12 | [Migration("20191206102741_CityInfoDBAddPoIDescription")] 13 | partial class CityInfoDBAddPoIDescription 14 | { 15 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 16 | { 17 | #pragma warning disable 612, 618 18 | modelBuilder 19 | .HasAnnotation("ProductVersion", "2.1.14-servicing-32113") 20 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 21 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 22 | 23 | modelBuilder.Entity("CityInfo.API.Entities.City", b => 24 | { 25 | b.Property("Id") 26 | .ValueGeneratedOnAdd() 27 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 28 | 29 | b.Property("Description") 30 | .HasMaxLength(200); 31 | 32 | b.Property("Name") 33 | .IsRequired() 34 | .HasMaxLength(50); 35 | 36 | b.HasKey("Id"); 37 | 38 | b.ToTable("Cities"); 39 | }); 40 | 41 | modelBuilder.Entity("CityInfo.API.Entities.PointOfInterest", b => 42 | { 43 | b.Property("Id") 44 | .ValueGeneratedOnAdd() 45 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 46 | 47 | b.Property("CityId"); 48 | 49 | b.Property("Description") 50 | .HasMaxLength(200); 51 | 52 | b.Property("Name") 53 | .IsRequired() 54 | .HasMaxLength(50); 55 | 56 | b.HasKey("Id"); 57 | 58 | b.HasIndex("CityId"); 59 | 60 | b.ToTable("PointsOfInterest"); 61 | }); 62 | 63 | modelBuilder.Entity("CityInfo.API.Entities.PointOfInterest", b => 64 | { 65 | b.HasOne("CityInfo.API.Entities.City", "City") 66 | .WithMany("PointsOfInterest") 67 | .HasForeignKey("CityId") 68 | .OnDelete(DeleteBehavior.Cascade); 69 | }); 70 | #pragma warning restore 612, 618 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Migrations/20191206102741_CityInfoDBAddPoIDescription.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace CityInfo.API.Migrations 4 | { 5 | public partial class CityInfoDBAddPoIDescription : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "Description", 11 | table: "PointsOfInterest", 12 | maxLength: 200, 13 | nullable: true); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.DropColumn( 19 | name: "Description", 20 | table: "PointsOfInterest"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Migrations/20191206111047_SampleData.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using CityInfo.API.Contexts; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | 9 | namespace CityInfo.API.Migrations 10 | { 11 | [DbContext(typeof(CityInfoContext))] 12 | [Migration("20191206111047_SampleData")] 13 | partial class SampleData 14 | { 15 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 16 | { 17 | #pragma warning disable 612, 618 18 | modelBuilder 19 | .HasAnnotation("ProductVersion", "2.1.14-servicing-32113") 20 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 21 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 22 | 23 | modelBuilder.Entity("CityInfo.API.Entities.City", b => 24 | { 25 | b.Property("Id") 26 | .ValueGeneratedOnAdd() 27 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 28 | 29 | b.Property("Description") 30 | .HasMaxLength(200); 31 | 32 | b.Property("Name") 33 | .IsRequired() 34 | .HasMaxLength(50); 35 | 36 | b.HasKey("Id"); 37 | 38 | b.ToTable("Cities"); 39 | 40 | b.HasData( 41 | new { Id = 1, Description = "The one with that big park.", Name = "New York City" }, 42 | new { Id = 2, Description = "The one with the cathedral that was never really finished.", Name = "Antwerp" }, 43 | new { Id = 3, Description = "The one with that big tower.", Name = "Paris" } 44 | ); 45 | }); 46 | 47 | modelBuilder.Entity("CityInfo.API.Entities.PointOfInterest", b => 48 | { 49 | b.Property("Id") 50 | .ValueGeneratedOnAdd() 51 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 52 | 53 | b.Property("CityId"); 54 | 55 | b.Property("Description") 56 | .HasMaxLength(200); 57 | 58 | b.Property("Name") 59 | .IsRequired() 60 | .HasMaxLength(50); 61 | 62 | b.HasKey("Id"); 63 | 64 | b.HasIndex("CityId"); 65 | 66 | b.ToTable("PointsOfInterest"); 67 | 68 | b.HasData( 69 | new { Id = 1, CityId = 1, Description = "The most visited urban park in the United States.", Name = "Central Park" }, 70 | new { Id = 2, CityId = 1, Description = "A 102-story skyscraper located in Midtown Manhattan.", Name = "Empire State Building" }, 71 | new { Id = 3, CityId = 2, Description = "A Gothic style cathedral, conceived by architects Jan and Pieter Appelmans.", Name = "Cathedral" }, 72 | new { Id = 4, CityId = 2, Description = "The the finest example of railway architecture in Belgium.", Name = "Antwerp Central Station" }, 73 | new { Id = 5, CityId = 3, Description = "A wrought iron lattice tower on the Champ de Mars, named after engineer Gustave Eiffel.", Name = "Eiffel Tower" }, 74 | new { Id = 6, CityId = 3, Description = "The world's largest museum.", Name = "The Louvre" } 75 | ); 76 | }); 77 | 78 | modelBuilder.Entity("CityInfo.API.Entities.PointOfInterest", b => 79 | { 80 | b.HasOne("CityInfo.API.Entities.City", "City") 81 | .WithMany("PointsOfInterest") 82 | .HasForeignKey("CityId") 83 | .OnDelete(DeleteBehavior.Cascade); 84 | }); 85 | #pragma warning restore 612, 618 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Migrations/20191206111047_SampleData.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace CityInfo.API.Migrations 4 | { 5 | public partial class SampleData : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.InsertData( 10 | table: "Cities", 11 | columns: new[] { "Id", "Description", "Name" }, 12 | values: new object[] { 1, "The one with that big park.", "New York City" }); 13 | 14 | migrationBuilder.InsertData( 15 | table: "Cities", 16 | columns: new[] { "Id", "Description", "Name" }, 17 | values: new object[] { 2, "The one with the cathedral that was never really finished.", "Antwerp" }); 18 | 19 | migrationBuilder.InsertData( 20 | table: "Cities", 21 | columns: new[] { "Id", "Description", "Name" }, 22 | values: new object[] { 3, "The one with that big tower.", "Paris" }); 23 | 24 | migrationBuilder.InsertData( 25 | table: "PointsOfInterest", 26 | columns: new[] { "Id", "CityId", "Description", "Name" }, 27 | values: new object[,] 28 | { 29 | { 1, 1, "The most visited urban park in the United States.", "Central Park" }, 30 | { 2, 1, "A 102-story skyscraper located in Midtown Manhattan.", "Empire State Building" }, 31 | { 3, 2, "A Gothic style cathedral, conceived by architects Jan and Pieter Appelmans.", "Cathedral" }, 32 | { 4, 2, "The the finest example of railway architecture in Belgium.", "Antwerp Central Station" }, 33 | { 5, 3, "A wrought iron lattice tower on the Champ de Mars, named after engineer Gustave Eiffel.", "Eiffel Tower" }, 34 | { 6, 3, "The world's largest museum.", "The Louvre" } 35 | }); 36 | } 37 | 38 | protected override void Down(MigrationBuilder migrationBuilder) 39 | { 40 | migrationBuilder.DeleteData( 41 | table: "PointsOfInterest", 42 | keyColumn: "Id", 43 | keyValue: 1); 44 | 45 | migrationBuilder.DeleteData( 46 | table: "PointsOfInterest", 47 | keyColumn: "Id", 48 | keyValue: 2); 49 | 50 | migrationBuilder.DeleteData( 51 | table: "PointsOfInterest", 52 | keyColumn: "Id", 53 | keyValue: 3); 54 | 55 | migrationBuilder.DeleteData( 56 | table: "PointsOfInterest", 57 | keyColumn: "Id", 58 | keyValue: 4); 59 | 60 | migrationBuilder.DeleteData( 61 | table: "PointsOfInterest", 62 | keyColumn: "Id", 63 | keyValue: 5); 64 | 65 | migrationBuilder.DeleteData( 66 | table: "PointsOfInterest", 67 | keyColumn: "Id", 68 | keyValue: 6); 69 | 70 | migrationBuilder.DeleteData( 71 | table: "Cities", 72 | keyColumn: "Id", 73 | keyValue: 1); 74 | 75 | migrationBuilder.DeleteData( 76 | table: "Cities", 77 | keyColumn: "Id", 78 | keyValue: 2); 79 | 80 | migrationBuilder.DeleteData( 81 | table: "Cities", 82 | keyColumn: "Id", 83 | keyValue: 3); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Migrations/CityInfoContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using CityInfo.API.Contexts; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 7 | 8 | namespace CityInfo.API.Migrations 9 | { 10 | [DbContext(typeof(CityInfoContext))] 11 | partial class CityInfoContextModelSnapshot : ModelSnapshot 12 | { 13 | protected override void BuildModel(ModelBuilder modelBuilder) 14 | { 15 | #pragma warning disable 612, 618 16 | modelBuilder 17 | .HasAnnotation("ProductVersion", "2.1.14-servicing-32113") 18 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 19 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 20 | 21 | modelBuilder.Entity("CityInfo.API.Entities.City", b => 22 | { 23 | b.Property("Id") 24 | .ValueGeneratedOnAdd() 25 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 26 | 27 | b.Property("Description") 28 | .HasMaxLength(200); 29 | 30 | b.Property("Name") 31 | .IsRequired() 32 | .HasMaxLength(50); 33 | 34 | b.HasKey("Id"); 35 | 36 | b.ToTable("Cities"); 37 | 38 | b.HasData( 39 | new { Id = 1, Description = "The one with that big park.", Name = "New York City" }, 40 | new { Id = 2, Description = "The one with the cathedral that was never really finished.", Name = "Antwerp" }, 41 | new { Id = 3, Description = "The one with that big tower.", Name = "Paris" } 42 | ); 43 | }); 44 | 45 | modelBuilder.Entity("CityInfo.API.Entities.PointOfInterest", b => 46 | { 47 | b.Property("Id") 48 | .ValueGeneratedOnAdd() 49 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 50 | 51 | b.Property("CityId"); 52 | 53 | b.Property("Description") 54 | .HasMaxLength(200); 55 | 56 | b.Property("Name") 57 | .IsRequired() 58 | .HasMaxLength(50); 59 | 60 | b.HasKey("Id"); 61 | 62 | b.HasIndex("CityId"); 63 | 64 | b.ToTable("PointsOfInterest"); 65 | 66 | b.HasData( 67 | new { Id = 1, CityId = 1, Description = "The most visited urban park in the United States.", Name = "Central Park" }, 68 | new { Id = 2, CityId = 1, Description = "A 102-story skyscraper located in Midtown Manhattan.", Name = "Empire State Building" }, 69 | new { Id = 3, CityId = 2, Description = "A Gothic style cathedral, conceived by architects Jan and Pieter Appelmans.", Name = "Cathedral" }, 70 | new { Id = 4, CityId = 2, Description = "The the finest example of railway architecture in Belgium.", Name = "Antwerp Central Station" }, 71 | new { Id = 5, CityId = 3, Description = "A wrought iron lattice tower on the Champ de Mars, named after engineer Gustave Eiffel.", Name = "Eiffel Tower" }, 72 | new { Id = 6, CityId = 3, Description = "The world's largest museum.", Name = "The Louvre" } 73 | ); 74 | }); 75 | 76 | modelBuilder.Entity("CityInfo.API.Entities.PointOfInterest", b => 77 | { 78 | b.HasOne("CityInfo.API.Entities.City", "City") 79 | .WithMany("PointsOfInterest") 80 | .HasForeignKey("CityId") 81 | .OnDelete(DeleteBehavior.Cascade); 82 | }); 83 | #pragma warning restore 612, 618 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Models/CityDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace CityInfo.API.Models 7 | { 8 | public class CityDto 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Description { get; set; } 13 | public int NumberOfPointsOfInterest 14 | { 15 | get 16 | { 17 | return PointsOfInterest.Count; 18 | } 19 | } 20 | 21 | public ICollection PointsOfInterest { get; set; } 22 | = new List(); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Models/CityWithoutPointsOfInterestDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace CityInfo.API.Models 7 | { 8 | public class CityWithoutPointsOfInterestDto 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Description { get; set; } 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Models/PointOfInterestDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace CityInfo.API.Models 7 | { 8 | public class PointOfInterestDto 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Description { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Models/PointOfInterestForCreationDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace CityInfo.API.Models 8 | { 9 | public class PointOfInterestForCreationDto 10 | { 11 | [Required(ErrorMessage = "You should provide a name value.")] 12 | [MaxLength(50)] 13 | public string Name { get; set; } 14 | 15 | [MaxLength(200)] 16 | public string Description { get; set; } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Models/PointOfInterestForUpdateDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace CityInfo.API.Models 8 | { 9 | public class PointOfInterestForUpdateDto 10 | { 11 | [Required(ErrorMessage = "You should provide a name value.")] 12 | [MaxLength(50)] 13 | public string Name { get; set; } 14 | 15 | [MaxLength(200)] 16 | public string Description { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Profiles/CityProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace CityInfo.API.Profiles 8 | { 9 | public class CityProfile : Profile 10 | { 11 | public CityProfile() 12 | { 13 | CreateMap(); 14 | CreateMap(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Profiles/PointOfInterestProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace CityInfo.API.Profiles 8 | { 9 | public class PointOfInterestProfile : Profile 10 | { 11 | public PointOfInterestProfile() 12 | { 13 | CreateMap(); 14 | CreateMap(); 15 | CreateMap() 16 | .ReverseMap(); 17 | 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using CityInfo.API.Contexts; 7 | using Microsoft.AspNetCore; 8 | using Microsoft.AspNetCore.Hosting; 9 | using Microsoft.EntityFrameworkCore; 10 | using Microsoft.Extensions.Configuration; 11 | using Microsoft.Extensions.DependencyInjection; 12 | using Microsoft.Extensions.Logging; 13 | using NLog.Web; 14 | 15 | namespace CityInfo.API 16 | { 17 | public class Program 18 | { 19 | public static void Main(string[] args) 20 | { 21 | var logger = NLogBuilder 22 | .ConfigureNLog("nlog.config") 23 | .GetCurrentClassLogger(); 24 | try 25 | { 26 | 27 | logger.Info("Initializing application..."); 28 | var host = CreateWebHostBuilder(args).Build(); 29 | 30 | using (var scope = host.Services.CreateScope()) 31 | { 32 | try 33 | { 34 | var context = scope.ServiceProvider.GetService(); 35 | 36 | // for demo purposes, delete the database & migrate on startup so 37 | // we can start with a clean slate 38 | context.Database.EnsureDeleted(); 39 | context.Database.Migrate(); 40 | } 41 | catch (Exception ex) 42 | { 43 | logger.Error(ex, "An error occurred while migrating the database."); 44 | } 45 | } 46 | 47 | // run the web app 48 | host.Run(); 49 | } 50 | catch (Exception ex) 51 | { 52 | logger.Error(ex, "Application stopped because of exception."); 53 | throw; 54 | } 55 | finally 56 | { 57 | NLog.LogManager.Shutdown(); 58 | } 59 | } 60 | 61 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 62 | WebHost.CreateDefaultBuilder(args) 63 | .UseStartup() 64 | .UseNLog(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:1028", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "CityInfo.API": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:5000" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Services/CityInfoRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using CityInfo.API.Contexts; 6 | using CityInfo.API.Entities; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace CityInfo.API.Services 10 | { 11 | public class CityInfoRepository : ICityInfoRepository 12 | { 13 | private readonly CityInfoContext _context; 14 | 15 | public CityInfoRepository(CityInfoContext context) 16 | { 17 | _context = context ?? throw new ArgumentNullException(nameof(context)); 18 | } 19 | 20 | public IEnumerable GetCities() 21 | { 22 | return _context.Cities.OrderBy(c => c.Name).ToList(); 23 | } 24 | 25 | public City GetCity(int cityId, bool includePointsOfInterest) 26 | { 27 | if (includePointsOfInterest) 28 | { 29 | return _context.Cities.Include(c => c.PointsOfInterest) 30 | .Where(c => c.Id == cityId).FirstOrDefault(); 31 | } 32 | 33 | return _context.Cities 34 | .Where(c => c.Id == cityId).FirstOrDefault(); 35 | } 36 | 37 | public PointOfInterest GetPointOfInterestForCity(int cityId, int pointOfInterestId) 38 | { 39 | return _context.PointsOfInterest 40 | .Where(p => p.CityId == cityId && p.Id == pointOfInterestId).FirstOrDefault(); 41 | } 42 | 43 | public IEnumerable GetPointsOfInterestForCity(int cityId) 44 | { 45 | return _context.PointsOfInterest 46 | .Where(p => p.CityId == cityId).ToList(); 47 | } 48 | 49 | public bool CityExists(int cityId) 50 | { 51 | return _context.Cities.Any(c => c.Id == cityId); 52 | } 53 | 54 | public void AddPointOfInterestForCity(int cityId, PointOfInterest pointOfInterest) 55 | { 56 | var city = GetCity(cityId, false); 57 | city.PointsOfInterest.Add(pointOfInterest); 58 | } 59 | 60 | public void UpdatePointOfInterestForCity(int cityId, PointOfInterest pointOfInterest) 61 | { 62 | 63 | } 64 | 65 | public void DeletePointOfInterest(PointOfInterest pointOfInterest) 66 | { 67 | _context.PointsOfInterest.Remove(pointOfInterest); 68 | } 69 | 70 | public bool Save() 71 | { 72 | return (_context.SaveChanges() >= 0); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Services/CloudMailService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace CityInfo.API.Services 9 | { 10 | public class CloudMailService : IMailService 11 | { 12 | private readonly IConfiguration _configuration; 13 | 14 | public CloudMailService(IConfiguration configuration) 15 | { 16 | _configuration = configuration ?? 17 | throw new ArgumentNullException(nameof(configuration)); 18 | } 19 | 20 | public void Send(string subject, string message) 21 | { 22 | // send mail - output to debug window 23 | Debug.WriteLine($"Mail from {_configuration["mailSettings:mailFromAddress"]} to {_configuration["mailSettings:mailToAddress"]}, with LocalMailService."); 24 | Debug.WriteLine($"Subject: {subject}"); 25 | Debug.WriteLine($"Message: {message}"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Services/ICityInfoRepository.cs: -------------------------------------------------------------------------------- 1 | using CityInfo.API.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace CityInfo.API.Services 8 | { 9 | public interface ICityInfoRepository 10 | { 11 | IEnumerable GetCities(); 12 | 13 | City GetCity(int cityId, bool includePointsOfInterest); 14 | 15 | IEnumerable GetPointsOfInterestForCity(int cityId); 16 | 17 | PointOfInterest GetPointOfInterestForCity(int cityId, int pointOfInterestId); 18 | 19 | bool CityExists(int cityId); 20 | 21 | void AddPointOfInterestForCity(int cityId, PointOfInterest pointOfInterest); 22 | 23 | void UpdatePointOfInterestForCity(int cityId, PointOfInterest pointOfInterest); 24 | 25 | void DeletePointOfInterest(PointOfInterest pointOfInterest); 26 | 27 | bool Save(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Services/IMailService.cs: -------------------------------------------------------------------------------- 1 | namespace CityInfo.API.Services 2 | { 3 | public interface IMailService 4 | { 5 | void Send(string subject, string message); 6 | } 7 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Services/LocalMailService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace CityInfo.API.Services 9 | { 10 | public class LocalMailService : IMailService 11 | { 12 | private readonly IConfiguration _configuration; 13 | 14 | public LocalMailService(IConfiguration configuration) 15 | { 16 | _configuration = configuration ?? 17 | throw new ArgumentNullException(nameof(configuration)); 18 | } 19 | 20 | public void Send(string subject, string message) 21 | { 22 | // send mail - output to debug window 23 | Debug.WriteLine($"Mail from {_configuration["mailSettings:mailFromAddress"]} to {_configuration["mailSettings:mailToAddress"]}, with LocalMailService."); 24 | Debug.WriteLine($"Subject: {subject}"); 25 | Debug.WriteLine($"Message: {message}"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using AutoMapper; 6 | using CityInfo.API.Contexts; 7 | using CityInfo.API.Services; 8 | using Microsoft.AspNetCore.Builder; 9 | using Microsoft.AspNetCore.Hosting; 10 | using Microsoft.AspNetCore.Http; 11 | using Microsoft.AspNetCore.Mvc.Formatters; 12 | using Microsoft.EntityFrameworkCore; 13 | using Microsoft.Extensions.Configuration; 14 | using Microsoft.Extensions.DependencyInjection; 15 | using Newtonsoft.Json.Serialization; 16 | 17 | namespace CityInfo.API 18 | { 19 | public class Startup 20 | { 21 | private readonly IConfiguration _configuration; 22 | 23 | public Startup(IConfiguration configuration) 24 | { 25 | _configuration = configuration ?? 26 | throw new ArgumentNullException(nameof(configuration)); 27 | } 28 | // This method gets called by the runtime. Use this method to add services to the container. 29 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 30 | public void ConfigureServices(IServiceCollection services) 31 | { 32 | services.AddMvc() 33 | .AddMvcOptions(o => 34 | { 35 | o.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()); 36 | }); 37 | //.AddJsonOptions(o => 38 | //{ 39 | // if (o.SerializerSettings.ContractResolver != null) 40 | // { 41 | // var castedResolver = o.SerializerSettings.ContractResolver 42 | // as DefaultContractResolver; 43 | // castedResolver.NamingStrategy = null; 44 | // } 45 | //}); 46 | #if DEBUG 47 | services.AddTransient(); 48 | #else 49 | services.AddTransient(); 50 | #endif 51 | var connectionString = _configuration["connectionStrings:cityInfoDBConnectionString"]; 52 | services.AddDbContext(o => 53 | { 54 | o.UseSqlServer(connectionString); 55 | }); 56 | 57 | services.AddScoped(); 58 | 59 | services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); 60 | } 61 | 62 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 63 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 64 | { 65 | if (env.IsDevelopment()) 66 | { 67 | app.UseDeveloperExceptionPage(); 68 | } 69 | else 70 | { 71 | app.UseExceptionHandler(); 72 | } 73 | 74 | app.UseStatusCodePages(); 75 | 76 | app.UseMvc(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/appsettings.Production.json: -------------------------------------------------------------------------------- 1 | { 2 | "mailSettings": { 3 | "mailToAddress": "admin@mycompany.com" 4 | } 5 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "mailSettings": { 3 | "mailToAddress": "admin@mycompany.com", 4 | "mailFromAddress": "noreply@mycompany.com" 5 | }, 6 | "connectionStrings": { 7 | "cityInfoDBConnectionString": "Server=(localdb)\\mssqllocaldb;Database=CityInfoDB;Trusted_Connection=True;" 8 | } 9 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/CityInfo.API.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinDockx/APIAspNetCore_Course/1814ba937f7394981aef3f9a3207402136528239/Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/CityInfo.API.dll -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/CityInfo.API.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinDockx/APIAspNetCore_Course/1814ba937f7394981aef3f9a3207402136528239/Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/CityInfo.API.pdb -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/CityInfo.API.runtimeconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "additionalProbingPaths": [ 4 | "C:\\Users\\kevin\\.dotnet\\store\\|arch|\\|tfm|", 5 | "C:\\Users\\kevin\\.nuget\\packages", 6 | "C:\\Microsoft\\Xamarin\\NuGet", 7 | "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder" 8 | ] 9 | } 10 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/CityInfo.API.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "netcoreapp2.1", 4 | "framework": { 5 | "name": "Microsoft.AspNetCore.App", 6 | "version": "2.1.1" 7 | }, 8 | "configProperties": { 9 | "System.GC.Server": true 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:1028", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "CityInfo.API": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:5000" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/appsettings.Production.json: -------------------------------------------------------------------------------- 1 | { 2 | "mailSettings": { 3 | "mailToAddress": "admin@mycompany.com" 4 | } 5 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "mailSettings": { 3 | "mailToAddress": "admin@mycompany.com", 4 | "mailFromAddress": "noreply@mycompany.com" 5 | }, 6 | "connectionStrings": { 7 | "cityInfoDBConnectionString": "Server=(localdb)\\mssqllocaldb;Database=CityInfoDB;Trusted_Connection=True;" 8 | } 9 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/nlog-2019-12-04.log: -------------------------------------------------------------------------------- 1 | 2019-12-04 15:47:37.0497|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 2 | 2019-12-04 15:47:37.5624|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 3 | 2019-12-04 15:47:37.5624|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 4 | 2019-12-04 15:47:37.6104|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 49.2759ms 200 5 | 2019-12-04 15:47:37.7434|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 184.033ms 404 text/plain 6 | 2019-12-04 15:47:37.7742|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 7 | 2019-12-04 15:47:37.7810|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 4.6135ms 404 text/plain 8 | 2019-12-04 15:47:51.6615|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/api/cities/10/pointsofinterest 9 | 2019-12-04 15:47:51.7031|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Route matched with {action = "GetPointsOfInterest", controller = "PointsOfInterest"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult GetPointsOfInterest(Int32) on controller CityInfo.API.Controllers.PointsOfInterestController (CityInfo.API). 10 | 2019-12-04 15:47:51.7795|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executing action method CityInfo.API.Controllers.PointsOfInterestController.GetPointsOfInterest (CityInfo.API) - Validation state: Valid 11 | 2019-12-04 15:47:51.8255|FATAL|CityInfo.API.Controllers.PointsOfInterestController|Exception while getting points of interest for city with id 10. 12 | 2019-12-04 15:47:51.8317|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action method CityInfo.API.Controllers.PointsOfInterestController.GetPointsOfInterest (CityInfo.API), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 46.1486ms. 13 | 2019-12-04 15:47:51.8317|INFO|Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor|Executing ObjectResult, writing value of type 'System.String'. 14 | 2019-12-04 15:47:51.8491|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action CityInfo.API.Controllers.PointsOfInterestController.GetPointsOfInterest (CityInfo.API) in 139.8817ms 15 | 2019-12-04 15:47:51.8491|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 192.9485ms 500 text/plain; charset=utf-8 16 | 2019-12-04 15:54:51.5306|INFO|CityInfo.API.Program|Initializing application... 17 | 2019-12-04 15:54:52.9689|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 18 | 2019-12-04 15:54:53.4851|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 19 | 2019-12-04 15:54:53.4851|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 20 | 2019-12-04 15:54:53.5282|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 43.9177ms 200 21 | 2019-12-04 15:54:53.6342|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 151.357ms 404 text/plain 22 | 2019-12-04 15:54:53.6647|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 23 | 2019-12-04 15:54:53.6725|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 3.7521ms 404 text/plain 24 | 2019-12-04 16:19:35.4042|INFO|CityInfo.API.Program|Initializing application... 25 | 2019-12-04 16:19:37.2725|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 26 | 2019-12-04 16:19:38.0248|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 27 | 2019-12-04 16:19:38.0248|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 28 | 2019-12-04 16:19:38.0729|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 48.2272ms 200 29 | 2019-12-04 16:19:38.2055|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 182.7705ms 404 text/plain 30 | 2019-12-04 16:19:38.2461|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 31 | 2019-12-04 16:19:38.2520|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 4.694ms 404 text/plain 32 | 2019-12-04 16:19:46.5883|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DELETE http://localhost:1028/api/cities/1/pointsofinterest/1 0 33 | 2019-12-04 16:19:46.6304|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Route matched with {action = "DeletePointOfInterest", controller = "PointsOfInterest"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult DeletePointOfInterest(Int32, Int32) on controller CityInfo.API.Controllers.PointsOfInterestController (CityInfo.API). 34 | 2019-12-04 16:19:46.7000|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executing action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) - Validation state: Valid 35 | 2019-12-04 16:19:46.7147|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API), returned result Microsoft.AspNetCore.Mvc.NoContentResult in 9.9766ms. 36 | 2019-12-04 16:19:46.7259|INFO|Microsoft.AspNetCore.Mvc.StatusCodeResult|Executing HttpStatusCodeResult, setting HTTP status code 204 37 | 2019-12-04 16:19:46.7259|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) in 95.6992ms 38 | 2019-12-04 16:19:46.7376|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 148.7035ms 204 39 | 2019-12-04 16:27:19.6816|INFO|CityInfo.API.Program|Initializing application... 40 | 2019-12-04 16:27:21.1512|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 41 | 2019-12-04 16:27:21.6250|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 42 | 2019-12-04 16:27:21.6250|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 43 | 2019-12-04 16:27:21.6719|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 47.736ms 200 44 | 2019-12-04 16:27:21.7816|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 160.0684ms 404 text/plain 45 | 2019-12-04 16:27:21.8124|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 46 | 2019-12-04 16:27:21.8124|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 3.6938ms 404 text/plain 47 | 2019-12-04 16:27:32.7274|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DELETE http://localhost:1028/api/cities/1/pointsofinterest/1 0 48 | 2019-12-04 16:27:32.7706|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Route matched with {action = "DeletePointOfInterest", controller = "PointsOfInterest"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult DeletePointOfInterest(Int32, Int32) on controller CityInfo.API.Controllers.PointsOfInterestController (CityInfo.API). 49 | 2019-12-04 16:27:32.8489|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executing action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) - Validation state: Valid 50 | 2019-12-04 16:27:32.8627|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API), returned result Microsoft.AspNetCore.Mvc.NoContentResult in 7.9918ms. 51 | 2019-12-04 16:27:32.8627|INFO|Microsoft.AspNetCore.Mvc.StatusCodeResult|Executing HttpStatusCodeResult, setting HTTP status code 204 52 | 2019-12-04 16:27:32.8784|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) in 101.9229ms 53 | 2019-12-04 16:27:32.8784|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 157.6037ms 204 54 | 2019-12-04 16:38:44.3777|INFO|CityInfo.API.Program|Initializing application... 55 | 2019-12-04 16:38:45.9038|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 56 | 2019-12-04 16:38:46.4767|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 57 | 2019-12-04 16:38:46.4767|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 58 | 2019-12-04 16:38:46.5142|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 36.8814ms 200 59 | 2019-12-04 16:38:46.6248|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 150.4904ms 404 text/plain 60 | 2019-12-04 16:38:46.6522|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 61 | 2019-12-04 16:38:46.6559|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 3.1328ms 404 text/plain 62 | 2019-12-04 16:38:50.9714|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DELETE http://localhost:1028/api/cities/1/pointsofinterest/1 0 63 | 2019-12-04 16:38:51.0213|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Route matched with {action = "DeletePointOfInterest", controller = "PointsOfInterest"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult DeletePointOfInterest(Int32, Int32) on controller CityInfo.API.Controllers.PointsOfInterestController (CityInfo.API). 64 | 2019-12-04 16:38:51.0970|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executing action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) - Validation state: Valid 65 | 2019-12-04 16:38:51.1121|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API), returned result Microsoft.AspNetCore.Mvc.NoContentResult in 8.849ms. 66 | 2019-12-04 16:38:51.1121|INFO|Microsoft.AspNetCore.Mvc.StatusCodeResult|Executing HttpStatusCodeResult, setting HTTP status code 204 67 | 2019-12-04 16:38:51.1290|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) in 101.898ms 68 | 2019-12-04 16:38:51.1290|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 164.7231ms 204 69 | 2019-12-04 16:44:14.1175|INFO|CityInfo.API.Program|Initializing application... 70 | 2019-12-04 16:44:15.4047|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 71 | 2019-12-04 16:44:15.8093|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 72 | 2019-12-04 16:44:15.8093|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 73 | 2019-12-04 16:44:15.8494|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 40.7682ms 200 74 | 2019-12-04 16:44:15.9481|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 140.6952ms 404 text/plain 75 | 2019-12-04 16:44:15.9784|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 76 | 2019-12-04 16:44:15.9784|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 3.1575ms 404 text/plain 77 | 2019-12-04 16:44:24.4723|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DELETE http://localhost:1028/api/cities/1/pointsofinterest/1 0 78 | 2019-12-04 16:44:24.5220|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Route matched with {action = "DeletePointOfInterest", controller = "PointsOfInterest"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult DeletePointOfInterest(Int32, Int32) on controller CityInfo.API.Controllers.PointsOfInterestController (CityInfo.API). 79 | 2019-12-04 16:44:24.5976|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executing action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) - Validation state: Valid 80 | 2019-12-04 16:44:24.6113|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API), returned result Microsoft.AspNetCore.Mvc.NoContentResult in 8.8398ms. 81 | 2019-12-04 16:44:24.6113|INFO|Microsoft.AspNetCore.Mvc.StatusCodeResult|Executing HttpStatusCodeResult, setting HTTP status code 204 82 | 2019-12-04 16:44:24.6113|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) in 98.0584ms 83 | 2019-12-04 16:44:24.6301|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 157.6144ms 204 84 | 2019-12-04 16:45:05.6254|INFO|CityInfo.API.Program|Initializing application... 85 | 2019-12-04 16:45:07.0102|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 86 | 2019-12-04 16:45:07.3139|FATAL|Microsoft.AspNetCore.Hosting.Internal.WebHost|Application startup exception 87 | 2019-12-04 16:45:07.5558|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 88 | 2019-12-04 16:45:07.5558|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 89 | 2019-12-04 16:45:07.5741|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 20.7639ms 500 text/html; charset=utf-8 90 | 2019-12-04 16:45:07.5778|ERROR|Microsoft.AspNetCore.Server.Kestrel|Connection id "0HLROQ3O35LS2", Request id "0HLROQ3O35LS2:00000001": An unhandled exception was thrown by the application. 91 | 2019-12-04 16:45:07.5778|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 29.746ms 500 92 | 2019-12-04 16:45:18.6684|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DELETE http://localhost:1028/api/cities/1/pointsofinterest/1 0 93 | 2019-12-04 16:45:18.6744|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 8.3775ms 500 text/html; charset=utf-8 94 | 2019-12-04 16:45:40.2087|INFO|CityInfo.API.Program|Initializing application... 95 | 2019-12-04 16:45:41.6185|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 96 | 2019-12-04 16:45:41.9786|FATAL|Microsoft.AspNetCore.Hosting.Internal.WebHost|Application startup exception 97 | 2019-12-04 16:45:42.2447|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 98 | 2019-12-04 16:45:42.2447|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 99 | 2019-12-04 16:45:42.2838|ERROR|Microsoft.AspNetCore.Server.Kestrel|Connection id "0HLROQ42DRJDM", Request id "0HLROQ42DRJDM:00000001": An unhandled exception was thrown by the application. 100 | 2019-12-04 16:45:42.2838|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 51.9799ms 500 101 | 2019-12-04 16:45:42.2838|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 51.8113ms 500 text/html; charset=utf-8 102 | 2019-12-04 16:46:32.9343|INFO|CityInfo.API.Program|Initializing application... 103 | 2019-12-04 16:46:34.3178|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 104 | 2019-12-04 16:46:34.5701|FATAL|Microsoft.AspNetCore.Hosting.Internal.WebHost|Application startup exception 105 | 2019-12-04 16:46:34.8112|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 106 | 2019-12-04 16:46:34.8112|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 107 | 2019-12-04 16:46:34.8271|ERROR|Microsoft.AspNetCore.Server.Kestrel|Connection id "0HLROQ4I39MJ6", Request id "0HLROQ4I39MJ6:00000001": An unhandled exception was thrown by the application. 108 | 2019-12-04 16:46:34.8337|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 24.3223ms 500 109 | 2019-12-04 16:46:34.8337|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 24.6512ms 500 text/html; charset=utf-8 110 | 2019-12-04 16:46:34.8808|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 111 | 2019-12-04 16:46:34.8808|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 6.4402ms 500 text/html; charset=utf-8 112 | 2019-12-04 16:47:32.2505|INFO|CityInfo.API.Program|Initializing application... 113 | 2019-12-04 16:47:35.8739|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 114 | 2019-12-04 16:47:36.3025|FATAL|Microsoft.AspNetCore.Hosting.Internal.WebHost|Application startup exception 115 | 2019-12-04 16:47:36.7967|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 116 | 2019-12-04 16:47:36.7967|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 117 | 2019-12-04 16:47:36.8359|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 42.4383ms 500 118 | 2019-12-04 16:47:36.8359|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 44.3206ms 500 text/html; charset=utf-8 119 | 2019-12-04 16:47:36.9538|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 120 | 2019-12-04 16:47:36.9754|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 10.0662ms 500 text/html; charset=utf-8 121 | 2019-12-04 16:48:25.7811|INFO|CityInfo.API.Program|Initializing application... 122 | 2019-12-04 16:48:27.3092|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 123 | 2019-12-04 16:48:27.8161|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 124 | 2019-12-04 16:48:27.8161|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 125 | 2019-12-04 16:48:27.8677|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 45.1158ms 200 126 | 2019-12-04 16:48:27.9813|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 167.7495ms 404 text/plain 127 | 2019-12-04 16:48:28.0169|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 128 | 2019-12-04 16:48:28.0331|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 16.7041ms 404 text/plain 129 | 2019-12-04 16:48:51.2941|INFO|CityInfo.API.Program|Initializing application... 130 | 2019-12-04 16:48:52.5747|INFO|Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager|User profile is available. Using 'C:\Users\kevin\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 131 | 2019-12-04 16:48:53.1390|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DEBUG http://localhost:1028/ 0 132 | 2019-12-04 16:48:53.1390|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/ 133 | 2019-12-04 16:48:53.1920|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 53.7816ms 200 134 | 2019-12-04 16:48:53.3387|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 193.3957ms 404 text/plain 135 | 2019-12-04 16:48:53.4125|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:1028/favicon.ico 136 | 2019-12-04 16:48:53.4351|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 22.9769ms 404 text/plain 137 | 2019-12-04 16:49:06.4371|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 DELETE http://localhost:1028/api/cities/1/pointsofinterest/1 0 138 | 2019-12-04 16:49:06.4779|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Route matched with {action = "DeletePointOfInterest", controller = "PointsOfInterest"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult DeletePointOfInterest(Int32, Int32) on controller CityInfo.API.Controllers.PointsOfInterestController (CityInfo.API). 139 | 2019-12-04 16:49:06.5470|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executing action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) - Validation state: Valid 140 | 2019-12-04 16:49:06.5610|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action method CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API), returned result Microsoft.AspNetCore.Mvc.NoContentResult in 8.8753ms. 141 | 2019-12-04 16:49:06.5685|INFO|Microsoft.AspNetCore.Mvc.StatusCodeResult|Executing HttpStatusCodeResult, setting HTTP status code 204 142 | 2019-12-04 16:49:06.5685|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executed action CityInfo.API.Controllers.PointsOfInterestController.DeletePointOfInterest (CityInfo.API) in 91.1672ms 143 | 2019-12-04 16:49:06.5806|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request finished in 143.4ms 204 144 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/bin/Debug/netcoreapp2.1/nlog.config: -------------------------------------------------------------------------------- 1 |  2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/nlog.config: -------------------------------------------------------------------------------- 1 |  2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/CityInfo.API.csproj.nuget.cache: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "dgSpecHash": "JoXPjyQSjbqdN83LCSWihEVHApK+7GUnLn4BtuqDCJwKLBoEns/iIiO+TE5VDbdk9Z8a0UIjdR13P6jciygP0A==", 4 | "success": true 5 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/CityInfo.API.csproj.nuget.dgspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 1, 3 | "restore": { 4 | "C:\\Pluralsight demo\\CityInfo\\CityInfo.API\\CityInfo.API.csproj": {} 5 | }, 6 | "projects": { 7 | "C:\\Pluralsight demo\\CityInfo\\CityInfo.API\\CityInfo.API.csproj": { 8 | "version": "1.0.0", 9 | "restore": { 10 | "projectUniqueName": "C:\\Pluralsight demo\\CityInfo\\CityInfo.API\\CityInfo.API.csproj", 11 | "projectName": "CityInfo.API", 12 | "projectPath": "C:\\Pluralsight demo\\CityInfo\\CityInfo.API\\CityInfo.API.csproj", 13 | "packagesPath": "C:\\Users\\kevin\\.nuget\\packages\\", 14 | "outputPath": "C:\\Pluralsight demo\\CityInfo\\CityInfo.API\\obj\\", 15 | "projectStyle": "PackageReference", 16 | "fallbackFolders": [ 17 | "C:\\Microsoft\\Xamarin\\NuGet\\", 18 | "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder" 19 | ], 20 | "configFilePaths": [ 21 | "C:\\Users\\kevin\\AppData\\Roaming\\NuGet\\NuGet.Config", 22 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config", 23 | "C:\\Program Files (x86)\\NuGet\\Config\\Xamarin.Offline.config" 24 | ], 25 | "originalTargetFrameworks": [ 26 | "netcoreapp2.1" 27 | ], 28 | "sources": { 29 | "C:\\LocalNuGetRepository": {}, 30 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 31 | "https://api.nuget.org/v3/index.json": {}, 32 | "https://dotnet.myget.org/F/roslyn/api/v3/index.json": {} 33 | }, 34 | "frameworks": { 35 | "netcoreapp2.1": { 36 | "projectReferences": {} 37 | } 38 | }, 39 | "warningProperties": { 40 | "warnAsError": [ 41 | "NU1605" 42 | ] 43 | } 44 | }, 45 | "frameworks": { 46 | "netcoreapp2.1": { 47 | "dependencies": { 48 | "AutoMapper.Extensions.Microsoft.DependencyInjection": { 49 | "target": "Package", 50 | "version": "[7.0.0, )" 51 | }, 52 | "Microsoft.AspNetCore.App": { 53 | "suppressParent": "All", 54 | "target": "Package", 55 | "version": "[2.1.1, )", 56 | "autoReferenced": true 57 | }, 58 | "Microsoft.AspNetCore.Razor.Design": { 59 | "suppressParent": "All", 60 | "target": "Package", 61 | "version": "[2.1.2, )" 62 | }, 63 | "Microsoft.NETCore.App": { 64 | "suppressParent": "All", 65 | "target": "Package", 66 | "version": "[2.1.0, )", 67 | "autoReferenced": true 68 | }, 69 | "NLog.Web.AspNetCore": { 70 | "target": "Package", 71 | "version": "[4.9.0, )" 72 | } 73 | }, 74 | "imports": [ 75 | "net461", 76 | "net462", 77 | "net47", 78 | "net471", 79 | "net472", 80 | "net48" 81 | ], 82 | "assetTargetFallback": true, 83 | "warn": true, 84 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\3.0.100\\RuntimeIdentifierGraph.json" 85 | } 86 | } 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/CityInfo.API.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | NuGet 6 | $(MSBuildThisFileDirectory)project.assets.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\kevin\.nuget\packages\;C:\Microsoft\Xamarin\NuGet\;C:\Program Files\dotnet\sdk\NuGetFallbackFolder 9 | PackageReference 10 | 5.3.1 11 | 12 | 13 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.entityframeworkcore.tools\2.1.1 26 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.codeanalysis.analyzers\1.1.0 27 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.razor.design\2.1.2 28 | 29 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/CityInfo.API.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("CityInfo.API")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 17 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 18 | [assembly: System.Reflection.AssemblyProductAttribute("CityInfo.API")] 19 | [assembly: System.Reflection.AssemblyTitleAttribute("CityInfo.API")] 20 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 21 | 22 | // Generated by the MSBuild WriteCodeFragment class. 23 | 24 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 322d0a618d9e5bcce4b443abc628fdd9d121603b 2 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.RazorAssemblyInfo.cache: -------------------------------------------------------------------------------- 1 | 2d09aaa509f756a3bef9f365de27e18eee6bc8a9 2 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.RazorAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.RelatedAssemblyAttribute("CityInfo.API.Views")] 15 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorLanguageVersionAttribute("2.1")] 16 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorConfigurationNameAttribute("MVC-2.1")] 17 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorExtensionAssemblyNameAttribute("MVC-2.1", "Microsoft.AspNetCore.Mvc.Razor.Extensions")] 18 | 19 | // Generated by the MSBuild WriteCodeFragment class. 20 | 21 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.RazorTargetAssemblyInfo.cache: -------------------------------------------------------------------------------- 1 | b0ba88e3a905f62cb2574a7ff9196815a97b1408 2 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinDockx/APIAspNetCore_Course/1814ba937f7394981aef3f9a3207402136528239/Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.assets.cache -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\Properties\launchSettings.json 2 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\CityInfo.API.deps.json 3 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\CityInfo.API.runtimeconfig.json 4 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\CityInfo.API.runtimeconfig.dev.json 5 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\CityInfo.API.dll 6 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\CityInfo.API.pdb 7 | C:\Pluralsight demo\CityInfo\CityInfo.API\obj\Debug\netcoreapp2.1\CityInfo.API.RazorAssemblyInfo.cache 8 | C:\Pluralsight demo\CityInfo\CityInfo.API\obj\Debug\netcoreapp2.1\CityInfo.API.RazorAssemblyInfo.cs 9 | C:\Pluralsight demo\CityInfo\CityInfo.API\obj\Debug\netcoreapp2.1\CityInfo.API.AssemblyInfoInputs.cache 10 | C:\Pluralsight demo\CityInfo\CityInfo.API\obj\Debug\netcoreapp2.1\CityInfo.API.AssemblyInfo.cs 11 | C:\Pluralsight demo\CityInfo\CityInfo.API\obj\Debug\netcoreapp2.1\CityInfo.API.RazorTargetAssemblyInfo.cache 12 | C:\Pluralsight demo\CityInfo\CityInfo.API\obj\Debug\netcoreapp2.1\CityInfo.API.dll 13 | C:\Pluralsight demo\CityInfo\CityInfo.API\obj\Debug\netcoreapp2.1\CityInfo.API.pdb 14 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\nlog.config 15 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\appsettings.json 16 | C:\Pluralsight demo\CityInfo\CityInfo.API\bin\Debug\netcoreapp2.1\appsettings.Production.json 17 | C:\Pluralsight demo\CityInfo\CityInfo.API\obj\Debug\netcoreapp2.1\CityInfo.API.csprojAssemblyReference.cache 18 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.csprojAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinDockx/APIAspNetCore_Course/1814ba937f7394981aef3f9a3207402136528239/Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.csprojAssemblyReference.cache -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinDockx/APIAspNetCore_Course/1814ba937f7394981aef3f9a3207402136528239/Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.dll -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinDockx/APIAspNetCore_Course/1814ba937f7394981aef3f9a3207402136528239/Finished sample/CityInfo.API/obj/Debug/netcoreapp2.1/CityInfo.API.pdb -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Release/netcoreapp2.1/CityInfo.API.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("CityInfo.API")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] 16 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 17 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 18 | [assembly: System.Reflection.AssemblyProductAttribute("CityInfo.API")] 19 | [assembly: System.Reflection.AssemblyTitleAttribute("CityInfo.API")] 20 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 21 | 22 | // Generated by the MSBuild WriteCodeFragment class. 23 | 24 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Release/netcoreapp2.1/CityInfo.API.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 098224736feab3276a571c166237b92482eb223b 2 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Release/netcoreapp2.1/CityInfo.API.RazorAssemblyInfo.cache: -------------------------------------------------------------------------------- 1 | 2d09aaa509f756a3bef9f365de27e18eee6bc8a9 2 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Release/netcoreapp2.1/CityInfo.API.RazorAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.RelatedAssemblyAttribute("CityInfo.API.Views")] 15 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorLanguageVersionAttribute("2.1")] 16 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorConfigurationNameAttribute("MVC-2.1")] 17 | [assembly: Microsoft.AspNetCore.Razor.Hosting.RazorExtensionAssemblyNameAttribute("MVC-2.1", "Microsoft.AspNetCore.Mvc.Razor.Extensions")] 18 | 19 | // Generated by the MSBuild WriteCodeFragment class. 20 | 21 | -------------------------------------------------------------------------------- /Finished sample/CityInfo.API/obj/Release/netcoreapp2.1/CityInfo.API.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinDockx/APIAspNetCore_Course/1814ba937f7394981aef3f9a3207402136528239/Finished sample/CityInfo.API/obj/Release/netcoreapp2.1/CityInfo.API.assets.cache -------------------------------------------------------------------------------- /Finished sample/CityInfo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29509.3 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CityInfo.API", "CityInfo.API\CityInfo.API.csproj", "{824D02E1-0BA0-4A61-A1A5-E70F2300D57D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {824D02E1-0BA0-4A61-A1A5-E70F2300D57D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {824D02E1-0BA0-4A61-A1A5-E70F2300D57D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {824D02E1-0BA0-4A61-A1A5-E70F2300D57D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {824D02E1-0BA0-4A61-A1A5-E70F2300D57D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {A48A6D4F-D922-4F83-847A-BF4B764B2F18} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Building Your First API with ASP.NET Core 2 | Starter files and fully functioning finished sample for my Building Your First API with ASP.NET Core course at Pluralsight (https://app.pluralsight.com/library/courses/asp-dotnet-core-api-building-first/table-of-contents) 3 | -------------------------------------------------------------------------------- /Starter files/startfromscratch.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinDockx/APIAspNetCore_Course/1814ba937f7394981aef3f9a3207402136528239/Starter files/startfromscratch.txt --------------------------------------------------------------------------------