小编Jas*_*rke的帖子

使用外部API调用分离验证器和服务

我目前正在构建一个Web应用程序,并尝试按照良好的MVC和面向服务的体系结构进行设计.

但是,我在连接表示层(即我的控制器)和后端服务时遇到了一些障碍,同时仍然保持良好的错误/验证报告给用户.

在这里阅读了一篇非常好的SO帖子,关于如何将验证逻辑与服务层分开,并且大部分都是有意义的.然而,有一个"缺陷",如果你可以称之为,在这个模型中,我嘻嘻哈哈:在查找验证器和服务所需的对象时,如何避免重复工作?

我认为用一个相当简单的例子解释会更容易:

假设我有一个允许用户共享代码片段的应用程序.现在,我决定添加一项新功能,允许用户将他们的GitHub帐户附加到我的网站上的帐户(即建立个人资料).出于这个例子的目的,我将简单地假设我的所有用户都是值得信赖的,并且只会尝试添加他们自己的GitHub帐户,而不是其他人的:)

按照前面提到的SO文章,我已经设置了一个基本的GitHub服务来检索GitHub用户信息.

interface IGitHubUserService {
    GitHubUser FindByUserName(string username);
}
Run Code Online (Sandbox Code Playgroud)

GitHubUserService的具体实现会进行昂贵的调用以https://api.github.com/users/{0}获取用户信息.再次,按照文章的模型,我实现了以下命令将用户帐户链接到GitHub用户:

// Command for linking a GitHub account to an internal user account
public class GitHubLinkCommand {
    public int UserId { get; set; }
    public string GitHubUsername { get; set }
};
Run Code Online (Sandbox Code Playgroud)

我的验证者需要验证用户输入的用户名是否是有效的GitHub帐户.这是非常简单的:调用FindByUserNameGitHubUserService,并确保结果不为空:

public sealed class GitHubLinkCommandValidator : Validator<GitHubLinkCommand> {
    private readonly IGitHubUserService _userService;

    public GitHubLinkCommandValidator(IGitHubUserService userService) {
        this._userService = userService;
    }

