Skip to content

Commit df54cf8

Browse files
committed
adding .net project
1 parent cad1267 commit df54cf8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+23760
-1
lines changed

YAML/demo_environment_template.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,23 @@ parameters:
2222
environmentDefinitionName: 'DemoApp'
2323
environmentType: 'CICD'
2424
regionAbrvs: ['eus']
25+
- name: projectNamesConfigurations
26+
type: object
27+
default:
28+
- projectName: 'todo'
29+
publishWebProject: true
30+
dotnetTest: false
31+
2532

2633

2734
stages:
28-
- template: stages/bicep_build_stage.yml@templates
35+
- template: stages/bicep_dotnet_build_stage.yml@templates
2936
parameters:
3037
environmentObjects: ${{ parameters.environmentObjects }}
3138
templateFileName: ${{ parameters.templateFileName }}
3239
serviceName: ${{ parameters.serviceName }}
3340
templateDirectory: ${{ parameters.templateDirectory }}
41+
projectNamesConfigurations: ${{ parameters.projectNamesConfigurations }}
3442
- template: stages/ade_loadtest_stage.yml@templates
3543
parameters:
3644
adeObjects: ${{ parameters.adeObjects }}

src/.dockerignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# directories
2+
**/bin/
3+
**/obj/
4+
**/out/
5+
6+
# files
7+
Dockerfile*
8+
**/*.md

src/Controllers/ItemController.cs

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
namespace todo.Controllers
2+
{
3+
using System;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Mvc;
6+
using todo.Models;
7+
8+
public class ItemController : Controller
9+
{
10+
private readonly ICosmosDbService _cosmosDbService;
11+
public ItemController(ICosmosDbService cosmosDbService)
12+
{
13+
_cosmosDbService = cosmosDbService;
14+
}
15+
16+
[ActionName("Index")]
17+
public async Task<IActionResult> Index()
18+
{
19+
return View(await _cosmosDbService.GetItemsAsync("SELECT * FROM c"));
20+
}
21+
22+
[ActionName("Create")]
23+
public IActionResult Create()
24+
{
25+
return View();
26+
}
27+
28+
[HttpPost]
29+
[ActionName("Create")]
30+
[ValidateAntiForgeryToken]
31+
public async Task<ActionResult> CreateAsync([Bind("Id,Name,Description,Completed")] Item item)
32+
{
33+
if (ModelState.IsValid)
34+
{
35+
item.Id = Guid.NewGuid().ToString();
36+
await _cosmosDbService.AddItemAsync(item);
37+
return RedirectToAction("Index");
38+
}
39+
40+
return View(item);
41+
}
42+
43+
[HttpPost]
44+
[ActionName("Edit")]
45+
[ValidateAntiForgeryToken]
46+
public async Task<ActionResult> EditAsync([Bind("Id,Name,Description,Completed")] Item item)
47+
{
48+
if (ModelState.IsValid)
49+
{
50+
await _cosmosDbService.UpdateItemAsync(item.Id, item);
51+
return RedirectToAction("Index");
52+
}
53+
54+
return View(item);
55+
}
56+
57+
[ActionName("Edit")]
58+
public async Task<ActionResult> EditAsync(string id)
59+
{
60+
if (id == null)
61+
{
62+
return BadRequest();
63+
}
64+
65+
Item item = await _cosmosDbService.GetItemAsync(id);
66+
if (item == null)
67+
{
68+
return NotFound();
69+
}
70+
71+
return View(item);
72+
}
73+
74+
[ActionName("Delete")]
75+
public async Task<ActionResult> DeleteAsync(string id)
76+
{
77+
if (id == null)
78+
{
79+
return BadRequest();
80+
}
81+
82+
Item item = await _cosmosDbService.GetItemAsync(id);
83+
if (item == null)
84+
{
85+
return NotFound();
86+
}
87+
88+
return View(item);
89+
}
90+
91+
[HttpPost]
92+
[ActionName("Delete")]
93+
[ValidateAntiForgeryToken]
94+
public async Task<ActionResult> DeleteConfirmedAsync([Bind("Id")] string id)
95+
{
96+
await _cosmosDbService.DeleteItemAsync(id);
97+
return RedirectToAction("Index");
98+
}
99+
100+
[ActionName("Details")]
101+
public async Task<ActionResult> DetailsAsync(string id)
102+
{
103+
return View(await _cosmosDbService.GetItemAsync(id));
104+
}
105+
}
106+
}

src/Dockerfile

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# https://hub.docker.com/_/microsoft-dotnet
2+
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
3+
4+
WORKDIR /source
5+
6+
# copy csproj and restore as distinct layers
7+
COPY *.csproj .
8+
RUN dotnet restore
9+
10+
# copy and publish app and libraries
11+
COPY . .
12+
RUN dotnet publish -c release -o /app --no-restore
13+
14+
# final stage/image
15+
FROM mcr.microsoft.com/dotnet/aspnet:3.1
16+
17+
WORKDIR /app
18+
COPY --from=build /app .
19+
ENTRYPOINT ["dotnet", "todo.dll"]

src/Models/ErrorViewModel.cs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
3+
namespace todo.Models
4+
{
5+
public class ErrorViewModel
6+
{
7+
public string RequestId { get; set; }
8+
9+
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
10+
}
11+
}

src/Models/Item.cs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace todo.Models
2+
{
3+
using Newtonsoft.Json;
4+
5+
public class Item
6+
{
7+
[JsonProperty(PropertyName = "id")]
8+
public string Id { get; set; }
9+
10+
[JsonProperty(PropertyName = "name")]
11+
public string Name { get; set; }
12+
13+
[JsonProperty(PropertyName = "description")]
14+
public string Description { get; set; }
15+
16+
[JsonProperty(PropertyName = "isComplete")]
17+
public bool Completed { get; set; }
18+
}
19+
}

src/Program.cs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace todo
2+
{
3+
using Microsoft.AspNetCore;
4+
using Microsoft.AspNetCore.Hosting;
5+
6+
public class Program
7+
{
8+
public static void Main(string[] args)
9+
{
10+
CreateWebHostBuilder(args).Build().Run();
11+
}
12+
13+
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
14+
WebHost.CreateDefaultBuilder(args)
15+
.UseStartup<Startup>();
16+
}
17+
}

src/Services/CosmosDbService.cs

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
namespace todo
2+
{
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using todo.Models;
7+
using Microsoft.Azure.Cosmos;
8+
using Microsoft.Azure.Cosmos.Fluent;
9+
using Microsoft.Extensions.Configuration;
10+
11+
public class CosmosDbService : ICosmosDbService
12+
{
13+
private Container _container;
14+
15+
public CosmosDbService(
16+
CosmosClient dbClient,
17+
string databaseName,
18+
string containerName)
19+
{
20+
this._container = dbClient.GetContainer(databaseName, containerName);
21+
}
22+
23+
public async Task AddItemAsync(Item item)
24+
{
25+
await this._container.CreateItemAsync<Item>(item, new PartitionKey(item.Id));
26+
}
27+
28+
public async Task DeleteItemAsync(string id)
29+
{
30+
await this._container.DeleteItemAsync<Item>(id, new PartitionKey(id));
31+
}
32+
33+
public async Task<Item> GetItemAsync(string id)
34+
{
35+
try
36+
{
37+
ItemResponse<Item> response = await this._container.ReadItemAsync<Item>(id, new PartitionKey(id));
38+
return response.Resource;
39+
}
40+
catch(CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
41+
{
42+
return null;
43+
}
44+
45+
}
46+
47+
public async Task<IEnumerable<Item>> GetItemsAsync(string queryString)
48+
{
49+
var query = this._container.GetItemQueryIterator<Item>(new QueryDefinition(queryString));
50+
List<Item> results = new List<Item>();
51+
while (query.HasMoreResults)
52+
{
53+
var response = await query.ReadNextAsync();
54+
55+
results.AddRange(response.ToList());
56+
}
57+
58+
return results;
59+
}
60+
61+
public async Task UpdateItemAsync(string id, Item item)
62+
{
63+
await this._container.UpsertItemAsync<Item>(item, new PartitionKey(id));
64+
}
65+
}
66+
}

src/Services/ICosmosDbService.cs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace todo
2+
{
3+
using System.Collections.Generic;
4+
using System.Threading.Tasks;
5+
using todo.Models;
6+
7+
public interface ICosmosDbService
8+
{
9+
Task<IEnumerable<Item>> GetItemsAsync(string query);
10+
Task<Item> GetItemAsync(string id);
11+
Task AddItemAsync(Item item);
12+
Task UpdateItemAsync(string id, Item item);
13+
Task DeleteItemAsync(string id);
14+
}
15+
}

src/Startup.cs

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
namespace todo
2+
{
3+
using System;
4+
using System.Threading.Tasks;
5+
using Azure.Identity;
6+
using Microsoft.AspNetCore.Builder;
7+
using Microsoft.AspNetCore.Hosting;
8+
using Microsoft.Extensions.Configuration;
9+
using Microsoft.Extensions.DependencyInjection;
10+
using Microsoft.Extensions.Hosting;
11+
12+
public class Startup
13+
{
14+
public Startup(IConfiguration configuration)
15+
{
16+
Configuration = configuration;
17+
}
18+
19+
public IConfiguration Configuration { get; }
20+
21+
// <ConfigureServices>
22+
public void ConfigureServices(IServiceCollection services)
23+
{
24+
services.AddControllersWithViews();
25+
services.AddSingleton<ICosmosDbService>(InitializeCosmosClientInstanceAsync(Configuration.GetSection("CosmosDb")).GetAwaiter().GetResult());
26+
}
27+
// </ConfigureServices>
28+
29+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
30+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
31+
{
32+
if (env.IsDevelopment())
33+
{
34+
app.UseDeveloperExceptionPage();
35+
}
36+
else
37+
{
38+
app.UseExceptionHandler("/Home/Error");
39+
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
40+
app.UseHsts();
41+
}
42+
app.UseHttpsRedirection();
43+
app.UseStaticFiles();
44+
45+
app.UseRouting();
46+
47+
app.UseAuthorization();
48+
49+
app.UseEndpoints(endpoints =>
50+
{
51+
endpoints.MapControllerRoute(
52+
name: "default",
53+
pattern: "{controller=Item}/{action=Index}/{id?}");
54+
});
55+
}
56+
57+
// <InitializeCosmosClientInstanceAsync>
58+
/// <summary>
59+
/// Creates a Cosmos DB database and a container with the specified partition key.
60+
/// </summary>
61+
/// <returns></returns>
62+
private static async Task<CosmosDbService> InitializeCosmosClientInstanceAsync(IConfigurationSection configurationSection)
63+
{
64+
string databaseName = configurationSection.GetSection("DatabaseName").Value;
65+
string containerName = configurationSection.GetSection("ContainerName").Value;
66+
string account = configurationSection.GetSection("Account").Value;
67+
68+
// If key is not set, assume we're using managed identity
69+
string key = configurationSection.GetSection("Key").Value;
70+
ManagedIdentityCredential miCredential;
71+
Microsoft.Azure.Cosmos.CosmosClient client;
72+
if (string.IsNullOrEmpty(key))
73+
{
74+
miCredential = new ManagedIdentityCredential();
75+
client = new Microsoft.Azure.Cosmos.CosmosClient(account, miCredential);
76+
}
77+
else
78+
{
79+
client = new Microsoft.Azure.Cosmos.CosmosClient(account, key);
80+
}
81+
82+
CosmosDbService cosmosDbService = new CosmosDbService(client, databaseName, containerName);
83+
Microsoft.Azure.Cosmos.DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
84+
await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");
85+
86+
return cosmosDbService;
87+
}
88+
// </InitializeCosmosClientInstanceAsync>
89+
}
90+
}

0 commit comments

Comments
 (0)