我正在使用一个示例为 Web API 项目设置 HMAC 身份验证。原始示例源代码/项目可在此处获得:
我试图让 Postman 在它的预请求脚本中构建和发送 GET 请求。但是请求总是以 401 失败,我不知道为什么。
邮递员预请求脚本:
var AppId = "4d53bce03ec34c0a911182d4c228ee6c";
var APIKey = "A93reRTUJHsCuQSHR+L3GxqOJyDmQpCgps102ciuabc=";
var requestURI = "http%3a%2f%2flocalhost%3a55441%2fapi%2fv1%2fdata";
var requestMethod = "GET";
var requestTimeStamp = "{{$timestamp}}";
var nonce = "1";
var requestContentBase64String = "";
var signatureRawData = AppId + requestMethod + requestURI + requestTimeStamp + nonce + requestContentBase64String; //check
var signature = CryptoJS.enc.Utf8.parse(signatureRawData);
var secretByteArray = CryptoJS.enc.Base64.parse(APIKey);
var signatureBytes = CryptoJS.HmacSHA256(signature,secretByteArray)
var requestSignatureBase64String = CryptoJS.enc.Base64.stringify(signatureBytes);
postman.setGlobalVariable("key", "amx " + AppId + …
Run Code Online (Sandbox Code Playgroud) 工具
MSBuild v14
视觉工作室2013
在 Windows Server 2012 上运行的 Jenkins v2.111
Git(本地文件服务器上的裸存储库)
Windows 批处理
我的目标
使用 MSBuild 构建 c# Visual Studio 项目,该项目从项目 AssemblyInfo.cs 中提取主要版本号和次要版本号,以供在生成期间使用。构建会生成类似 1.2.$BUILD_NUMBER 的内容,从而产生类似 1.2.121、1.2.122、1.2.123 等的内容。一旦用户选择“发布”构建,文件夹名称中具有正确版本的 clickonce 部署将被复制到其目标位置,并将标签应用于 Git 存储库。
管道示例
以下是我所做的“正在进行的工作”。欢迎提出任何改进建议。对于那些想知道为什么我将代码库复制到临时文件夹的人来说。我在 Jenkins 中使用多分支作业,自动生成的文件夹非常长!这给我带来了一些错误,比如我的文件名、项目名或两者都太长(因为整个路径超过了 255 个左右的字符长度)。因此,解决这个问题的唯一方法是复制内容,以便构建和发布能够正常进行。
pipeline {
agent none
stages {
stage ('Checkout'){
agent any
steps
{
checkout scm
}
}
stage ('Nuget Restore'){
agent any
steps
{
bat 'nuget restore "%WORKSPACE%\\src\\Test\\MyTestSolution.sln"'
}
}
stage('Build Debug') {
agent any
steps
{
bat "xcopy %WORKSPACE%\\src\\* /ey d:\\temp\\"
bat …
Run Code Online (Sandbox Code Playgroud) 概述
一个事件数据库,它将有许多列保存查找表中保存的记录的 ID。
我试图解决的问题
我需要提出一个强大的解决方案来管理某些字段保存查找 ID 的历史数据。我已经列出了我提出的解决方案以及替代方案。我想从其他开发人员那里知道他们是否在他们的项目中以类似的方式管理这些场景。也许你有更好的方法?
数据库:Oracle 10g
列:部门名称
场景:部门名称在一年中可以更改 X 次。企业需要报告其所有部门的数据,但希望在其各自部门名称下查看事件,就像事件发生时一样。
建议的解决方案:在部门名称查找表中设置条目时,设置开始和结束日期值。使用视图,根据事件日期创建一个计算字段,以便在任何给定时间点访问正确的部门名称。
优点:通过一些防御性编码,它可以使选定用户的自助服务能够通过 GUI 管理他们的静态数据,而无需任何额外的数据库更改。可以即时更改,例如完全更改名称。不需要 DBA 支持。
缺点:考虑到在大型数据集上进行的查找/计算量,这可能是一项昂贵的操作。
替代解决方案:只需使用并插入部门名称的纯文本值。这里的缺点是临时请求需要 DBA 来更改/更新值,可能针对特定日期范围并错误地丢失一些记录。表空间消耗也会增加。
列:Assigned_Technician_ID
场景:事件将分配一名技术人员,技术人员的 ID 将存储在该位置。查找表将保存所有可用技术人员的“当前”列表。当人们离开公司时,必须更新列表并删除过时的技术人员。这是为了将下拉列表中的值数量保持在最低限度。企业仍希望查看分配给哪些技术人员处理所有事件数据。
解决方案:不要从技术人员查找表中删除条目,而是使用表示“已归档/已删除”的标志来标记该条目。此标志将作为 GUI 下拉菜单上的过滤器,以删除不需要的条目。
优点:查找表仅包含员工表中技术人员的 UID。因此,如果业务需求发生变化,很容易在主视图中呈现技术人员的任何属性,例如全名或员工编号等。
缺点:与前面的示例一样,查找可能是对大型数据集的昂贵操作。GUI 方面需要在业务逻辑和设计方面进行额外的工作。特别是在原始条目已“存档”时如何管理下拉列表。
替代解决方案:与上面的示例一样,只需使用纯文本值。这里的缺点是会消耗更多的表空间,并且随着不断变化的业务需求的灵活性降低。
我有一个 MVC 项目,它将通过 HTTP 'Post' 动词接受数据。我热衷于遵循最佳实践,并想就如何最好地设置我的模型提出一个简短的问题。
通常在处理发布的数据时,我会设计我的控制器以使用具体模型。然而,当我想使用 IoC 时,我想确定我是否应该像以前一样继续或者我是否应该创建接口。
我的直觉是,我应该在整个 Web 应用程序中为我的所有模型和类使用接口,以有效地实现 IoC。我只是想得到确认我走在正确的道路上!:o)
例子:
My concrete model
public class PhoneBook : IPhoneBook
{
public string Firstname {get; set;}
public string LastName {get; set;}
public string PhoneNumber {get; set;}
}
My interface
public interface IPhoneBook
{
string Firstname {get;set;}
string Lastname {get;set;}
string Phonenumber {get;set;}
}
My controller
//Accept posted data from web form
public void Post(IPhoneBook passInDetails)
{
...
}
Run Code Online (Sandbox Code Playgroud)
提前致谢。
我刚开始将异步编程实现到我正在编写的一些方法中.
业务逻辑是接受入站调用,如果项目尚未在全局高速缓存中处理,或者如果是,则只需更新该条目,然后稍后将在代码中处理该条目.
然而,我看到一些奇怪的行为,我无法理解.我的单元测试向我的QueueProcessor方法提交了两个请求(每次调用之间有2秒的延迟).为了测试,我故意在处理请求时QueueProcessor将调用的另一个方法中使用task.delay.这模拟了一个真实世界的测试用例,我们在处理第一个请求时阻止了其他请求.
我在我的子方法范围内使用一个名为ProcessRoutine的局部变量.但由于某种原因,当第二次调用进入更新全局缓存时,仅在ProcessRoutine方法范围内的局部变量也会更改.
此外,第二个请求将只有更新全局缓存变量然后停止的动作逻辑.因此没有其他代码被触发.我通过我的日志证实了这一点.我只是不明白为什么ProessRoutine方法中传递的数据集可以通过这种方式更改.
public async Task<bool> QueueProcessor(RtcPluginModel_IncidentModel passInModel)
{
//Ensure the processing cache is instantiated
if (QueueGlobalVariables.processingCache == null)
{
QueueGlobalVariables.processingCache = new List<tempTicketData>();
}
try
{
tempTicketData ticketItem = (tempTicketData)passInModel;
ticketItem.timeStamp = DateTime.Now;
var checkItemExistsInProcessingCache =
QueueGlobalVariables.processingCache.Find(
x => x.PAName == passInModel.PAName);
if (checkItemExistsInProcessingCache != null)
{
var result = QueueGlobalVariables.processingCache.Remove( QueueGlobalVariables.processingCache.Find(
x => x.PAName == passInModel.PAName && x.recordId == passInModel.recordId));
QueueGlobalVariables.processingCache.Add(ticketItem);
logger.Trace("Stopping update branch of code as no further action needed at this point.");
}
else …
Run Code Online (Sandbox Code Playgroud)