C# 路由:解析参数并调整它们
在将参数交给控制器之前,是否有任何方法可以自动解析参数 例如,目前,我有一个控制器如下所示:C# 路由:解析参数并调整它们,c#,asp.net-core,core,asp.net-core-3.1,C#,Asp.net Core,Core,Asp.net Core 3.1,在将参数交给控制器之前,是否有任何方法可以自动解析参数 例如,目前,我有一个控制器如下所示: [HttpGet] [路由(“{group}”)] 公共异步任务拆分(字符串组) { 返回Ok(db.Find(group)); } 如果路由参数表示为{group},dotnet中是否有任何功能允许我截取id,在数据库中查找实体并将实体交给控制器,如下所示: [HttpGet] [路由(“{group}”)] 公用异步任务拆分(组) { 返回Ok(组); } 我查看了DynamicRouteVal
[HttpGet]
[路由(“{group}”)]
公共异步任务拆分(字符串组)
{
返回Ok(db.Find(group));
}
如果路由参数表示为{group}
,dotnet中是否有任何功能允许我截取id,在数据库中查找实体并将实体交给控制器,如下所示:
[HttpGet]
[路由(“{group}”)]
公用异步任务拆分(组)
{
返回Ok(组);
}
我查看了DynamicRouteValueTransformer,
但它似乎是用来根据输入操作选择哪个控制器和操作的
奖金问题
此外,我想验证登录用户是否有权访问给定的组。是否有一种特定的方法可以做到这一点,而不必在每个控制器操作中都这样做?您可以为从数据库检索数据的类
组使用自定义模型绑定器:
public class GroupModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext is null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var modelName = bindingContext.ModelName;
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
var value = valueProviderResult.FirstValue;
if (string.IsNullOrEmpty(value))
{
return Task.CompletedTask;
}
// ************************************************
// Replace with your code for retrieve group from db
// ************************************************
var group = new Group { Name = "Bound Group", Description = "Bound group from custom model binder" };
bindingContext.Result = ModelBindingResult.Success(group);
return Task.CompletedTask;
}
}
要使用模型绑定器,只需创建一个自定义模型绑定器提供程序,该提供程序返回类型为组的模型绑定器
:
public class CustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(Group))
{
return new BinderTypeModelBinder(typeof(GroupModelBinder));
}
return null;
}
}
services.AddControllers(options =>
{
options.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());
});
并将其添加到启动的配置服务方法中:
public class CustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(Group))
{
return new BinderTypeModelBinder(typeof(GroupModelBinder));
}
return null;
}
}
services.AddControllers(options =>
{
options.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());
});
您可以为从数据库检索数据的类组使用自定义模型绑定器:
public class GroupModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext is null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var modelName = bindingContext.ModelName;
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
var value = valueProviderResult.FirstValue;
if (string.IsNullOrEmpty(value))
{
return Task.CompletedTask;
}
// ************************************************
// Replace with your code for retrieve group from db
// ************************************************
var group = new Group { Name = "Bound Group", Description = "Bound group from custom model binder" };
bindingContext.Result = ModelBindingResult.Success(group);
return Task.CompletedTask;
}
}
要使用模型绑定器,只需创建一个自定义模型绑定器提供程序,该提供程序返回类型为组的模型绑定器
:
public class CustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(Group))
{
return new BinderTypeModelBinder(typeof(GroupModelBinder));
}
return null;
}
}
services.AddControllers(options =>
{
options.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());
});
并将其添加到启动的配置服务方法中:
public class CustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(Group))
{
return new BinderTypeModelBinder(typeof(GroupModelBinder));
}
return null;
}
}
services.AddControllers(options =>
{
options.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());
});
关键字中间件
和操作过滤器
并且您可以实现操作过滤器来进行个人拦截,我会避免这样做。您开始将数据层与公共API紧密结合。我只接受字符串作为参数,并在服务层中查找值。@DavidG谢谢您的建议。对我来说,这似乎是一个必须重复的乏味代码。我理解这对架构的影响。但在哪里重复的冗长代码?如果它在服务层,就没有repeat.Keywordmiddleware
和ActionFilter
了,你可以实现动作过滤器来进行个人拦截,我会避免这样做。您开始将数据层与公共API紧密结合。我只接受字符串作为参数,并在服务层中查找值。@DavidG谢谢您的建议。对我来说,这似乎是一个必须重复的乏味代码。我理解这对架构的影响。但在哪里重复的冗长代码?如果它位于服务层,则不会重复。