dotnet-presentations / aspnetcore-app-workshop Goto Github PK
View Code? Open in Web Editor NEWThis workshop will teach you ASP.NET Core by building a complete conference management website from scratch.
License: MIT License
This workshop will teach you ASP.NET Core by building a complete conference management website from scratch.
License: MIT License
For those examples that involve a number of copy/pasting several new files' worth of code, might make sense to have folks copy/paste into a BigCopiedFile.cs
or something similar and then utilize shortcuts to extract those classes to individual files. I think VS & ReSharper both have shortcuts for this though I'm not sure the VS / VSCode ones off-hand.
If you like this idea, I can submit a PR to combine some of the examples that run one after the other.
The Speaker
entity depicted in The database schema has ConferenceID
but its correponding classes (ConferenceDTO.Speaker
and BackEnd.Data.Speaker
) have no such a property.
Currently build and build badge are hooked to https://msft-shayne.visualstudio.com/ - should move to dotnetfoundation sponsored account.
I would love to see some unit tests around this code as a new user to EF having used other ORM's for years. It is not obvious how you would mock and test the concrete classes for the dbcontext and the dbsets.
If you only have Visual Studio 2017 installed fresh (newbie) and have not installed SDK 2.0, solution will not load.
I have tried the first section "Create BackEnd API project". However, when I scaffold the API controller using Visual Studio, it fails with the following error:
Method 'Create' in type 'Microsoft.EntityFramework.Core.SqlServer.Query.Internal.SqlServerTranslatingExpressionVisitorFactory' ... does not have implementation.
I have tried to solve this by updating all nugets. However, there is problem with Microsoft.VisualStudio.Web.CodeGeneration.Design (5.0.2). The latest version is not compatible wit .NET Core 3.1. So I tried to uninstall the package and install version 3.1.5 instead. The scaffolding still does not work. This time, it fails with error:
I do not know if the problem is with the instructions in this workshop, in some of the Nuget packages, or in the scaffolding in Visual Studio. Maybe specific versions of Nugets are required. It is sad when such basic things does not work out of the box. I have tried scaffolding for API controllers in .NET framework and some older versions of .NET Core and it worked without problems that time.
I am using Visual Studio 2019 (version 16.9.4).
I changed my job a year ago and that fact made me move away from asp.net development. I am trying to catch up asp.net core using this app. However, when I run this app after repo, I met the following error
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslState.ThrowIfExceptional()
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__47_1(IAsyncResult iar)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at FrontEnd.Services.ApiClient.GetSessionsAsync() in /Users/shootingstar/Code/booksource/aspnetcore-app-workshop/src/FrontEnd/Services/ApiClient.cs:line 69
at FrontEnd.Services.ApiClient.GetSessionsByAttendeeAsync(String name) in /Users/shootingstar/Code/booksource/aspnetcore-app-workshop/src/FrontEnd/Services/ApiClient.cs:line 153
at FrontEnd.Pages.IndexModel.OnGetAsync(Int32 day) in /Users/shootingstar/Code/booksource/aspnetcore-app-workshop/src/FrontEnd/Pages/Index.cshtml.cs:line 43
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.ExecutorFactory.NonGenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeNextPageFilterAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
After a few search, I found the following site
https://www.hanselman.com/blog/DevelopingLocallyWithASPNETCoreUnderHTTPSSSLAndSelfSignedCerts.aspx
and I could fix with this command dotnet dev-certs https --trust
I think it can be helpful if this potential issue is mentioned somewhere in a doco.
During the workshop today I added the ability for the session cards on the Home and My Agenda pages to progressively enhance the buttons for adding/removing sessions from the personal agenda to post using JavaScript rather than a normal form submit. It also handles dynamically updating the UI including removing the cards on the My Agenda page.
The JavaScript and modified agenda partial follow. We should consider incorporating this into the workshop.
"use strict";
// Agenda form functionality
let onMyAgendaPage = document.querySelector("h1[data-myAgenda]") !== null;
let form = document.querySelector("#agendaForm");
if (form) {
form.addEventListener("submit", async e => {
e.preventDefault();
let sessionId = document.activeElement.getAttribute("value"),
card = document.querySelector("#session-" + sessionId),
button = card.querySelector("button:not(.template)"),
template = card.querySelector("button.template"),
url = button.formAction || form.action,
formData = new FormData(form);
formData.append("sessionId", sessionId);
let response = await fetch(url, {
method: form.method,
body: formData
});
if (response.status === 200) {
if (url.indexOf("Remove") > 0 && onMyAgendaPage) {
let timeSlotDiv = card.closest("div.timeSlot"),
agendaDiv = document.querySelector("div.agenda"),
dayPill = agendaDiv.querySelector("a.nav-link.active");
card.remove();
// Check if this was the last card in this time slot and if so remove the track node
if (timeSlotDiv.querySelectorAll(".session-card").length === 0) {
timeSlotDiv.remove();
// Check if this was the last card in the day and if so remove the day pill button
if (agendaDiv.querySelectorAll(".session-card").length === 0) {
dayPill.remove();
// Check if there are more days and if so navigate to the next day, else show the empty message
let dayPills = agendaDiv.querySelectorAll("a.nav-link");
if (dayPills.length > 0) {
document.location.search = "";
}
else {
agendaDiv.querySelector("#agendaMessage").classList.remove("template");
}
}
}
} else {
button.classList.add("template");
template.classList.remove("template");
}
}
});
}
@model IndexModel
<div class="agenda">
<ul class="nav nav-pills mb-3">
@foreach (var day in Model.DayOffsets)
{
<li role="presentation" class="nav-item">
<a class="nav-link @(Model.CurrentDayOffset == day.Offset ? "active" : null)" asp-route-day="@day.Offset">@day.DayofWeek?.ToString()</a>
</li>
}
</ul>
@{
var messageClassName = Model.Sessions.Any() ? "template" : null;
}
<p id="agendaMessage" class="@messageClassName">There don't appear to be any sessions here.</p>
<form authz method="post" id="agendaForm">
@foreach (var timeSlot in Model.Sessions)
{
<div class="timeSlot">
<h4>@timeSlot.Key?.ToString("HH:mm")</h4>
<div class="row">
@foreach (var session in timeSlot)
{
<div class="col-md-3 mb-4 session-card" id="[email protected]">
<div class="card shadow session h-100">
<div class="card-header">@session.Track?.Name</div>
<div class="card-body">
<h5 class="card-title"><a asp-page="Session" asp-route-id="@session.Id">@session.Title</a></h5>
</div>
<div class="card-footer">
<ul class="list-inline mb-0">
@foreach (var speaker in session.Speakers)
{
<li class="list-inline-item">
<a asp-page="Speaker" asp-route-id="@speaker.Id">@speaker.Name</a>
</li>
}
</ul>
<p class="mb-0">
<a authz-policy="Admin" asp-page="/Admin/EditSession" asp-route-id="@session.Id" class="btn btn-default btn-xs">Edit</a>
@{
var isInSession = Model.UserSessions.Contains(session.Id);
var removeClassName = isInSession ? "" : "template";
var addClassName = isInSession ? "template" : "";
}
<button type="submit" name="sessionId" value="@session.Id" asp-page-handler="Remove" class="btn btn-default btn-sm bg-transparent @removeClassName" title="Remove from my personal agenda">
<i class="icon ion-md-star" aria-hidden="true"></i>
</button>
<button type="submit" name="sessionId" value="@session.Id" class="btn btn-default btn-sm bg-transparent @addClassName" title="Add to my personal agenda">
<i class="icon ion-md-star-outline" aria-hidden="true"></i>
</button>
</p>
</div>
</div>
</div>
}
</div>
</div>
}
</form>
</div>
Instead of the HttpExtensions class, we can use the Microsoft.AspNet.WebApi.Client which already has these methods.
Can use the Emulator for local development. EF Core 2.1 will support NoSQL.
A "previous" and "next" link at the end of each session markdown file would make for easy transitions between sessions.
PS C:\Users\geoff\work\ConferencePlanner> dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 3.1.1
Could not find any project in `C:\Users\geoff\work\ConferencePlanner\`.
PS C:\Users\geoff\work\ConferencePlanner> dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 3.1.1
Could not find any project in `C:\Users\geoff\work\ConferencePlanner\`.
I've taken a look at your fine database. I took the liberty to build a diagram using plantuml. It might be easier to understand compared to the one you built using Sql Server Management Studio. Also, some suggestions (to whoever wants to work further with this sample):
For Linux/macOS users or Windows users without Visual Studio, it's actually failry trivial to use SQL Server instead of SQLite if they have Docker installed:
docker run -e ACCEPT_EULA=Y -e SA_PASSWORD=Password12! -p 1433:1433 -d mcr.microsoft.com/mssql/server
Use this conneciton string:
"DefaultConnection": "User ID=sa;Password=Password12!;Database=ConferencePlanner"
When attempting to see Frontend Web Page, you get a HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).
Updated IndexModel
code from OnGetAsync
follows. Key was removing the use of Enumerable.Range
to generate the day offsets based on the start and end time the first and last sessions in the entire conference, but rather looking at the distinct dates in the actual set of sessions being displayed.
var sessions = await GetSessionsAsync();
var startDate = sessions.Min(s => s.StartTime?.Date);
DayOffsets = sessions.Select(s => s.StartTime?.Date)
.Distinct()
.OrderBy(d => d)
.Select(day => ((int)Math.Floor((day.Value - startDate)?.TotalDays ?? 0),
day?.DayOfWeek))
.ToList();
var filterDate = startDate?.AddDays(day);
Sessions = sessions.Where(s => s.StartTime?.Date == filterDate)
.OrderBy(s => s.TrackId)
.GroupBy(s => s.StartTime)
.OrderBy(g => g.Key);
IOException: The handshake failed due to an unexpected packet format.
FrontEnd cannot establish connection with BackEnd api.
Replace with a "ConferenceName" setting in appsetttings.json
There are steps missing from each of the sessions that add pages
I have run into problems when I was trying to add migration for Identity framework in the 4th part of this workshop (https://github.com/dotnet-presentations/aspnetcore-app-workshop/blob/master/docs/4.%20Add%20auth%20features.md).
When I run command Add-Migration CreateIdentitySchema
, the created migration file is wrong. The metods Down() and Up() are empty in it. After spending some time by Googling, I have found out that the instructions in this workshop are missing an important detail - it is necessary to select "FrontEnd" in the Default project drop-down in the Package Manager Console. Without it, BackEnd project is selected and the migration file is empty. I recommend adding this at the end of the first step.
I also recommend adding step 3 that after generating the migration and updating the database, it is necessary to go to the solutions properties and select both FrontEnd and BackEnd as startup projects again.
Let's add a module to teach how to test an ASP.NET Core app with Playwright
System.Net.Http.HttpRequestException: Aucune connexion n’a pu être établie car l’ordinateur cible l’a expressément refusée ---> System.Net.Sockets.SocketException: Aucune connexion n’a pu être établie car l’ordinateur cible l’a expressément refusée
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask
1.get_Result()
at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask
1.get_Result()
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at FrontEnd.Services.ApiClient.GetSessionsAsync() in C:\Users\Maher\Documents\GitHub\aspnetcore-app-workshop\src\FrontEnd\Services\ApiClient.cs:line 63
at FrontEnd.Services.ApiClient.GetSessionsByAttendeeAsync(String name) in C:\Users\Maher\Documents\GitHub\aspnetcore-app-workshop\src\FrontEnd\Services\ApiClient.cs:line 147
at FrontEnd.Pages.IndexModel.OnGetAsync(Int32 day) in C:\Users\Maher\Documents\GitHub\aspnetcore-app-workshop\src\FrontEnd\Pages\Index.cshtml.cs:line 43
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.ExecutorFactory.NonGenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeNextPageFilterAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Internal Server Error https://aspnetcorews-frontend.azurewebsites.net/
HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).
I use Rider, which doesnt have templates for TagHelpers. Adding a line saying adding an empty class would already help.
When I run the FrontEnd project in stage 3 I get the above error for "serviceUrl". The BackEnd project runs as expected. Here is my stacktrace:
System.Uri..ctor(string uriString)
FrontEnd.Startup.b__4_1(HttpClient client) in Startup.cs
client.BaseAddress = new Uri(Configuration["serviceUrl"]);
Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(string name)
Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions+<>c__DisplayClass10_0<TClient, TImplementation>.b__0(IServiceProvider s)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(IServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(IServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine+<>c__DisplayClass1_0.b__0(ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)
lambda_method(Closure , IServiceProvider , object[] )
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelActivatorProvider+<>c__DisplayClass1_0.b__0(PageContext context)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelFactoryProvider+<>c__DisplayClass3_0.b__0(PageContext pageContext)
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.CreateInstance()
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
We should update the data seeding system to use the EF Core 2.1 Data Seeding feature.
This is the current experience for editing the start/end time on the EditSession page:
It currently relies on the default input field rendering for DateTimeOffset
which isn't great, due to issues with the browsers' own pickers not supporting round-trippable formats.
We might have to split the date/time and time-zone offset info into their own input fields with the date/time portion being one, and a time-zone picker being the other, e.g.:
<input name="StartTime.DateTime" type="datetime-local" />
<select name="StartTime.Offset"> ...
@spboyer has details
The ApiClient and related code should be reviewed to take advantage for HttpClientFactory features.
In the initial instruction of Session 1, while clear steps have been enunciated for command line, the Visual Studio code has been left to the discretion of workshop participant.
In VS, perhaps we can give a name to the solution. But more importantly we need to mention that VS Project created should be named 'Backend'. This step is only made explicit for the cmdline users.
Adding this here to surface it in case it can bubble its way up to the right spot; feel free to close if there's nowhere for this to go.
In the first section of the course, it references using the codegenerator to scaffold a controller:
dotnet aspnet-codegenerator controller -api -name SpeakersController -m Speaker -dc BackEnd.Models.ApplicationDbContext -outDir Controllers
However, no matter what framework I specify, when I run this command, I see:
The specified framework 'Microsoft.NETCore.App', version '2.1.5' was not found.
I don't yet have 2.1.5
but I expected this would be able to work on 2.1.x`.
dotnet --list-sdks
:
dotnet --list-runtimes
:
I found a suspicious property quoted from the repository as follows.
public class Speaker : ConferenceDTO.Speaker
{
public virtual ICollection<SessionSpeaker> SessionSpeakers { get; set; } = new List<SessionSpeaker>();
}
I don't understand why the initialized collection is made mutable?
i was following the insructtion until i stoped at the frontend chapitre because the PostAsJsonAsync Is not valid anymore in this dll System.Net.Http also the other methods ReadAsAsync after my reserch after on google
I found ConferencePlannerArchitectureDiagram.svg is still showing dot net core 2.0 and 2.2 but this demo presentation is updated to 3.0 so kindly update Diagram thanks
Twitter requires application and approval. This takes about 2 weeks.
Facebook is immediate (for now) and easier than Google.
I've been following the steps and at the end of Session 2, when I run the app and go the "/swagger" url I get an exception about "Conflicting schemaIds".
It's just me?
I fixed it by adding this to the swagger configuration in the startup.cs:
options.CustomSchemaIds(x => x.FullName);
Exception details:
System.InvalidOperationException: Conflicting schemaIds: Identical schemaIds detected for types BackEnd.Data.Speaker and ConferenceDTO.Speaker. See config settings - "CustomSchemaIds" for a workaround at Swashbuckle.AspNetCore.SwaggerGen.SchemaIdManager.IdFor(Type type) at Swashbuckle.AspNetCore.SwaggerGen.SchemaRegistry.CreateReferenceSchema(Type type, Queue
1 referencedTypes)
at Swashbuckle.AspNetCore.SwaggerGen.SchemaRegistry.GetOrRegister(Type type)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreateBodyParameter(ApiParameterDescription apiParameterDescription, String name, Boolean isRequired, ISchemaRegistry schemaRegistry)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreateParameter(ApiDescription apiDescription, ApiParameterDescription apiParameterDescription, ISchemaRegistry schemaRegistry)
at System.Linq.Enumerable.WhereSelectListIterator2.ToList() at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreateOperation(ApiDescription apiDescription, ISchemaRegistry schemaRegistry)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreatePathItem(IEnumerable1 apiDescriptions, ISchemaRegistry schemaRegistry) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable
1 source, Func2 keySelector, Func
2 elementSelector, IEqualityComparer1 comparer) at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreatePathItems(IEnumerable
1 apiDescriptions, ISchemaRegistry schemaRegistry)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath, String[] schemes)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT1.ProcessRequestAsync()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.