【发布时间】:2019-12-16 13:52:02
【问题描述】:
我在 Blazor 客户端托管应用程序中执行 API 请求时收到 HTTP 500。如果我省略控制器参数,则请求成功,但是,一旦我在控制器内设置参数,我就会得到 HTTP 500。
我已经检查并测试了容器并注册了接口。只要我不在服务器控制器构造函数中提供参数,客户端就可以工作。
我需要做什么才能在 blazor 应用程序的服务器控制器中注入构造函数?
在撰写本文时,我正在使用 Visual Studio 2019 16.2 预览版 4 和 .NET Core 3 预览版。
Startup.cs
public class Startup
{
private readonly IDependency _dependency;
public Startup()
{
_dependency = new Dependency();
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson();
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});
_dependency
.SetServiceCollection(services)
.SetServiceProvider(services.BuildServiceProvider());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBlazorDebugging();
}
app.UseClientSideBlazorFiles<Client.Startup>();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
});
_dependency
.SetWebHostEnvironment(env)
.ConfigureDependencies()
.ConfigureDatabases();
}
}
Dependency.cs
public class Dependency : IDependency
{
private IServiceCollection _services;
private IServiceProvider _provider;
private IWebHostEnvironment _environment;
public IDependency SetServiceCollection(IServiceCollection services)
{
if (_services != null)
throw new AlreadyConfiguredException($"{nameof(services)} is already configured.");
_services = services;
return this;
}
public IDependency SetServiceProvider(IServiceProvider provider)
{
if (_provider != null)
throw new AlreadyConfiguredException($"{nameof(provider)} is already configured.");
_provider = provider;
return this;
}
public IDependency SetWebHostEnvironment(IWebHostEnvironment environment)
{
if (_environment != null)
throw new AlreadyConfiguredException($"{nameof(environment)} is already configured.");
_environment = environment;
return this;
}
public IDependency ConfigureDatabases()
{
var builder = new ConfigurationBuilder()
.SetBasePath(_environment.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{_environment.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
var config = builder.Build();
var database = config.GetConnectionString("MenuDatabase");
MenuStartup.Configure(_services, database);
OpeningTimeStartup.Configure(_services, database);
return this;
}
public IDependency ConfigureDependencies()
{
// Bounded Contexts
// Domain Models
_services.AddTransient<IMenu, Menu.Menu>();
// Infrastructure
_services.AddTransient(typeof(IRepository<,>), typeof(Repository<,>));
_services.AddTransient<IFactory, Factory>();
_services.AddSingleton<ICompositeCache, MemoryCompositeCache>();
_services.AddTransient<IDataContextFactory, DataContextFactory>();
_services.AddTransient<IMenuRepository, MenuRepository>();
return this;
}
}
IDependency.cs
public interface IDependency
{
IDependency SetServiceCollection(IServiceCollection services);
IDependency SetServiceProvider(IServiceProvider buildServiceProvider);
IDependency ConfigureDependencies();
IDependency SetWebHostEnvironment(IWebHostEnvironment environment);
IDependency ConfigureDatabases();
}
MenuDataController.cs
[Route("api/[controller]")]
public class MenuDataController : Controller
{
private readonly IMenu _menu;
public MenuDataController(IMenu menu)
{
_menu = menu;
}
[HttpGet("[action]")]
public IEnumerable<SpiceViewModel> Spices()
{
return new Spice[] { };
}
}
Spices.razor
@inject HttpClient Http
<div class="alert alert-secondary mt-4" role="alert">
<span class="oi oi-pencil mr-2" aria-hidden="true"></span>
<strong>@Title</strong>
<span class="text-nowrap">
Please take our
<a target="_blank" class="font-weight-bold" href="https://go.microsoft.com/fwlink/?linkid=2093904">brief survey</a>
</span>
and tell us what you think.
@if (spices == null)
{
<p><em>Loading...</em></p>
}
else
{
<div class="form-group">
<label for="spicesSelect">Select list:</label>
<select class="form-control" id="spicesSelect">
<option>None</option>
@foreach (var spice in spices)
{
<option value="@spice.Id">@spice.Name</option>
}
</select>
</div>
}
</div>
@code {
[Parameter] string Title { get; set; }
SpiceViewModel[] spices;
protected override async Task OnInitAsync()
{
spices = await Http.GetJsonAsync<SpiceViewModel[]>("api/MenuData/Spices");
}
}
【问题讨论】:
-
如果您能提供一个最小的可重现示例(stackoverflow.com/help/minimal-reproducible-example),那就太棒了
-
我认为如果您编写了客户端托管的 Blazor 应用程序,这将很容易理解。如果我尝试注入 SampleDataController 它会爆炸。
-
请显示代码...
-
请提供请求的代码 - 我们看不到您的屏幕,也看不到您提供的参数或调用 API 的方式。这是帮助您的所有相关信息。
-
我已经添加了代码。这是 Blazor 客户端托管应用的基本框架。我已使用 IServicesCollection 中的 IServiceProvider 激活 IMenu 作为测试。
标签: asp.net-core .net-core visual-studio-2019 blazor