我正在尝试在我的后端系统中添加API文档.默认的ApiExplorer和帮助页面工作非常好,直到我向Api控制器引入版本.
为了添加版本,我在Controllers文件夹下创建了子文件夹:
并在那里有基于版本的Api控制器.为了让我的Api可被发现,我必须重写DefaultHttpControllerSelector以考虑任何客户端提供的命名空间并将它们映射到右侧控制器:
这打破了我的默认ApiExplorer,以下属性返回ZERO api描述
Configuration.Services.GetApiExplorer().ApiDescriptions
Run Code Online (Sandbox Code Playgroud)
如何自定义现有的ApiExplorer并帮助他找到我的Api控制器,而不是重写整个ApiExplorer实现.我真的只需要显示在哪里找到我的Api控制器.
请指教.
api documentation asp.net-mvc asp.net-mvc-apiexplorer asp.net-apicontroller
我目前正在使用nunit为以前未经测试的服务器编写集成测试,该服务器是用C#using ApiController和Entity Framework 编写的.大多数测试运行得很好,但我遇到了两个总是导致数据库超时的问题.错误消息看起来像这样:
System.Data.Entity.Infrastructure.DbUpdateException:更新条目时发生错误.有关详细信息,请参阅内部异常
System.Data.Entity.Core.UpdateException:更新条目时发生错误.有关详细信息,请参阅内部异常
System.Data.SqlClient.SqlException:超时已过期.操作完成之前经过的超时时间或服务器没有响应.
System.ComponentModel.Win32Exception:等待操作超时
超时的第一个测试:
[TestCase, WithinTransaction]
public async Task Patch_EditJob_Success()
{
var testJob = Data.SealingJob;
var requestData = new Job()
{
ID = testJob.ID,
Name = "UPDATED"
};
var apiResponse = await _controller.EditJob(testJob.ID, requestData);
Assert.IsInstanceOf<StatusCodeResult>(apiResponse);
Assert.AreEqual("UPDATED", testJob.Name);
}
Run Code Online (Sandbox Code Playgroud)
超时的另一个测试:
[TestCase, WithinTransaction]
public async Task Post_RejectJob_Success()
{
var rejectedJob = Data.SealingJob;
var apiResponse = await _controller.RejectJob(rejectedJob.ID);
Assert.IsInstanceOf<OkResult>(apiResponse);
Assert.IsNull(rejectedJob.Organizations);
Assert.AreEqual(rejectedJob.JobStatus, JobStatus.OnHold);
_fakeEmailSender.Verify(
emailSender => emailSender.SendEmail(rejectedJob.Creator.Email, It.Is<string>(emailBody => emailBody.Contains(rejectedJob.Name)), It.IsAny<string>()),
Times.Once());
}
Run Code Online (Sandbox Code Playgroud)
这些是这些测试使用的控制器方法:超时始终发生在await db.SaveChangesAsync()控制器内的第一次调用中.正在测试的其他控制器方法也可以SaveChangesAsync …
c# nunit unit-testing entity-framework asp.net-apicontroller
在ApiController的请求中,我正在跟踪等待打开Sql连接的持续时间.
await t.TrackDependencyAsync(async() => { await sqlConnection.OpenAsync(); return true; }, "WaitingSqlConnection");
Run Code Online (Sandbox Code Playgroud)
如果我的请求至少被调用了5分钟,那么任何新的呼叫都会看到持续时间OpenAsync很长(约3秒)而不是立即.
我想了解消除这种疯狂缓慢的原因.
UPDATE
我创建了一个端点只是为了打开SqlConnection.如果我等待超过5分钟然后调用该OpenConnection端点然后再调用任何其他请求,OpenConnection将产生上述等待成本,但请求不会.
因此,我计划在Azure上运行每分钟运行并调用OpenConnection端点.但是,当我从我的http客户端发出请求时,我会产生等待时间.好像打开了SqlConnection以某种方式链接到http客户端IP ...
此外,5分钟的窗口是典型的DNS TTL ...但是数据库端点的DNS查找的3秒太长.不可能.
更新2
在htt客户端级别观察到的时间似乎是等待连接以及其他一些延迟(dns查找?)的结果.
这是一个总结我观察到的内容的表:
更新3
根据Fiddler,我表中第3行和第4行的区别在于TCP/IP Connect和HTTPS握手所花费的时间.我们不要只关注那个帖子,而只关注等待SqlConnection开放的时间.
更新4
实际上我认为两个等待时间都有相同的原因.
服务器需要"保持"其与数据库的连接,并且客户端需要"保持"其与服务器的连接.
更新5
我每隔4分钟就有一份工作要打开,SqlConnection但有一段时间它会产生等待成本.所以我认为不活动时间是4分钟而不是5分钟(因此我更新了这个帖子标题).
所以我更新了我的预定工作,每分钟运行一次.然后我意识到它仍然会产生等待成本,但每30分钟定期(因此我更新了这个帖子标题).
这两次奇怪地与Azure负载均衡器空闲超时相关.
load-balancing sqlconnection keep-alive asp.net-web-api asp.net-apicontroller
我有一个Web API控制器,如下所示:
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Threading.Tasks;
using System.IO;
namespace APIIntegration.Controllers
{
public class TestController : ApiController
{
// http://localhost/api/test
[HttpGet]
public async Task<HttpResponseMessage> Get()
{
Stream stream = streamWith256Bytes;
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentLength = stream.Length;
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "foo.bin";
return result;
}
private static Stream streamWith256Bytes
{
get
{
MemoryStream stream = new MemoryStream();
for (int i = 0; …Run Code Online (Sandbox Code Playgroud) 有人可以告诉我如何测试此功能:
[RoutePrefix("service")]
public class TestControler : ApiController
{
[Route("function-route")]
[HttpPost]
public HttpResponseMessage Testfunction(TestData t_testData )
{
...
HttpResponseMessage httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
return httpResponseMessage;
}
}
public class TestData
{
public byte[] PreviewImage { get; set; }
public byte[] FileAsByteArray { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我们通过以下方式启用了 Swagger:
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
//Using AttributeRoutes
config.MapHttpAttributeRoutes();
//Swagger
config.EnableSwagger(c =>{
c.SingleApiVersion("v1", "My Test API");
}).EnableSwaggerUi();
appBuilder.UseWebApi(config);
}
Run Code Online (Sandbox Code Playgroud)
我真的不知道如何通过 swagger、postman 或 curl 来测试这个 …
我正在使用asp.net授权以Angular js登录客户端,我需要让当前用户登录
我需要让当前用户在我的记录器表中保存任何操作,并且httpcontext.session.current为null,是否有另一种方法可以在会话中保存登录的用户或随时获取其他信息
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly string _publicClientId;
static ERPV02_03Entities db;
public ApplicationOAuthProvider(string publicClientId)
{
if (publicClientId == null)
{
throw new ArgumentNullException("publicClientId");
}
db = SingleTonConText.Instance;
_publicClientId = publicClientId;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType); …Run Code Online (Sandbox Code Playgroud) 我注意到是否使用此属性是一样的。我错了吗?
举个例子:
[Route("[controller]")]
[ApiController]
public class DataTablesController: ControllerBase
{
[HttpGet]
public IActionResult Test()
{
return Ok("test");
}
}
Run Code Online (Sandbox Code Playgroud)
当我删除该[ApiController]属性时什么也没发生。
在微软的文档中,我找到了这样的解释:
指示类型和所有派生类型用于提供 HTTP API 响应。
使用此属性修饰的控制器配置了旨在改善开发人员构建 API 体验的功能和行为。
在程序集中装饰时,程序集中的所有控制器都将被视为具有 API 行为的控制器。
什么是 API 行为?我们为什么要使用它?
c# controller asp.net-apicontroller .net-attributes asp.net-core
在ApiController动作中,我需要在动作执行完毕后立即关闭与数据库的连接.
在控制器下我覆盖OnActionExecuted以实现此目的.
如何在ApiController行动中实现这一目标?
谢谢
我正在尝试IValidatableObject在 web api 2 上下文中使用验证。该Validate方法正在被调用,但ValidationContext传递的参数有一个调用的方法GetService,该方法始终返回 null,因为从未设置验证上下文的服务提供者。
从我所有的研究来看,我们可以轻松地在 MVC 框架中配置它,但我没有找到任何关于如何在 web api 2 中配置它的信息。
在验证传递给 的模型时,我们如何将服务提供者设置为验证上下文ApiController?
c# validation ivalidatableobject asp.net-apicontroller asp.net-web-api2
我正在尝试在 ASP.NET core 5 Razor Pages Web 应用程序中创建 API 控制器。
我已在 Visual Studio 中命名的文件夹内创建了 Api 控制器Api。
然后,当我尝试运行以下 url 来测试 api 控制器是否正常工作时,我收到 404 not found:
https://localhost:345345/api/saveimage
我缺少什么?
Api 控制器(SaveImageController.cs):
[Route("api/[controller]")]
[ApiController]
public class saveImageController : ControllerBase
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "test", "test2" };
}
}
Run Code Online (Sandbox Code Playgroud) c# controller asp.net-apicontroller razor-pages asp.net-core-5.0
c# ×6
controller ×2
angularjs ×1
api ×1
asp.net-core ×1
asp.net-mvc ×1
curl ×1
javascript ×1
keep-alive ×1
nunit ×1
postman ×1
razor-pages ×1
swagger ×1
unit-testing ×1
validation ×1