您能否澄清一下Web API错误管理的最佳实践?实际上,我不知道将try catch用于我的Api请求是否是一个好习惯.
public Vb.Order PostOrderItem(Vb.Order order)
{
if (OAuth.isValid(Request.Headers.GetValues("Token").Single()) != true)
{
HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);
throw new HttpResponseException(httpResponseMessage);
}
if (!ModelState.IsValid)
{
HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
throw new HttpResponseException(httpResponseMessage);
}
try
{
return Vb.Document.Generate(order);
}
catch (Exception ex)
{
logger.Error(ex);
HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
httpResponseMessage.Content = new StringContent(ex.Message);
throw new HttpResponseException(httpResponseMessage);
}
}
Run Code Online (Sandbox Code Playgroud)
我有使用try catch到服务器端代码的感觉不是一个好习惯,因为我只是记录我的catch并重新抛出一个异常.
Blazor 服务器端(dotnet 核心 3.1)
我遇到了在客户方面显示的问题:
无法重新连接到服务器。重新加载页面以恢复功能。
每次我更新代码库或互联网时都会坏掉或类似的东西。
现在的目标是它应该在服务器再次返回时(或在某个时间间隔内)重新加载页面。
有什么可能可以帮助我吗?
我已将ASP.NET MVC5应用程序配置为使用AttributeRouting进行WebApi:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
}
}
Run Code Online (Sandbox Code Playgroud)
我有ApiController如下:
[RoutePrefix("api/v1/subjects")]
public class SubjectsController : ApiController
{
[Route("search")]
[HttpPost]
public SearchResultsViewModel Search(SearchCriteriaViewModel criteria)
{
//...
}
}
Run Code Online (Sandbox Code Playgroud)
我想为我的WebApi控制器操作生成一个URL,而不必指定显式路由名称.
根据CodePlex上的这个页面,所有MVC路由都有一个不同的名称,即使它没有指定.
如果没有指定的路由名称,Web API将生成默认路由名称.如果特定控制器上的操作名称只有一个属性路由,则路径名称将采用"ControllerName.ActionName"形式.如果该控制器上有多个具有相同操作名称的属性,则会添加后缀以区分路径:"Customer.Get1","Customer.Get2".
在ASP.NET上,它没有确切地说明默认命名约定是什么,但它确实表明每个路由都有一个名称.
在Web API中,每个路由都有一个名称.路由名称对于生成链接非常有用,因此您可以在HTTP响应中包含链接.
基于这些资源,以及StackOverflow用户Karhgath的回答,我被认为以下会产生一个指向我的WebApi路由的URL:
@(Url.RouteUrl("Subjects.Search"))
Run Code Online (Sandbox Code Playgroud)
但是,这会产生错误:
在路径集合中找不到名为"Subjects.Search"的路径.
我已经根据我在StackOverflow上找到的其他答案尝试了一些其他变体,没有成功.
@(Url.Action("Search", "Subjects", new { httproute = "" }))
@(Url.HttpRouteUrl("Search.Subjects", new {}))
Run Code Online (Sandbox Code Playgroud)
实际上,即使在属性中提供Route名称,也只能使用:
@(Url.HttpRouteUrl("Search.Subjects", new {}))
Run Code Online (Sandbox Code Playgroud)
其中"Search.Subjects"被指定为Route属性中的路径名称.
我不想被迫为我的路线指定一个唯一的名称.
如何生成WebApi控制器操作的URL而无需在Route属性中明确指定路由名称?
CodePlex的默认路由命名方案是否可能已更改或记录错误?
有没有人对正确检索已使用AttributeRouting设置的路由的URL的方法有所了解?
c# asp.net asp.net-web-api attributerouting asp.net-web-api-routing
我正在尝试编写一个单元测试,我需要设置一个受保护的方法.我正在使用Moq进行此设置.
_innerHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", It.IsAny<HttpRequestMessage>(), It.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage);
Run Code Online (Sandbox Code Playgroud)
当该行执行时,它会抛出以下异常:
System.ArgumentException:使用
ItExpr.IsNull<TValue>而不是null参数值,因为它阻止正确的方法查找.
当我将其更改为使用时ItExpr.IsNull<TValue>,它确实允许测试执行.但是,它当然缺少我想配置的设置.
为了使用It.IsAny<TValue>?设置受保护的方法,我需要做什么?
MS文档文章"ASP.NET Core中的日志记录简介"提供了2个构造函数注入示例
使用ILogger
private readonly ILogger _logger;
public TodoController(ILogger<TodoController> logger)
{
_logger = logger;
}
Run Code Online (Sandbox Code Playgroud)和ILoggerFactory
private readonly ILogger _logger;
public TodoController( ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<TodoController>();
}
Run Code Online (Sandbox Code Playgroud)我的问题是我应该传递给从我的控制器调用的子类
通过ILoggerFactory我从控制器和每种类别的呼叫称为子类
LoggerFactoryExtensions.CreateLogger<MyChildClass>()或
将父控制器传递ILogger<MyController>给从控制器创建的每个子类,并具有非泛型参数ILogger.
在日志中,我更喜欢为每个类看到单独的类别"MyChildClass",而不是所有类都使用父控制器中的"MyController"类别.
但是,每个对象构造中的CreateLogger可能是一项昂贵的操作(例如,请参阅https://github.com/aspnet/Logging/issues/524)
你会推荐哪个选项?你能建议其他方法吗?
我有一个使用Xunit的单元测试项目,我们正在测试的方法返回IActionResult.
我看到有些人建议使用"NegotiatedContentResult"获取内容,IActionResult但这在Xunit中不起作用.
所以我想知道如何获取IActionResultXunit中的内容值?
测试代码示例如下:
public void GetTest()
{
var getTest = new ResourcesController(mockDb);
var result = getTest.Get("1");
//Here I want to convert the result to my model called Resource and
//compare the attribute Description like below.
Resource r = ?? //to get the content value of the IActionResult
Assert.Equal("test", r.Description);
}
Run Code Online (Sandbox Code Playgroud)
有没有人知道如何在XUnit中这样做?
我试图使用通用的Lazy类来实例化.net核心依赖注入扩展的昂贵类.我已经注册了IRepo类型,但我不确定Lazy类的注册是什么样的,或者它是否支持.作为一种解决方法,我使用了这种方法http://mark-dot-net.blogspot.com/2009/08/lazy-loading-of-dependencies-in-unity.html
配置:
public void ConfigureService(IServiceCollection services)
{
services.AddTransient<IRepo, Repo>();
//register lazy
}
Run Code Online (Sandbox Code Playgroud)
控制器:
public class ValuesController : Controller
{
private Lazy<IRepo> _repo;
public ValuesController (Lazy<IRepo> repo)
{
_repo = repo;
}
[HttpGet()]
public IActionResult Get()
{
//Do something cheap
if(something)
return Ok(something);
else
return Ok(repo.Value.Get());
}
}
Run Code Online (Sandbox Code Playgroud) c# dependency-injection lazy-initialization .net-core asp.net-core
如何使用Castle Windsor作为IOC而不是默认的.net核心IOC容器?
我已经构建了一个依赖于WindsorContainer解析服务的服务解析器.
就像是:
public class ServiceResolver
{
private static WindsorContainer container;
public ServiceResolver()
{
container = new WindsorContainer();
// a method to register components in container
RegisterComponents(container);
}
public IList<T> ResolveAll<T>()
{
return container.ResolveAll<T>().ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
无法弄清楚如何让我的.net core 2 web API使用此解析器作为IServiceCollection的替代品.
c# dependency-injection castle-windsor ioc-container asp.net-core-2.0
我有一个方法来获取标头值使用 IHttpContextAccessor
public class HeaderConfiguration : IHeaderConfiguration
{
public HeaderConfiguration()
{
}
public string GetTenantId(IHttpContextAccessor httpContextAccessor)
{
return httpContextAccessor.HttpContext.Request.Headers["Tenant-ID"].ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
我正在测试GetBookByBookId方法
假设该方法如下所示:
public class Book
{
private readonly IHttpContextAccessor _httpContextAccessor;
private IHeaderConfiguration _headerConfiguration;
private string _tenantID;
public Book(IHeaderConfiguration headerConfiguration, IHttpContextAccessor httpContextAccessor){
var headerConfig = new HeaderConfiguration();
_httpContextAccessor = httpContextAccessor;
_tenantID = headerConfig.GetTenantId(_httpContextAccessor);
}
public Task<List<BookModel>> GetBookByBookId(string id){
//do something with the _tenantId
//...
}
}
Run Code Online (Sandbox Code Playgroud)
这是我对GetBookByBookId方法的单元测试
[Fact]
public void test_GetBookByBookId()
{
//Arrange
//Mock IHttpContextAccessor
var …Run Code Online (Sandbox Code Playgroud) 我有一个键入的客户端,我想将其注册为单例:
public class SomeHttpClient
{
private readonly IHttpClientFactory _clientFactory;
public SomeHttpClient(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public Task MakeSomeCallAsync(...)
{
var client = _clientFactory.Create();
// Do more stuff
}
}
Run Code Online (Sandbox Code Playgroud)
类型化的客户端必须是单例的,因为它有一些断路器逻辑,如果 API 对客户端进行速率限制,则会中断电路。电路必须在整个应用程序中断开,显然不仅仅是当前的请求管道(否则客户端将继续访问已经从其他实例进行速率限制的 API)。这已经通过使用封装了该功能的类型化客户端(虽然不是 Polly)来实现的。
现在因为类型化的客户端将是一个单身人士,我们不能注入一个单身人士,HttpClient因为这会带来我们以前在一个 long living 中遇到的所有问题HttpClient。显而易见的解决方案是注入一个HttpClientFactory现在可以用来在HttpClient每次键入的客户端需要一个实例时发出一个实例而不必担心生命周期管理等,因为这已经推迟到HttpClientFactory现在。
我现在的问题是如何HttpClientFactory为一个简单的功能集成测试创建默认值,我想在其中实例化一个类型化的客户端,看看我是否可以点击 API 并从自动化测试中获得成功的响应?
我不想设置一个 ASP.NET Core TestServer 和一个围绕它的整个应用程序,因为这对于我现在想要做的那种功能测试来说太过分了。
没有可用于注入HttpClientFactory?
c# dotnet-httpclient .net-core asp.net-core httpclientfactory
c# ×9
asp.net-core ×5
.net-core ×4
unit-testing ×3
asp.net ×2
moq ×2
blazor ×1
logging ×1
xunit ×1