| using ProtoBuf; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Text.Json.Serialization; | |||||
| using System.Threading.Tasks; | |||||
| namespace Grpc.Shared.DTOs.Search | |||||
| { | |||||
| [ProtoContract] | |||||
| internal class SearchDTO | |||||
| { | |||||
| public partial class SearchContracts | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Tracks? Tracks { get; set; } | |||||
| } | |||||
| public partial class Tracks | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Items[]? Items { get; set; } | |||||
| } | |||||
| public partial class Items | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Album Album { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Artist[] Artists { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public long DurationMs { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public ExternalUrls ExternalUrls { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(7)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(8)] | |||||
| public long Popularity { get; set; } | |||||
| [ProtoMember(9)] | |||||
| public long TrackNumber { get; set; } | |||||
| [ProtoMember(10)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(11)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| public partial class Album | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public Image[] Images { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public DateTimeOffset ReleaseDate { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public long TotalTracks { get; set; } | |||||
| [ProtoMember(7)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(8)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| public partial class Image | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public long Height { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Uri Url { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public long Width { get; set; } | |||||
| } | |||||
| public partial class Artist | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public ExternalUrls ExternalUrls { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| public partial class ExternalUrls | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Spotify { get; set; } | |||||
| } | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Grpc.Shared.DTOs.Search | |||||
| { | |||||
| internal class SearchRequestDTO | |||||
| { | |||||
| } | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk"> | |||||
| <PropertyGroup> | |||||
| <TargetFramework>net6.0</TargetFramework> | |||||
| <ImplicitUsings>enable</ImplicitUsings> | |||||
| <Nullable>enable</Nullable> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <PackageReference Include="protobuf-net.Core" Version="3.1.17" /> | |||||
| <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" /> | |||||
| </ItemGroup> | |||||
| </Project> |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Runtime.Serialization; | |||||
| using System.ServiceModel; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace GrpcShared.Interfaces | |||||
| { | |||||
| [ServiceContract] | |||||
| public interface ISearchService | |||||
| { | |||||
| Task<SearchResult> SearchTracks(SearchRequest req); | |||||
| } | |||||
| [DataContract] | |||||
| public class SearchResult | |||||
| { | |||||
| [DataMember(Order = 1)] | |||||
| public string NewQuery { get; set; } | |||||
| [DataMember(Order = 2)] | |||||
| public string NewType { get; set; } | |||||
| } | |||||
| [DataContract] | |||||
| public class SearchRequest | |||||
| { | |||||
| [DataMember(Order = 1)] | |||||
| public string Query { get; set; } | |||||
| [DataMember(Order = 2)] | |||||
| public string Type { get; set; } = "track"; | |||||
| } | |||||
| } |
| using ProtoBuf; | |||||
| namespace GrpcShared | |||||
| { | |||||
| [ProtoContract] | |||||
| public class AuthParams | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public string ClientId { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public string RedirectURI { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public string Scope { get; set; } | |||||
| } | |||||
| } |
| using ProtoBuf; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace GrpcShared.DTO.Auth | |||||
| { | |||||
| [ProtoContract] | |||||
| public class AuthRequest | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public string ClientId { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public string ClientSecret { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public string RedirectURI { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public string ResponseType { get; set; } = "track"; | |||||
| [ProtoMember(5)] | |||||
| public string Scope { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public string ShowDialog{ get; set; } | |||||
| } | |||||
| } |
| using ProtoBuf; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace GrpcShared.DTO.Auth | |||||
| { | |||||
| [ProtoContract] | |||||
| public class AuthResponse | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public string AccessToken { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public string RefreshToken{ get; set; } | |||||
| } | |||||
| } |
| using ProtoBuf; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace GrpcShared.DTO.Auth | |||||
| { | |||||
| [ProtoContract] | |||||
| public class CodeResponse | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public string Code { get; set; } | |||||
| } | |||||
| } |
| using ProtoBuf; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace GrpcShared.DTO.Search | |||||
| { | |||||
| [ProtoContract] | |||||
| public class SearchDetails | |||||
| { | |||||
| [ProtoContract] | |||||
| public partial class SearchContracts | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Tracks? Tracks { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Tracks | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Item[]? Items { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Item | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Album Album { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Artist[] Artists { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public long DurationMs { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public ExternalUrls ExternalUrls { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(7)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(8)] | |||||
| public long Popularity { get; set; } | |||||
| [ProtoMember(9)] | |||||
| public long TrackNumber { get; set; } | |||||
| [ProtoMember(10)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(11)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Album | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public Image[] Images { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public DateTimeOffset ReleaseDate { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public long TotalTracks { get; set; } | |||||
| [ProtoMember(7)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(8)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Image | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public long Height { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Uri Url { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public long Width { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Artist | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public ExternalUrls ExternalUrls { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class ExternalUrls | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Spotify { get; set; } | |||||
| } | |||||
| } | |||||
| } |
| using ProtoBuf; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace GrpcShared.DTO.Search | |||||
| { | |||||
| [ProtoContract] | |||||
| public class SearchRequest | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public string Query { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public string Include_External { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public int Limit { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public int Offset { get; set; } | |||||
| } | |||||
| } |
| using ProtoBuf; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace GrpcShared.DTO.Search | |||||
| { | |||||
| [ProtoContract] | |||||
| public class SearchResponse | |||||
| { | |||||
| [ProtoContract] | |||||
| public partial class SearchContracts | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Tracks? Tracks { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Tracks | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public List<Item>? Items { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Item | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Album? Album { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Artist[] Artists { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public long DurationMs { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public ExternalUrls ExternalUrls { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(7)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(8)] | |||||
| public long Popularity { get; set; } | |||||
| [ProtoMember(9)] | |||||
| public long TrackNumber { get; set; } | |||||
| [ProtoMember(10)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(11)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Album | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public Image[] Images { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public DateTimeOffset ReleaseDate { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public long TotalTracks { get; set; } | |||||
| [ProtoMember(7)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(8)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Image | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public long Height { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Uri Url { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public long Width { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class Artist | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public ExternalUrls ExternalUrls { get; set; } | |||||
| [ProtoMember(2)] | |||||
| public Uri Href { get; set; } | |||||
| [ProtoMember(3)] | |||||
| public string Id { get; set; } | |||||
| [ProtoMember(4)] | |||||
| public string Name { get; set; } | |||||
| [ProtoMember(5)] | |||||
| public string Type { get; set; } | |||||
| [ProtoMember(6)] | |||||
| public string Uri { get; set; } | |||||
| } | |||||
| [ProtoContract] | |||||
| public partial class ExternalUrls | |||||
| { | |||||
| [ProtoMember(1)] | |||||
| public Uri Spotify { get; set; } | |||||
| } | |||||
| } | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk"> | |||||
| <PropertyGroup> | |||||
| <OutputType>Library</OutputType> | |||||
| <TargetFramework>net6.0</TargetFramework> | |||||
| <ImplicitUsings>enable</ImplicitUsings> | |||||
| <Nullable>enable</Nullable> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" /> | |||||
| <PackageReference Include="protobuf-net.BuildTools" Version="3.1.17"> | |||||
| <PrivateAssets>all</PrivateAssets> | |||||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||||
| </PackageReference> | |||||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | |||||
| </ItemGroup> | |||||
| </Project> |
| using GrpcShared.DTO.Auth; | |||||
| using ProtoBuf.Grpc.Configuration; | |||||
| namespace GrpcShared.Interfaces | |||||
| { | |||||
| [Service] | |||||
| public interface IAuthService | |||||
| { | |||||
| Task<CodeResponse> GetCode(AuthRequest request); | |||||
| Task<AuthResponse> GetAccessToken(CodeResponse code); | |||||
| Task<AuthParams> GetAuthParams(); | |||||
| } | |||||
| } |
| using GrpcShared.DTO.Search; | |||||
| using ProtoBuf.Grpc.Configuration; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace GrpcShared.Interfaces | |||||
| { | |||||
| [Service] | |||||
| public interface ISearchService | |||||
| { | |||||
| Task<SearchResponse> ListSearchAsync(SearchRequest request); | |||||
| } | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk.Web"> | |||||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | |||||
| <PropertyGroup> | <PropertyGroup> | ||||
| <TargetFramework>net6.0</TargetFramework> | <TargetFramework>net6.0</TargetFramework> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Protobuf Include="Protos\greet.proto" GrpcServices="Server" /> | |||||
| <Protobuf Include="Protos\auth.proto" GrpcServices="Server" /> | |||||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||||
| <PackageReference Include="Grpc.AspNetCore.Web" Version="2.47.0" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.8" /> | |||||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | |||||
| <PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.152" /> | |||||
| <PackageReference Include="protobuf-net.Grpc.AspNetCore.Reflection" Version="1.0.152" /> | |||||
| <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" /> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||||
| <ProjectReference Include="..\GrpcShared\GrpcShared.csproj" /> | |||||
| <ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" /> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| </Project> | </Project> |
| using GrpcShared; | |||||
| using IdentityProvider.Services; | using IdentityProvider.Services; | ||||
| using Microsoft.AspNetCore.Server.Kestrel.Core; | |||||
| using ProtoBuf.Grpc.Server; | |||||
| using Microsoft.Extensions.Options; | |||||
| var builder = WebApplication.CreateBuilder(args); | var builder = WebApplication.CreateBuilder(args); | ||||
| #if DEBUG | |||||
| builder.WebHost.ConfigureKestrel(options => | |||||
| { | |||||
| options.ListenLocalhost(5050, o => o.Protocols = | |||||
| HttpProtocols.Http2); | |||||
| options.ListenLocalhost(5051, o => o.Protocols = | |||||
| HttpProtocols.Http1AndHttp2); | |||||
| }); | |||||
| #endif | |||||
| builder.Services.AddOptions(); | |||||
| // Additional configuration is required to successfully run gRPC on macOS. | // Additional configuration is required to successfully run gRPC on macOS. | ||||
| // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682 | // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682 | ||||
| builder.Services.Configure<AuthParams>(builder.Configuration.GetSection("AuthParams")); | |||||
| builder.Services.AddControllersWithViews(); | |||||
| builder.Services.AddRazorPages(); | |||||
| builder.Services.AddEndpointsApiExplorer(); | |||||
| // Add services to the container. | |||||
| builder.Services.AddGrpc(); | builder.Services.AddGrpc(); | ||||
| builder.Services.AddCodeFirstGrpc(); | |||||
| builder.Services.AddCodeFirstGrpcReflection(); | |||||
| var app = builder.Build(); | var app = builder.Build(); | ||||
| // Configure the HTTP request pipeline. | // Configure the HTTP request pipeline. | ||||
| app.MapGrpcService<GreeterService>(); | |||||
| app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); | |||||
| if (app.Environment.IsDevelopment()) | |||||
| { | |||||
| app.UseWebAssemblyDebugging(); | |||||
| } | |||||
| else | |||||
| { | |||||
| app.UseExceptionHandler("/Error"); | |||||
| // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. | |||||
| app.UseHsts(); | |||||
| } | |||||
| app.UseHttpsRedirection(); | |||||
| app.UseBlazorFrameworkFiles(); | |||||
| app.UseStaticFiles(); | |||||
| app.UseRouting(); | |||||
| app.UseGrpcWeb(); | |||||
| app.MapRazorPages(); | |||||
| app.MapControllers(); | |||||
| //app.MapGrpcService<WeatherService>(); | |||||
| app.MapGrpcService<AuthService>().EnableGrpcWeb(); | |||||
| app.MapCodeFirstGrpcReflectionService(); | |||||
| app.MapFallbackToFile("index.html"); | |||||
| app.Run(); | |||||
| app.Run(); |
| { | { | ||||
| "iisSettings": { | |||||
| "windowsAuthentication": false, | |||||
| "anonymousAuthentication": true, | |||||
| "iisExpress": { | |||||
| "applicationUrl": "http://localhost:28725", | |||||
| "sslPort": 44342 | |||||
| } | |||||
| }, | |||||
| "profiles": { | "profiles": { | ||||
| "IIS Express": { | |||||
| "commandName": "IISExpress", | |||||
| "launchBrowser": true, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "environmentVariables": { | |||||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||||
| } | |||||
| }, | |||||
| "IdentityProvider": { | "IdentityProvider": { | ||||
| "commandName": "Project", | "commandName": "Project", | ||||
| "dotnetRunMessages": true, | |||||
| "launchBrowser": false, | |||||
| "applicationUrl": "http://localhost:5164;https://localhost:7164", | |||||
| "dotnetRunMessages": "true", | |||||
| "launchBrowser": true, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "applicationUrl": "https://localhost:5001;http://localhost:5000", | |||||
| "environmentVariables": { | "environmentVariables": { | ||||
| "ASPNETCORE_ENVIRONMENT": "Development" | "ASPNETCORE_ENVIRONMENT": "Development" | ||||
| } | } |
| syntax = "proto3"; | |||||
| option csharp_namespace = "IdentityProvider.Protos"; | |||||
| package auth; | |||||
| service AuthorizationService { | |||||
| rpc RedirectUser(AuthParams) returns (AuthResponse); | |||||
| rpc GetAccessToken(AuthResponse) returns (AccessResponse); | |||||
| } | |||||
| message AuthParams{ | |||||
| string client_id = 1; | |||||
| string redirect_uri = 2; | |||||
| string response_type = 3; | |||||
| string scope = 4; | |||||
| bool show_dialog = 5; | |||||
| } | |||||
| message AuthResponse { | |||||
| string code = 1; | |||||
| } | |||||
| message AccessResponse { | |||||
| string access_token = 1; | |||||
| } |
| syntax = "proto3"; | |||||
| option csharp_namespace = "IdentityProvider"; | |||||
| package greet; | |||||
| // The greeting service definition. | |||||
| service Greeter { | |||||
| // Sends a greeting | |||||
| rpc SayHello (HelloRequest) returns (HelloReply); | |||||
| } | |||||
| // The request message containing the user's name. | |||||
| message HelloRequest { | |||||
| string name = 1; | |||||
| } | |||||
| // The response message containing the greetings. | |||||
| message HelloReply { | |||||
| string message = 1; | |||||
| } |
| using IdentityProvider.Protos.AuthService; | |||||
| //using IdentityProvider.Protos.AuthService; | |||||
| using GrpcShared; | |||||
| using GrpcShared.DTO.Auth; | |||||
| using GrpcShared.Interfaces; | |||||
| using Microsoft.Extensions.Options; | |||||
| namespace IdentityProvider.Services | namespace IdentityProvider.Services | ||||
| { | { | ||||
| public class AuthService : AuthorizationService.AuthorizationServiceBase | |||||
| public class AuthService : IAuthService | |||||
| { | { | ||||
| private readonly ILogger<AuthService> _logger; | private readonly ILogger<AuthService> _logger; | ||||
| public AuthService(ILogger<AuthService> logger) | |||||
| private readonly AuthParams _params; | |||||
| public AuthService(ILogger<AuthService> logger, IOptions<AuthParams> options ) | |||||
| { | { | ||||
| _logger = logger; | _logger = logger; | ||||
| _params = options.Value; | |||||
| } | } | ||||
| public Task<AuthResponse> GetAccessToken(CodeResponse code) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| public Task<CodeResponse> GetCode(AuthRequest request) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| public async Task<AuthParams> GetAuthParams() | |||||
| { | |||||
| var authParams = new AuthParams { | |||||
| ClientId = _params.ClientId, | |||||
| RedirectURI = _params.RedirectURI, | |||||
| Scope =_params.Scope }; | |||||
| return await Task.FromResult(authParams); | |||||
| } | |||||
| } | } | ||||
| } | } |
| using Grpc.Core; | |||||
| using IdentityProvider; | |||||
| namespace IdentityProvider.Services | |||||
| { | |||||
| public class GreeterService : Greeter.GreeterBase | |||||
| { | |||||
| private readonly ILogger<GreeterService> _logger; | |||||
| public GreeterService(ILogger<GreeterService> logger) | |||||
| { | |||||
| _logger = logger; | |||||
| } | |||||
| public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) | |||||
| { | |||||
| return Task.FromResult(new HelloReply | |||||
| { | |||||
| Message = "Hello " + request.Name | |||||
| }); | |||||
| } | |||||
| } | |||||
| } |
| "EndpointDefaults": { | "EndpointDefaults": { | ||||
| "Protocols": "Http2" | "Protocols": "Http2" | ||||
| } | } | ||||
| }, | |||||
| "AuthParams": { | |||||
| "ClientId": "83e1d09876b049c4bb1953185a4b3bfb", | |||||
| "RedirectURI": "https://localhost:44342/callback", | |||||
| "Scope": "user-read-currently-playing user-read-email user-library-modify user-top-read" | |||||
| } | } | ||||
| } | } |
| EndProject | EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityProvider", "IdentityProvider\IdentityProvider.csproj", "{D160945A-5068-4D6A-A09D-5DD7A9EFBC01}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityProvider", "IdentityProvider\IdentityProvider.csproj", "{D160945A-5068-4D6A-A09D-5DD7A9EFBC01}" | ||||
| EndProject | EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GrpcShared", "GrpcShared\GrpcShared.csproj", "{C142D6DF-066A-4ADA-86A3-1C736136C1FA}" | |||||
| EndProject | |||||
| Global | Global | ||||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| Debug|Any CPU = Debug|Any CPU | Debug|Any CPU = Debug|Any CPU | ||||
| {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Debug|Any CPU.Build.0 = Debug|Any CPU | {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Release|Any CPU.ActiveCfg = Release|Any CPU | {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Release|Any CPU.Build.0 = Release|Any CPU | {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| {C142D6DF-066A-4ADA-86A3-1C736136C1FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
| {C142D6DF-066A-4ADA-86A3-1C736136C1FA}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
| {C142D6DF-066A-4ADA-86A3-1C736136C1FA}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
| {C142D6DF-066A-4ADA-86A3-1C736136C1FA}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
| EndGlobalSection | EndGlobalSection | ||||
| GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
| HideSolutionNode = FALSE | HideSolutionNode = FALSE |
| <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> | |||||
| <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> | |||||
| <PropertyGroup> | <PropertyGroup> | ||||
| <TargetFramework>net6.0</TargetFramework> | <TargetFramework>net6.0</TargetFramework> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <PackageReference Include="Grpc.Net.Client" Version="2.47.0" /> | |||||
| <PackageReference Include="Grpc.Net.Client.Web" Version="2.47.0" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.7" /> | <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.7" /> | ||||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.7" PrivateAssets="all" /> | <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.7" PrivateAssets="all" /> | ||||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <ProjectReference Include="..\GrpcShared\GrpcShared.csproj" /> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| </Project> | </Project> |
| @page "/" | @page "/" | ||||
| @using Grpc.Net.Client | |||||
| @using Grpc.Net.Client.Web | |||||
| @using GrpcShared | |||||
| @using GrpcShared.DTO.Auth | |||||
| @using NemAnBlazor.Services.Interfaces | |||||
| @inject NavigationManager NavigationManager | @inject NavigationManager NavigationManager | ||||
| @inject IAuthClientService AuthService | |||||
| @*@inject ISearchClientService SearchService*@ | |||||
| <PageTitle>Index</PageTitle> | <PageTitle>Index</PageTitle> | ||||
| <h1>Pozdrav Diligent!</h1> | <h1>Pozdrav Diligent!</h1> | ||||
| Dobrodošli u našu NemAn aplikaciju. | Dobrodošli u našu NemAn aplikaciju. | ||||
| <button class="btn-outline-success" @onclick="SpotifyRedirect">Spotify</button> | |||||
| @code{ | |||||
| private void SpotifyRedirect() | |||||
| @code { | |||||
| protected override async Task OnInitializedAsync() | |||||
| { | { | ||||
| NavigationManager.NavigateTo( | |||||
| "https://accounts.spotify.com/en/authorize?client_id=83e1d09876b049c4bb1953185a4b3bfb&redirect_uri=https%3A%2F%2Flocalhost%3A7229%2F&response_type=code&scope=user-read-currently-playing%20user-read-email%20user-library-modify%20user-top-read%0A%0A%0A&show_dialog=true"); | |||||
| //var response = await SearchService.GetListSearchAsync(new GrpcShared.DTO.Search.SearchRequest() { Query="venom", Type = "track"}); | |||||
| AuthParams authParams = await AuthService.GetAuthParams(); | |||||
| // await AuthService.GetAccessToken(new CodeResponse{ Code = "hello"}); | |||||
| AuthRequest request = new() { ResponseType = "code", Scope = authParams.Scope, ClientId = authParams.ClientId, RedirectURI = authParams.RedirectURI}; | |||||
| string url = $"https://accounts.spotify.com/en/authorize?client_id={request.ClientId}&redirect_uri={request.RedirectURI}&response_type={request.ResponseType}&scope={request.Scope}&show_dialog=true"; | |||||
| NavigationManager.NavigateTo(url); | |||||
| } | } | ||||
| } | } |
| using Grpc.Net.Client; | |||||
| using Grpc.Net.Client.Web; | |||||
| using Microsoft.AspNetCore.Components; | |||||
| using Microsoft.AspNetCore.Components.Web; | using Microsoft.AspNetCore.Components.Web; | ||||
| using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | ||||
| using NemAnBlazor; | using NemAnBlazor; | ||||
| using NemAnBlazor.Services; | |||||
| using NemAnBlazor.Services.Interfaces; | |||||
| var builder = WebAssemblyHostBuilder.CreateDefault(args); | var builder = WebAssemblyHostBuilder.CreateDefault(args); | ||||
| builder.RootComponents.Add<App>("#app"); | builder.RootComponents.Add<App>("#app"); | ||||
| builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); | ||||
| builder.Services.AddScoped(_ => | |||||
| { | |||||
| var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); | |||||
| var channel = GrpcChannel.ForAddress(builder.HostEnvironment.BaseAddress, new GrpcChannelOptions { HttpHandler = grpcWebHandler }); | |||||
| return channel; | |||||
| }); | |||||
| builder.Services.AddScoped<ISearchClientService, SearchClientService>(); | |||||
| builder.Services.AddScoped<IAuthClientService, AuthClientService>(); | |||||
| await builder.Build().RunAsync(); | await builder.Build().RunAsync(); | ||||
| { | { | ||||
| "iisSettings": { | "iisSettings": { | ||||
| "windowsAuthentication": false, | "windowsAuthentication": false, | ||||
| "anonymousAuthentication": true, | |||||
| "iisExpress": { | |||||
| "applicationUrl": "http://localhost:50338", | |||||
| "sslPort": 44375 | |||||
| } | |||||
| "anonymousAuthentication": true | |||||
| }, | }, | ||||
| "profiles": { | "profiles": { | ||||
| "NemAnCore": { | "NemAnCore": { | ||||
| "commandName": "Project", | "commandName": "Project", | ||||
| "dotnetRunMessages": true, | |||||
| "launchBrowser": true, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "applicationUrl": "https://localhost:7229;http://localhost:5229", | |||||
| "environmentVariables": { | |||||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||||
| } | |||||
| }, | |||||
| "IIS Express": { | |||||
| "commandName": "IISExpress", | |||||
| "launchBrowser": true, | "launchBrowser": true, | ||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "environmentVariables": { | "environmentVariables": { | ||||
| "ASPNETCORE_ENVIRONMENT": "Development" | "ASPNETCORE_ENVIRONMENT": "Development" | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| using Grpc.Net.Client; | |||||
| using GrpcShared.DTO.Auth; | |||||
| using GrpcShared.Interfaces; | |||||
| using NemAnBlazor.Services.Interfaces; | |||||
| using ProtoBuf.Grpc.Client; | |||||
| using GrpcShared; | |||||
| namespace NemAnBlazor.Services | |||||
| { | |||||
| public class AuthClientService : IAuthClientService | |||||
| { | |||||
| private IAuthService _serviceClient; | |||||
| public AuthClientService(GrpcChannel grpcChannel) | |||||
| { | |||||
| _serviceClient = grpcChannel.CreateGrpcService<IAuthService>(); | |||||
| } | |||||
| public async Task<AuthResponse> GetAccessToken(CodeResponse code) | |||||
| { | |||||
| return await _serviceClient.GetAccessToken(code); | |||||
| } | |||||
| public async Task <AuthParams> GetAuthParams() | |||||
| { | |||||
| return await _serviceClient.GetAuthParams(); | |||||
| } | |||||
| public Task<CodeResponse> GetCode(AuthRequest request) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| } | |||||
| } |
| using GrpcShared; | |||||
| using GrpcShared.DTO.Auth; | |||||
| namespace NemAnBlazor.Services.Interfaces | |||||
| { | |||||
| public interface IAuthClientService | |||||
| { | |||||
| Task<CodeResponse> GetCode(AuthRequest request); | |||||
| Task<AuthResponse> GetAccessToken(CodeResponse code); | |||||
| Task<AuthParams> GetAuthParams(); | |||||
| } | |||||
| } |
| using GrpcShared.DTO.Search; | |||||
| namespace NemAnBlazor.Services.Interfaces | |||||
| { | |||||
| public interface ISearchClientService | |||||
| { | |||||
| Task<SearchResponse> GetListSearchAsync(SearchRequest request); | |||||
| } | |||||
| } |
| using GrpcShared.DTO.Search; | |||||
| using GrpcShared.Interfaces; | |||||
| using NemAnBlazor.Services.Interfaces; | |||||
| namespace NemAnBlazor.Services | |||||
| { | |||||
| public class SearchClientService : ISearchClientService | |||||
| { | |||||
| private ISearchService _serviceClient; | |||||
| public SearchClientService(ISearchService serviceClient) | |||||
| { | |||||
| _serviceClient = serviceClient; | |||||
| } | |||||
| public async Task<SearchResponse> GetListSearchAsync(SearchRequest request) | |||||
| { | |||||
| return await _serviceClient.ListSearchAsync(request); | |||||
| } | |||||
| } | |||||
| } |
| <ItemGroup> | <ItemGroup> | ||||
| <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> | <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> | ||||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| </Project> | </Project> |
| using gRPCServer.Services; | |||||
| using Microsoft.AspNetCore.Server.Kestrel.Core; | |||||
| using ProtoBuf.Grpc.Server; | |||||
| using SpotifyService.Services; | |||||
| var builder = WebApplication.CreateBuilder(args); | var builder = WebApplication.CreateBuilder(args); | ||||
| // Additional configuration is required to successfully run gRPC on macOS. | |||||
| // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682 | |||||
| #if DEBUG | |||||
| /* | |||||
| builder.WebHost.ConfigureKestrel(options => | |||||
| { | |||||
| options.ListenLocalhost(5050, o => o.Protocols = | |||||
| HttpProtocols.Http2); | |||||
| options.ListenLocalhost(5051, o => o.Protocols = | |||||
| HttpProtocols.Http1AndHttp2); | |||||
| }); | |||||
| */ | |||||
| #endif | |||||
| // Add services to the container. | // Add services to the container. | ||||
| builder.Services.AddControllersWithViews(); | |||||
| builder.Services.AddRazorPages(); | |||||
| builder.Services.AddEndpointsApiExplorer(); | |||||
| builder.Services.AddSwaggerGen(); | |||||
| builder.Services.AddGrpc(); | builder.Services.AddGrpc(); | ||||
| builder.Services.AddCodeFirstGrpc(); | |||||
| builder.Services.AddCodeFirstGrpcReflection(); | |||||
| var app = builder.Build(); | var app = builder.Build(); | ||||
| app.UseSwagger(); | |||||
| app.UseSwaggerUI(); | |||||
| // Configure the HTTP request pipeline. | // Configure the HTTP request pipeline. | ||||
| app.MapGrpcService<GreeterService>(); | |||||
| app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); | |||||
| if (app.Environment.IsDevelopment()) | |||||
| { | |||||
| app.UseWebAssemblyDebugging(); | |||||
| } | |||||
| else | |||||
| { | |||||
| app.UseExceptionHandler("/Error"); | |||||
| // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. | |||||
| app.UseHsts(); | |||||
| } | |||||
| app.UseHttpsRedirection(); | |||||
| app.UseBlazorFrameworkFiles(); | |||||
| app.UseStaticFiles(); | |||||
| app.UseRouting(); | |||||
| app.UseGrpcWeb(); | |||||
| app.MapRazorPages(); | |||||
| app.MapControllers(); | |||||
| //app.MapGrpcService<WeatherService>(); | |||||
| app.MapGrpcService<SearchService>().EnableGrpcWeb(); | |||||
| app.MapCodeFirstGrpcReflectionService(); | |||||
| app.MapFallbackToFile("index.html"); | |||||
| app.Run(); | app.Run(); |
| { | { | ||||
| "iisSettings": { | |||||
| "windowsAuthentication": false, | |||||
| "anonymousAuthentication": true, | |||||
| "iisExpress": { | |||||
| "applicationUrl": "http://localhost:28725", | |||||
| "sslPort": 44342 | |||||
| } | |||||
| }, | |||||
| "profiles": { | "profiles": { | ||||
| "gRPCServer": { | |||||
| "IIS Express": { | |||||
| "commandName": "IISExpress", | |||||
| "launchBrowser": true, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "environmentVariables": { | |||||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||||
| } | |||||
| }, | |||||
| "SpotifyService": { | |||||
| "commandName": "Project", | "commandName": "Project", | ||||
| "dotnetRunMessages": true, | |||||
| "launchBrowser": false, | |||||
| "applicationUrl": "http://localhost:5251;https://localhost:7251", | |||||
| "dotnetRunMessages": "true", | |||||
| "launchBrowser": true, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "applicationUrl": "https://localhost:5001;http://localhost:5000", | |||||
| "environmentVariables": { | "environmentVariables": { | ||||
| "ASPNETCORE_ENVIRONMENT": "Development" | "ASPNETCORE_ENVIRONMENT": "Development" | ||||
| } | } |
| syntax = "proto3"; | |||||
| option csharp_namespace = "gRPCServer"; | |||||
| package greet; | |||||
| // The greeting service definition. | |||||
| service Greeter { | |||||
| // Sends a greeting | |||||
| rpc SayHello (HelloRequest) returns (HelloReply); | |||||
| } | |||||
| // The request message containing the user's name. | |||||
| message HelloRequest { | |||||
| string name = 1; | |||||
| } | |||||
| // The response message containing the greetings. | |||||
| message HelloReply { | |||||
| string message = 1; | |||||
| } |
| using Grpc.Core; | |||||
| using gRPCServer; | |||||
| namespace gRPCServer.Services | |||||
| { | |||||
| public class GreeterService : Greeter.GreeterBase | |||||
| { | |||||
| private readonly ILogger<GreeterService> _logger; | |||||
| public GreeterService(ILogger<GreeterService> logger) | |||||
| { | |||||
| _logger = logger; | |||||
| } | |||||
| public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) | |||||
| { | |||||
| return Task.FromResult(new HelloReply | |||||
| { | |||||
| Message = "Hello " + request.Name | |||||
| }); | |||||
| } | |||||
| } | |||||
| } |
| using Grpc.Core; | |||||
| using System.Text.Json; | |||||
| namespace SpotifyService.Services | |||||
| { | |||||
| public class SearchService | |||||
| { | |||||
| private readonly IHttpClientFactory _httpClientFactory; | |||||
| public SearchService(IHttpClientFactory httpClientFactory) | |||||
| { | |||||
| _httpClientFactory = httpClientFactory; | |||||
| } | |||||
| } | |||||
| } | |||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Protobuf Include="Protos\greet.proto" GrpcServices="Server" /> | |||||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||||
| <PackageReference Include="Grpc.AspNetCore.Web" Version="2.47.0" /> | |||||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.8" /> | |||||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | |||||
| <PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.152" /> | |||||
| <PackageReference Include="protobuf-net.Grpc.AspNetCore.Reflection" Version="1.0.152" /> | |||||
| <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||||
| <ProjectReference Include="..\GrpcShared\GrpcShared.csproj" /> | |||||
| <ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" /> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| </Project> | </Project> |
| "AllowedHosts": "*", | "AllowedHosts": "*", | ||||
| "Kestrel": { | "Kestrel": { | ||||
| "EndpointDefaults": { | "EndpointDefaults": { | ||||
| "Protocols": "Http2" | |||||
| "Protocols": "Http1AndHttp2" | |||||
| } | } | ||||
| } | } | ||||
| } | } |