    protected override IEnumerable<ValidationResult> Validate(GitHubLinkCommand command) …
Run Code Online (Sandbox Code Playgroud)

c# asp.net-mvc service-layer

12
推荐指数
1
解决办法
262
查看次数

导出的功能转发给自己?

今天我遇到解析Windows可移植可执行文件结构的时候遇到了一个非常奇怪的问题.具体在Export表中.

在尝试解析DLL中导出函数的函数地址时,我发现自己得到了Stack Overflow(所以这看起来像是最合适的QA板).

我编写了自己的版本,GetProcAddress手动解析而不是调用现有GetProcAddress方法.请不要只是告诉我要使用现有的GetProcAddress方法,它不适合我目前的状况,我想了解这个东西.

对于我遇到的大多数情况,我的版本工作得非常好,并没有遇到任何问题.但是,该函数是针对名为API-MS-Win-Core-ProcessThreads-L1-1-0.dll(作为递归解析的一部分)的DLL进行测试的Kernel32.dll,这是StackOverflow发生的时间.

我把它缩小到以下函数导出API-MS-Win-Core-ProcessThreads-L1-1-0.dll:

CreateRemoteThreadEx
Run Code Online (Sandbox Code Playgroud)

现在,此导出的函数实际上是转发导出.通常这不用担心; 我编写了我的函数,以便它应该处理转发的导出.但是此功能转发给

api-ms-win-core-processthreads-l1-1-0.CreateRemoteThreadEx

有人在这看到问题吗?逐句通过代码,我的GetProcAddress函数然后调用LoadLibraryapi-ms-win-core-processthreads-l1-1-0,然后尝试递归查找CreateRemoteThreadEx.然而,在下一次迭代中,该CreateRemoteThreadEx函数再次转发到...

api-ms-win-core-processthreads-l1-1-0.CreateRemoteThreadEx

然后开始StackOverflow.经过一番调查后我发现了调用的结果

LoadLibraryA("api-ms-win-core-processthreads-l1-1-0");
Run Code Online (Sandbox Code Playgroud)

返回与之相同的结果

LoadLibraryA("kernel32.dll");
Run Code Online (Sandbox Code Playgroud)

我很难过.

这是我目前的代码:

#include <Windows.h>

#define MKPTR(p1,p2) ((DWORD_PTR)(p1) + (DWORD_PTR)(p2))

INT LookupExport(IMAGE_DOS_HEADER* pDosHd, DWORD* pNames, DWORD nNames, LPCSTR lpProcName)
{
    // Do a binary search on the name pointer table
    INT start = 0, 
        index = -1,
        middle = -1, 
        end = nNames …
Run Code Online (Sandbox Code Playgroud)

c++ windows portable-executable

5
推荐指数
1
解决办法
1997
查看次数

导出的DLL函数没有词法排序?

好吧,今天我遇到了一个奇怪的问题.我刚才写了自己的GetProcAddress版本来获取远程进程的函数地址.我显然花了很多时间阅读PE架构,找出解决这个问题的最佳方法.

根据PECOFF v8规范(我认为它是最新的官方规范),有以下符号Export Name Pointer Table:

导出名称指针表是导出名称表中的地址数组(RVAs).指针各32位,并且相对于图像库.指针是词法排序的,以允许二进制搜索.

所以我在编写GetProcAddress版本时考虑到了这一点.显然,使用线性搜索的二进制搜索,在导出表格中可以有很好的效率提升... KERNEL32.dll(1300+导出函数).

直到今天,我遇到了一个奇怪的问题.看起来Kernel32中的一些导出函数实际上并没有按词汇顺序排序,这就是我的二进制搜索.以下是使用我将在下面发布的函数导出的Dll转储的摘录:

Ordinal: 810    Name: K32QueryWorkingSetEx
Ordinal: 811    Name: LCIDToLocaleName
Ordinal: 812    Name: LCMapStringA
Ordinal: 813    Name: LCMapStringEx
Ordinal: 814    Name: LCMapStringW
Ordinal: 815    Name: LZClose
Ordinal: 816    Name: LZCloseFile
Ordinal: 817    Name: LZCopy
Ordinal: 818    Name: LZCreateFileW
Ordinal: 819    Name: LZDone
Ordinal: 820    Name: LZInit
Ordinal: 821    Name: LZOpenFileA
Ordinal: 822    Name: LZOpenFileW
Ordinal: 823    Name: LZRead
Ordinal: 824    Name: LZSeek
Ordinal: 825    Name: LZStart
Ordinal: 826    Name: LeaveCriticalSection …
Run Code Online (Sandbox Code Playgroud)

c++ windows portable-executable

4
推荐指数
1
解决办法
665
查看次数

在临时目录中创建新项目

首先可能需要一些上下文,

基本上我在过去几年里一直在使用VS2008 Express版本.使用快速版本(C++除外),默认情况下,在创建新项目时,项目文件都存储在临时目录中.当您第一次选择"全部保存"时,VS会提示输入项目目录,然后您可以将项目保存到常规项目目录中.

这是我发现非常有用的行为,因为很多时候我创建了非常快速,简单的程序,在我再也不需要它们之前为我做一件事.一旦我关闭VS,它会提示我是否要保存项目,我选择"丢弃"并且一切都很好; 我的项目目录不会被一次性项目的无用目录弄得乱七八糟,每个人都赢了.

然而,随着VS2010最终我注意到,默认行为已发生变化,所有新项目都直接创建到我的项目目录(是的,我知道创建项目时,我可以更改目录,但这是时间的不必要的浪费) .这使我每次想写一个小程序时都会回复表达版本,这在家里并不算太差,但在工作中我们只有VS2010专业版.每次我创建一个简单的项目时,我都要记得以后删除该目录或者面对"WindowsFormsApplication1000232131231"目录.

所以我的问题是:是否有可能改变VS2010 Profession/Ultimate的默认项目创建行为以匹配早期的2008 Express版本?

干杯,J

c# vb.net visual-studio-2010 visual-studio

2
推荐指数
1
解决办法
146
查看次数