Cce*_*e32 6 asp.net rest asp.net-core
我正在移植一个使用的 PHP/ CI API,$params = $this->uri->uri_to_assoc()
以便它可以接受具有多种组合的 GET 请求,例如:
有很多代码,如:
$page = 1;
if (!empty($params['page'])) {
$page = (int)$params['page'];
}
Run Code Online (Sandbox Code Playgroud)
1)catchall的常规路由:
app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Properties}/{action=Search}/{*params}"
);
});
Run Code Online (Sandbox Code Playgroud)
但是现在我必须解析
params
键/值对的字符串,并且无法利用模型绑定。
2)属性路由:
[HttpGet("properties/search")]
[HttpGet("properties/search/beds/{beds}")]
[HttpGet("properties/search/beds/{beds}/page/{page}")]
[HttpGet("properties/search/page/{page}/beds/{beds}")]
public IActionResult Search(int beds, double lat, double lon, int page = 1, int limit = 10) {
}
Run Code Online (Sandbox Code Playgroud)
显然,将允许的搜索参数和值的每个组合都放在一起是乏味的。
FromPath
价值提供者您想要的是将复杂模型绑定到 url 路径的一部分。不幸的是,ASP.NET Core 没有内置的FromPath
绑定器。不过幸运的是,我们可以构建自己的。
这是GitHub 中的一个示例FromPathValueProvider
,其结果如下:
基本上,它是有约束力的domain.com/controller/action/key/value/key/value/key/value
。FromRoute
这与价值提供者或价值提供者所做的不同FromQuery
。
FromPath
提供者创建这样的路线:
routes.MapRoute(
name: "properties-search",
template: "{controller=Properties}/{action=Search}/{*path}"
);
Run Code Online (Sandbox Code Playgroud)
将[FromPath]
属性添加到您的操作中:
public IActionResult Search([FromPath]BedsEtCetera model)
{
return Json(model);
}
Run Code Online (Sandbox Code Playgroud)
神奇的是,它将绑定*path
到一个复杂的模型:
public class BedsEtCetera
{
public int Beds { get; set; }
public int Page { get; set; }
public string Sort { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
FromPath
价值提供者基于 . 创建一个新属性FromRoute
。
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property,
AllowMultiple = false, Inherited = true)]
public class FromPath : Attribute, IBindingSourceMetadata, IModelNameProvider
{
/// <inheritdoc />
public BindingSource BindingSource => BindingSource.Custom;
/// <inheritdoc />
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
创建一个新的 IValueProviderFactory 基于RouteValueProviderFactory
.
public class PathValueProviderFactory : IValueProviderFactory
{
public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
{
var provider = new PathValueProvider(
BindingSource.Custom,
context.ActionContext.RouteData.Values);
context.ValueProviders.Add(provider);
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
基于 . 创建一个新的 IValueProvider RouteValueProvider
。
public class PathValueProvider : IValueProvider
{
public Dictionary<string, string> _values { get; }
public PathValueProvider(BindingSource bindingSource, RouteValueDictionary values)
{
if(!values.TryGetValue("path", out var path))
{
var msg = "Route value 'path' was not present in the route.";
throw new InvalidOperationException(msg);
}
_values = (path as string).ToDictionaryFromUriPath();
}
public bool ContainsPrefix(string prefix) => _values.ContainsKey(prefix);
public ValueProviderResult GetValue(string key)
{
key = key.ToLower(); // case insensitive model binding
if(!_values.TryGetValue(key, out var value)) {
return ValueProviderResult.None;
}
return new ValueProviderResult(value);
}
}
Run Code Online (Sandbox Code Playgroud)
使用扩展PathValueProvider
方法ToDictionaryFromUriPath
。
public static class StringExtensions {
public static Dictionary<string, string> ToDictionaryFromUriPath(this string path) {
var parts = path.Split('/');
var dictionary = new Dictionary<string, string>();
for(var i = 0; i < parts.Length; i++)
{
if(i % 2 != 0) continue;
var key = parts[i].ToLower(); // case insensitive model binding
var value = parts[i + 1];
dictionary.Add(key, value);
}
return dictionary;
}
}
Run Code Online (Sandbox Code Playgroud)
将课堂上的事物连接在一起Startup
。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddMvcOptions(options =>
options.ValueProviderFactories.Add(new PathValueProviderFactory()));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc(routes => {
routes.MapRoute(
name: "properties-search",
template: "{controller=Properties}/{action=Search}/{*path}"
);
});
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6215 次 |
最近记录: |