【发布时间】:2018-05-15 01:50:55
【问题描述】:
所以我刚刚遇到了这个非常奇怪的问题,使用 .NET Core (2.1.200 cli) 和 VSCode (1.23.1) 构建了一个简单的 WebAPI 模板。大多数异常(如果抛出)会将我放入 VSCode 调试器并继续返回发送到浏览器的开发人员异常页面。但是,当抛出 ArugmentNullException 时……应用程序会在没有 VSCode 调试器交互的情况下硬崩溃。
Program.cs(默认 webapi 模板代码)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace ExceptionIssue {
public class Program {
public static void Main(string[] args) {
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}
Startup.cs(默认 webapi 模板代码)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace ExceptionIssue {
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
}
.\Controllers\ValuesController.cs(修改后的获取)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace ExceptionIssue.Controllers {
[Route("api/[controller]")]
public class ValuesController : Controller {
// GET api/values
[HttpGet]
public IEnumerable<string> Get() {
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id) {
String result = null;
switch (id) {
case 1:
throw new Exception("One");
break;
case 2:
throw new ArgumentNullException("Two");
break;
case 3:
result = String.Format(null, "UH OH");
break;
case 4:
String template = null;
result = String.Format(template, "UH OH");
break;
}
return result;
}
// POST api/values
[HttpPost]
public void Post([FromBody]string value) {
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value) {
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id) {
}
}
}
- 还要注意 String.Format(null, "UH OH"); 返回 "UH OH" 而 String.Format(template, "UH OH); 抛出一个 ArgumentNullException(不知道为什么会有区别,他们不应该做同样的事情)。
不确定这是 .NET Core、Kestrel 还是 VSCode 问题,但对我来说它是 100% 可重现的。
【问题讨论】:
-
“不知道为什么有区别,他们不应该做同样的事情吗” - 不,第一个是调用
string.Format(IFormatProvider, string, object[])并使用null来表示“当前文化”,所以它是可以返回“UH OH”。 -
里面有异常处理代码吗?过于激进的捕捉实际上很容易搞砸。如果那个 catch 块然后执行“Application.Close()”或类似代码(不确定正确的 WPF 变体),它很容易解释这种行为。
-
其实这个问题是关于 ArgumentNullException 的硬崩溃,String.Format 只是一个旁注。
-
我的错,我把问题解释错了。
-
@DaisyShipton 感谢您对 String.Format 旁注的见解。我应该看看实际调用了什么构造函数,这现在更有意义了。谢谢。
标签: c# visual-studio-code .net-core asp.net-core-webapi