我试图让小数只有两个点。例如:我会尝试让 1.2345 = 1.23。
我尝试了“String.Format("{0.0.00}", cats.ToString());”,但它给了我一个错误,基本上说它的格式不正确。
我试图让小数只有两个点。例如:我会尝试让 1.2345 = 1.23。
我尝试了“String.Format("{0.0.00}", cats.ToString());”,但它给了我一个错误,基本上说它的格式不正确。
private Texture2D defaultCursor; // Store the original cursor
void Start()
{
Cursor.SetCursor(defaultCursor, Vector2.zero, CursorMode.Auto); // Store the default cursor
}
这样做的话,defaultCursor 变量将为空,因此我将无法在以后的代码中使用它。
我希望当我在代码中的某处使用带有自定义纹理图像的 Cursor.SetCursor 时,能够在需要时将其更改回默认鼠标光标纹理。
我看到有一个 MouseCursor,您可以执行例如 MouseCursor.Pan 或 MouseCursor.Arrow,但是如何将鼠标光标形状更改为此 Pan 或 Arrow ?没有自定义纹理。
我目前正在学习 ASP.NET Core Web API 项目中的错误错误管理,以尝试找到一个优雅的解决方案,确保ProblemDetails
在出现问题时始终返回。
我正在使用WeatherForecast
创建带有控制器的新 C# / ASP.NET Core 8 Web API 项目时创建的默认 API 模板。
我已经实现了自定义异常处理程序;然而我发现它并不总是有效。
当我使用 调用 APIPostman
导致错误时,我得到了正确的ProblemDetails
、状态代码和标头信息;但是,当我从界面中的“试用”功能调用 API 时Swagger
,我得到了错误的状态代码(500 内部错误)以及异常详细信息而不是ProblemDetails
和错误的标头信息。
研究这个问题,我发现在我的GlobalExceptionHandler
类(实现IExceptionHandle
接口)中,如果我尝试来自 Swagger 的代码,该ProblemDetailsService.TryWriteAsync(...)
方法就会返回false
;但是,当我通过从 Postman 调用它执行完全相同的代码时,该ProblemDetailsService.TryWriteAsync(...)
方法就会返回true
。
我提出了一个当“ProblemDetailsService.TryWriteAsync(...)”返回失败的情况,以便我可以尝试直接将其ProblemDetailsContext
写入httpContext.Response
。
当我这样做时,我能够捕获以下异常(再次,这仅在使用 Swagger 的 Try Code 功能时发生......而不是从 Postman 调用时发生):
不支持对“System.Type”实例进行序列化和反序列化。路径:$.HttpContext.Features.Key。”
我不知道为什么这会失败。
我正在寻求帮助,如何确保无论如何调用 API,我的错误管理都以相同的方式运行。
GlobalExceptionHandler
这是我的课程的实现:
public class GlobalExceptionHandler : IExceptionHandler
{
private readonly IProblemDetailsService _problemDetailsService;
public GlobalExceptionHandler(IProblemDetailsService problemDetailsService)
{
if (problemDetailsService == null) throw new ArgumentException(nameof(problemDetailsService));
_problemDetailsService = problemDetailsService;
}
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
var message = exception switch
{
ArgumentException => ((ArgumentException)exception).Message,
ValidationException => ((ValidationException)exception).Message,
_ => $"Internal Server Error ({exception.GetType().Name})"
};
int status = exception switch
{
ArgumentException => (int)HttpStatusCode.BadRequest,
ValidationException => (int)HttpStatusCode.BadRequest,
_ => (int)HttpStatusCode.InternalServerError
};
ProblemDetails problemDetails = new()
{
Title = $"Bad Request: {exception.GetType().Name}", // human-readable summary of the problem type
Detail = message, //detailed explanation specific to the problem
Status = status,
Instance = httpContext.Request.GetEncodedUrl(),
Type = exception.HelpLink
};
var errorcontext = new ProblemDetailsContext()
{
HttpContext = httpContext,
ProblemDetails = problemDetails,
//Exception = exception,
AdditionalMetadata = null
};
httpContext.Response.Clear();
httpContext.Response.StatusCode = status;
var written = await _problemDetailsService.TryWriteAsync(errorcontext);
if (!written)
{
try
{
await httpContext.Response.WriteAsJsonAsync<ProblemDetailsContext>(errorcontext);
written = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
written = false;
}
}
return written;
}
}
这是我的Program.cs
:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Net;
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Net.Http;
using Microsoft.AspNetCore.Diagnostics;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Add services to the container.
builder.Services.AddExceptionHandler<ProblemDetailsScratchPad.GlobalExceptionHandler>(); // Using a custom exception handler that converts the exception into a Problem Details
builder.Services.AddProblemDetails(); // required for using the exception handler with the custom problem details exception handler code because it adds the services required for Problem Details
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseExceptionHandler(opt => { }); //adding the custom GlobalExceptionHandler to the app's pipeline
app.UseAuthorization();
app.MapControllers();
app.Run();
这是我的实现WeatherForecastController
(并不是说调用 post 或 get 会引发异常并由自定义异常处理程序进行处理)
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet("GetWeatherForecast")]
public ActionResult<IEnumerable<object>> GetWeatherForecast()
{
throw new ArgumentException("Please provide a valid value for a week day: between 0 and 6");
}
[HttpPost("PostWeatherForecastDTO")]
public ActionResult<IEnumerable<object>> PostWeatherForecastDTO()
{
throw new Exception("Please provide a valid value for a week day: between 0 and 6");
}
}
我已经使用执行构建了这样的图像
docker build--tag=api--file=Dockerfile_01--no-cache--progress=plain。
基于下面的Dockerfile_01。
来自 mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /bin
复制 *.csproj ./
运行 dotnet 恢复
复制 . ./
运行 dotnet 发布 --configuration 发布 --output /release
来自 mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /bin
复制 --from=build /release .
暴露 8080 8081
CMD ["dotnet", "Api.dll"]
我开始执行我的容器
docker run --detach --publish 5001:8080 --publish 7001:8081 --name WebApi api
并且它似乎可以工作,日志告诉我程序监听端口 8080 等。但是,当我导航到http://localhost:5001时,我得到了 404。当我使用相应的配置文件直接从 VS 启动时,我可以看到 Swagger,正如预期的那样。
我该如何解决此问题?
我看到的唯一意外的事情是在日志中,它告诉我由于端口混乱,重定向到安全协议失败。不过,这是明天的问题,目前我尝试使用 5001,即 HTTP。
2025-02-14 17:56:41 信息:Microsoft.Hosting.Lifetime[14]
2025-02-14 17:56:41 正在监听:http://[::]:8080
2025-02-14 17:56:41 信息:Microsoft.Hosting.Lifetime[0]
2025-02-14 17:56:41 应用程序已启动。按 Ctrl+C 关闭。
2025-02-14 17:56:41 信息:Microsoft.Hosting.Lifetime[0]
2025-02-14 17:56:41 托管环境:生产
2025-02-14 17:56:41 信息:Microsoft.Hosting.Lifetime[0]
2025-02-14 17:56:41 内容根路径:/usr/bin
2025-02-14 17:57:02 警告:Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
2025-02-14 17:57:02 无法确定重定向的 https 端口。
我怀疑我配置端口的方式有些问题,但我看不出在哪里。它也遵循了这个答案的建议。我测试了许多不同的组合,但没有发现任何有用的信息。
当然,为了确保万无一失,我测试了/,/swagger和/swagger.html ,尽管我知道这不是问题所在。
我有以下类来获取 API 响应:
[JsonObject]
[Serializable]
public class Root
{
public Metadata metadata { get; set; }
public List<Result> result { get; set; }
}
[JsonObject]
[Serializable]
public class GroupRecord
{
public string groupNumber { get; set; }
}
[JsonObject]
[Serializable]
public class Metadata
{
public int totalCount { get; set; }
public int page { get; set; }
public int pageCount { get; set; }
}
[JsonObject]
[Serializable]
public class Npi
{
public DateTime EffectiveDate { get; set; }
}
[JsonObject]
[Serializable]
public class Result
{
public string Name { get; set; }
public Npi npi { get; set; }
public List<GroupRecord> aGroupRecord { get; set; }
}
groupNumber
我正在尝试使用 LINQ 获取与给定匹配且具有最新结果的结果EffectiveDate
。
这是我认为应该可以工作的应用程序代码:
string groupNumber = "SALT"
Root dataObject = response.Content.ReadAsAsync<Root>().Result;
if (dataObject.result.Count >= 1)
{
var result = dataObject.result.Where(x => x.aGroupRecord.Where(a => a.groupNumber == groupNumber).OrderByDescending(x.npi => x.npi.EffectiveDate)).FirstOrDefault();
}
从 Azure TelemetryClient 切换到 OpenTelemetry 后,我们在 Application Insights 中看到大量 CustomMetrics,事实上,数量如此之多,以至于我们在不到一小时的时间内就填满了报价。
查看 Application Insights > Logs,我可以看到:https://imgur.com/a/afu4aCM,它在同一毫秒内显示至少 25 个条目。因此,我想先过滤掉这些日志,但由于对 OpenTelemetry 还不熟悉,因此很难理解文档。
运行的应用程序是一个 asp.net 核心网站,我们的 OpenTelemetry 配置非常简单:
public static void RegisterOpenTelemetry(this IServiceCollection service, IConfiguration configuration)
{
service.AddOpenTelemetry()
.UseAzureMonitor(options =>
{
options.ConnectionString = configuration["ApplicationInsights:ConnectionString"];
options.EnableLiveMetrics = true;
})
.WithTracing(x =>
{
x.AddSqlClientInstrumentation(options =>
{
options.SetDbStatementForText = true;
options.RecordException = true;
});
})
.WithMetrics(x =>
{
x.AddSqlClientInstrumentation();
});
service.Configure<AspNetCoreTraceInstrumentationOptions>(options =>
{
options.RecordException = true;
});
}
tl;dr:如果我想过滤掉所有的“http.client_open_connections”,我该怎么做?
提前致谢
作为我的问题的一个简化示例,我有一个数组ISomeType
,我想循环遍历该数组中所有实际的元素MyType
,但我收到IDE0220 警告“在 foreach 循环中添加显式强制转换”,我认为这不适用。以下是代码示例:
public interface ISomeType {
void DoThing();
}
public class MyType: ISomeType {
void DoThing() { /* do something */ }
void DoMyTypeThing() { /* do something specific to MyType */ }
}
public class YourType: ISomeType {
void DoThing() { /* do something */ }
void DoMyTypeThing() { /* do something specific to MyType */ }
}
ISomeType[] maybeMyTypes = [new MyType()];
// I get the error on this line because I cast the element into `MyType`
foreach (MyType foobar in maybeMyTypes.Where(i => i.GetType() == typeof(MyType))) {
// use the MyType methods availbale on foobar
}
maybeFooBars
编译器抱怨它隐式地将的元素转换为MyType
,并且这可能在运行时失败,所以我应该明确说明转换:
// Code with violations. var list = new List<object>(); foreach (string item in list) { } // Fixed code. var list = new List<object>(); foreach (string item in list.Cast<string>())
我的代码在运行时真的会失败吗?因为我正在检查类型,并且只在类型正确时进行隐式转换?还是 C# 编译器不够聪明,无法看出我已经防范了类型不正确?
我正在尝试使用 c# 中的匿名类型发送 WhatsApp 云 API 消息。以下代码运行正常:
// Request Body
var body = new
{
messaging_product = "whatsapp",
to = "92" + patient.Phone.TrimStart('0'), // Use the entered recipient's phone number
type = "template",
template = new
{
name = "appointment_new",
language = new
{
code = "en"
},
components = new[]
{
new
{
type = "header",
parameters = new[]
{
new
{
type = "text",
text = clinicname??"Appointment"
}
}
},
new
{
type = "body",
parameters = new[]
{
new
{
type = "text",
text = $"test"
}
}
}
}
},
message = "test" // Use the entered message
};
但我想使用 mediaId 在标头中发送 PDF 文件。因此我进行了以下更改,例如:
// Request Body
var body = new
{
messaging_product = "whatsapp",
to = "92" + patient.Phone.TrimStart('0'), // Use the entered recipient's phone number
type = "template",
template = new
{
name = "appointment_new",
language = new
{
code = "en"
},
components = new[]
{
new
{
type = "header",
parameters = new[]
{
new
{
type = "document", //////change
document = new //////change
{
id = mediaId //////change
}
}
}
},
new
{
type = "body",
parameters = new[]
{
new
{
type = "text",
text = $"test"
}
}
}
}
},
message = "test" // Use the entered message
};
但是 Visual Studio 在此处给出语法错误:No best type found for implicitly-typed array
我想了解原因?第一个代码和第二个代码有什么不同?AI 也发布了第二个版本,没有其他想法。
我读过文档说将状态设置为“已取消”需要三个条件:
OperationCanceledException
(或其派生的异常类型,如TaskCanceledException
)被抛出token.IsCancellationRequested
是真的token
传递给的委托与在任务创建时传递的参数OperationCanceledException
相同token
但是下面的示例直接抛出,没有任何 token,但取消成功。是因为 token 是一个结构体,所以默认值总是满足最后两个条件吗?我对这个想法没有信心,如果我错了,希望得到一些解释
var task = Task.Run(() =>
{
throw new OperationCanceledException();
});
try
{
task.Wait();
}
catch (AggregateException)
{
Console.WriteLine(task.Status); // Cancelled
}
以下示例场景:
A
我有 RowIndex为
4
ColumnIndex 为 7 的列
我想将列A
向左移动 11 位,因此我得到的列索引 ( B
) 为
RowIndex: 2
ColumnIndex: 6
更糟糕的是,该表是一个子表,因此不是从索引 0, 0 开始,而是像本例中的 4, 2 这样的索引开始
我很确定这可以通过模计算来解决,但我的大脑拒绝给我正确的公式。
到目前为止,我已经使用 C# 开始编写此代码,但这显然不正确(https://dotnetfiddle.net/5iEqgD):
public static void Main()
{
int minColumnIndex = 4;
int maxColumnIndex = 8;
int minRowIndex = 2;
int maxRowIndex = 5;
int cellARowIndex = 4;
int cellAColumnIndex = 7;
int shiftCellToTheLeft = 11;
int cellBColumnIndex = cellAColumnIndex - ((maxColumnIndex - minColumnIndex + 1) % shiftCellToTheLeft);
int cellBRowIndex = cellARowIndex - ((maxColumnIndex - maxColumnIndex + 1) % shiftCellToTheLeft);
Console.WriteLine("cellBColumnIndex: " + cellBColumnIndex);
Console.WriteLine("cellBRowIndex: " + cellBRowIndex);
// Result:
// cellBColumnIndex: 2
// cellBRowIndex: 3
}
我在这里做错了什么?