如何始终执行功能,而不管调用的 API 路由如何?
How to always perform a function, regardless of the API route called?
我正在创建 NetCore 2 API 并连接到 SQL 服务器数据库。无论路由是什么,都可以始终调用一个函数吗?我的例子:
对于每个调用,我都会传递必要的参数以连接到 header 中的 SQL 数据库。我将在此 api 中进行数百次调用,因此我真的不想为每次调用都重复此操作:
[HttpGet]
public async Task<IEnumerable<DEPARTMENT>> Get(
[FromHeader] string Server,
[FromHeader] string Database,
[FromHeader] string Username,
[FromHeader] string Password,
[FromHeader] string Trusted)
{
util.SetConnectionString(Server, Database, Username, Password, Trusted);
return await this.departmentDataProvider.GetDepartments();
}
[HttpGet("{DepartmentId}")]
public async Task<IEnumerable<DEPARTMENT>> Get(
string DepartmentId,
[FromHeader] string Server,
[FromHeader] string Database,
[FromHeader] string Username,
[FromHeader] string Password,
[FromHeader] string Trusted)
{
util.SetConnectionString(Server, Database, Username, Password, Trusted);
return await this.departmentDataProvider.GetDepartment(DepartmentId);
}
我想创建一个只有 header 连接参数的祖先函数,以及设置连接字符串的调用。最终目标是这样的:
祖先:
[HttpGet]
public async Task<IEnumerable<?>> Get(
[FromHeader] string Server,
[FromHeader] string Database,
[FromHeader] string Username,
[FromHeader] string Password,
[FromHeader] string Trusted)
{
util.SetConnectionString(Server, Database, Username, Password, Trusted);
}
Children:
[HttpGet]
public async Task<IEnumerable<DEPARTMENT>> Get()
{
return await this.departmentDataProvider.GetDepartments();
}
[HttpGet("{DepartmentId}")]
public async Task<IEnumerable<DEPARTMENT>> Get(string DepartmentId)
{
return await this.departmentDataProvider.GetDepartment(DepartmentId);
}
编辑:
添加 Util.cs & DepartmentDataProvider.cs 以获取更多信息。
Util.cs
public static class util
{
public static string ConnectionString { get; set; }
public static void SetConnectionString(string Server, string Database, string UserName, string Password, string Trusted)
{
if (Trusted == "true")
ConnectionString = "Server=" + Server + ";Database=" + Database + ";Trusted_Connection=True;";
else
ConnectionString = "Server=" + Server + ";Database=" + Database + ";User ID= " + UserName + ";Password=" + Password + ";Trusted_Connection=False;";
}
public static string GetConnectionString()
{
return ConnectionString;
}
}
DepartmentDataProvider.cs
public class DepartmentDataProvider : IDepartmentDataProvider
{
public async Task<DEPARTMENT> GetDepartment(int DepartmentId)
{
string connString = util.GetConnectionString();
using (var sqlConnection = new SqlConnection(util.GetConnectionString()))
{
await sqlConnection.OpenAsync();
var dynamicParameters = new DynamicParameters();
dynamicParameters.Add("@DepartmentID", DepartmentId);
return await sqlConnection.QuerySingleOrDefaultAsync<DEPARTMENT>(
"Select * From DEPARTMENT Where DEPARTMENT_ID = @DepartmentID",
dynamicParameters,
commandType: CommandType.Text);
}
}
}
创建一个 class 来封装连接字符串数据,任何相关的 object 将被注入其中(例如可能是 HttpContext
):
public class ConnectingStringParmsFromHeaders
{
public string Server { get; private set; }
// other properties
// ideally you wouldn't depend on ASP.NET Core constructs such as HttContext
// but I'm using it here for brevity
public ConnectionStringPropertiesFromHeaders( HttpContext httpContext )
{
ReadPropertiesFromHeaders( httpContext.Request.Headers );
}
private void ReadPropertiesFromHeaders( IHeaderDictionary headers )
{
// do your header-reading thing here
}
public string BuildConnectionString()
{
// your Util.SetConnectionString(...) code here
// using local instance properties and not static properties
}
}
接下来,register 这个 class 的生命周期为 Scoped
(在同一个 HTTP 请求中重复使用单个 object):
public void ConfigureServices(IServiceCollection services)
{
...
services.AddScoped<ConnectionStringParmsFromHeaders>();
}
最后,将此类型的参数添加到控制器的构造函数中,并设置一个 属性 或字段以用于操作方法:
public class DepartmentsController : Controller
{
private ConnectionStringParmsFromHeaders ConnStrParms { get; private set; }
public DepartmentsController( ConnectionStringParmsFromHeaders connStrParms )
{
ConnStrParms = connStrParms;
}
public async Task<IActionResult> Get()
{
// for illustrative purposes
var connStr = connStrParms.BuildConnectionString();
// remainder of your action method's code
}
}
请注意,您的 Util
class 设置静态 属性 和 per-http-request header 数据是一个问题 b/c 可以有多个并发线程读取和写入相同的 属性 和不同的数据——您将不知道您是否使用了正确的数据!将连接字符串生成代码移动到此新配置 class,以便您可以在 per-request 基础上访问它,如上面的代码示例所示。
上面的代码可能不是 100% 准确,因为我现在无法对其进行测试,但它应该足以让你到达你需要去的地方。
我正在创建 NetCore 2 API 并连接到 SQL 服务器数据库。无论路由是什么,都可以始终调用一个函数吗?我的例子:
对于每个调用,我都会传递必要的参数以连接到 header 中的 SQL 数据库。我将在此 api 中进行数百次调用,因此我真的不想为每次调用都重复此操作:
[HttpGet]
public async Task<IEnumerable<DEPARTMENT>> Get(
[FromHeader] string Server,
[FromHeader] string Database,
[FromHeader] string Username,
[FromHeader] string Password,
[FromHeader] string Trusted)
{
util.SetConnectionString(Server, Database, Username, Password, Trusted);
return await this.departmentDataProvider.GetDepartments();
}
[HttpGet("{DepartmentId}")]
public async Task<IEnumerable<DEPARTMENT>> Get(
string DepartmentId,
[FromHeader] string Server,
[FromHeader] string Database,
[FromHeader] string Username,
[FromHeader] string Password,
[FromHeader] string Trusted)
{
util.SetConnectionString(Server, Database, Username, Password, Trusted);
return await this.departmentDataProvider.GetDepartment(DepartmentId);
}
我想创建一个只有 header 连接参数的祖先函数,以及设置连接字符串的调用。最终目标是这样的:
祖先:
[HttpGet]
public async Task<IEnumerable<?>> Get(
[FromHeader] string Server,
[FromHeader] string Database,
[FromHeader] string Username,
[FromHeader] string Password,
[FromHeader] string Trusted)
{
util.SetConnectionString(Server, Database, Username, Password, Trusted);
}
Children:
[HttpGet]
public async Task<IEnumerable<DEPARTMENT>> Get()
{
return await this.departmentDataProvider.GetDepartments();
}
[HttpGet("{DepartmentId}")]
public async Task<IEnumerable<DEPARTMENT>> Get(string DepartmentId)
{
return await this.departmentDataProvider.GetDepartment(DepartmentId);
}
编辑:
添加 Util.cs & DepartmentDataProvider.cs 以获取更多信息。
Util.cs
public static class util
{
public static string ConnectionString { get; set; }
public static void SetConnectionString(string Server, string Database, string UserName, string Password, string Trusted)
{
if (Trusted == "true")
ConnectionString = "Server=" + Server + ";Database=" + Database + ";Trusted_Connection=True;";
else
ConnectionString = "Server=" + Server + ";Database=" + Database + ";User ID= " + UserName + ";Password=" + Password + ";Trusted_Connection=False;";
}
public static string GetConnectionString()
{
return ConnectionString;
}
}
DepartmentDataProvider.cs
public class DepartmentDataProvider : IDepartmentDataProvider
{
public async Task<DEPARTMENT> GetDepartment(int DepartmentId)
{
string connString = util.GetConnectionString();
using (var sqlConnection = new SqlConnection(util.GetConnectionString()))
{
await sqlConnection.OpenAsync();
var dynamicParameters = new DynamicParameters();
dynamicParameters.Add("@DepartmentID", DepartmentId);
return await sqlConnection.QuerySingleOrDefaultAsync<DEPARTMENT>(
"Select * From DEPARTMENT Where DEPARTMENT_ID = @DepartmentID",
dynamicParameters,
commandType: CommandType.Text);
}
}
}
创建一个 class 来封装连接字符串数据,任何相关的 object 将被注入其中(例如可能是 HttpContext
):
public class ConnectingStringParmsFromHeaders
{
public string Server { get; private set; }
// other properties
// ideally you wouldn't depend on ASP.NET Core constructs such as HttContext
// but I'm using it here for brevity
public ConnectionStringPropertiesFromHeaders( HttpContext httpContext )
{
ReadPropertiesFromHeaders( httpContext.Request.Headers );
}
private void ReadPropertiesFromHeaders( IHeaderDictionary headers )
{
// do your header-reading thing here
}
public string BuildConnectionString()
{
// your Util.SetConnectionString(...) code here
// using local instance properties and not static properties
}
}
接下来,register 这个 class 的生命周期为 Scoped
(在同一个 HTTP 请求中重复使用单个 object):
public void ConfigureServices(IServiceCollection services)
{
...
services.AddScoped<ConnectionStringParmsFromHeaders>();
}
最后,将此类型的参数添加到控制器的构造函数中,并设置一个 属性 或字段以用于操作方法:
public class DepartmentsController : Controller
{
private ConnectionStringParmsFromHeaders ConnStrParms { get; private set; }
public DepartmentsController( ConnectionStringParmsFromHeaders connStrParms )
{
ConnStrParms = connStrParms;
}
public async Task<IActionResult> Get()
{
// for illustrative purposes
var connStr = connStrParms.BuildConnectionString();
// remainder of your action method's code
}
}
请注意,您的 Util
class 设置静态 属性 和 per-http-request header 数据是一个问题 b/c 可以有多个并发线程读取和写入相同的 属性 和不同的数据——您将不知道您是否使用了正确的数据!将连接字符串生成代码移动到此新配置 class,以便您可以在 per-request 基础上访问它,如上面的代码示例所示。
上面的代码可能不是 100% 准确,因为我现在无法对其进行测试,但它应该足以让你到达你需要去的地方。