- 用Route形式承载批量信息:对于URL:api/touristRoutes/(1,2,3,4)这类括号内包含批量信息的情况
通用的做法:①在http中匹配字符串:[HttpDelete("({Ids})"),此时Ids对应"1,2,3,4",在类型时选择IEnumerableIds,然后对Ids进行字符串解析
using Microsoft.AspNetCore.Mvc.ModelBinding;//Microsoft.AspNetCore.ModelBinding里面也有一个IModelBinder,注意区分
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace TouristTest.Helpers
{
public class ArrayModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
// Our binder works only on enumerable types
if (!bindingContext.ModelMetadata.IsEnumerableType)
{
bindingContext.Result = ModelBindingResult.Failed();
return Task.CompletedTask;
}
// Get the inputted value through the value provider
string value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).ToString();
// If that value is null or whitespace, we return null
if (string.IsNullOrWhiteSpace(value))
{
bindingContext.Result = ModelBindingResult.Success(null);
return Task.CompletedTask;
}
// The value isn't null or whitespace,
// and the type of the model is enumerable.
// Get the enumerable's type, and a converter
Type elementType = bindingContext.ModelType.GetTypeInfo().GenericTypeArguments[0];
TypeConverter converter = TypeDescriptor.GetConverter(elementType);
// Convert each item in the value list to the enumerable type
object[] values = value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(x => converter.ConvertFromString(x.Trim())).ToArray();
// Create an array of that type, and set it as the Model value
Array typedValues = Array.CreateInstance(elementType, values.Length);
values.CopyTo(typedValues, 0);
bindingContext.Model = typedValues;
// return a successful result, passing in the Model
bindingContext.Result = ModelBindingResult.Success(bindingContext.Model);
return Task.CompletedTask;
}
}
}
使用
[HttpDelete("({touristIDs})")]
[Authorize(Roles = "Admin")]
public async Task<IActionResult> DeleteByIDs(
[ModelBinder( BinderType = typeof(ArrayModelBinder))][FromRoute]IEnumerable<Guid> touristIDs)
{
if(touristIDs == null)
{
return BadRequest();
}
var touristRoutesFromRepo = await _touristRouteRepository.GetTouristRoutesByIDListAsync(touristIDs);
_touristRouteRepository.DeleteTouristRoutes(touristRoutesFromRepo);
await _touristRouteRepository.SaveAsync();
return NoContent();
}
- 用FromQuery的形式承载批量信息:对于URL:api/touristRoutes?Ids=1,2,3,4&orderby=title desc,description
api/touristRoutes?orderby=title,id这种一个词携带多个的情况:
1、单个变量直接使用
[route("search")]
public IActionResult Action([FromQuery(Name="actions")] string keyword,[FromQuery(Name="actions2")] string keyword2){}
//传入的URL:https:localhost/api/search?actions=123&actions2=234
//或者
[route("search")]
public IActionResult Action([FromQuery] string keyword,string keyword2){}//两者都是FromQuery,写一个或者都不写。
//传入的URL应为:https:localhost/api/search?keyword=123&keyword2=234
2、将全部的变量单独封装
new一个新的类,封装全部的关键词,并在该类中把URL信息中包含的逻辑信息解析为参数。
例:URL信息为:https:localhost/api/search?actions=lessthan123&actions2=234(包含的信息为小于123)
下面为类的代码:
public class TouristRouteResourceParamaters
{
public string Keyword { get; set; }//不包含逻辑的直接get set一个属性
public string RatingOperator { get; set; }
public int? RatingValue { get; set; }
private string _rating;//包含逻辑的需要写一个逻辑,把rating转化为Rating、RatingValue、RatingOperator
public string Rating {
get { return _rating; }
set
{
if (!string.IsNullOrWhiteSpace(value))
{
Regex regex = new Regex(@"([A-Za-z0-9\-]+)(\d+)");
Match match = regex.Match(value);
if (match.Success)
{
RatingOperator = match.Groups[1].Value;
RatingValue = Int32.Parse(match.Groups[2].Value);
}
}
_rating = value;
}
}
}
使用方法:
public async Task<IActionResult> GerTouristRoutes([FromQuery] TouristRouteResourceParamaters paramaters)
调用参数(例)
if (!_propertyMappingService
.IsMappingExists<TouristRouteDto, TouristRoute>(
paramaters.OrderBy))
{
return BadRequest("请输入正确的排序参数");
}