2017-04-25 40 views
0

的問題是,QueryParams對象是不是蛇的情況下SnakeCase QueryParams對.NET核心

 public async Task<IActionResult> Search (
     [FromQuery] ProjectFilterDto filterParams, 
     [FromQuery(Name = "page_size")] int pageSize = 10, 
     [FromQuery(Name = "page_index")] int pageIndex = 0) 

enter image description here

所有其他的事情,FromBody和響應在蛇的情況下語法

安裝調試;

options.SerializerSettings.ContractResolver = new DefaultContractResolver() 
{ 
    NamingStrategy = new SnakeCaseNamingStrategy(true, true) 
}; 

有沒有什麼辦法,使查詢參數一樣ProjectFilterDto是蛇的情況下不使用FromQuery(名稱=「X」)?

回答

2

從創建一個擴展方法開始,該方法將給定的字符串轉換爲它的蛇形封裝版本。下一步我們將需要這種方法。

public static string ToSnakeCase(this string s) 
{ 
    if (string.IsNullOrWhiteSpace(s)) 
    { 
     return s; 
    } 

    s = s.Trim(); 

    var length = s.Length; 
    var addedByLower = false; 
    var stringBuilder = new StringBuilder(); 

    for (var i = 0; i < length; i++) 
    { 
     var currentChar = s[i]; 

     if (char.IsWhiteSpace(currentChar)) 
     { 
      continue; 
     } 

     if (currentChar.Equals('_')) 
     { 
      stringBuilder.Append('_'); 
      continue; 
     } 

     bool isLastChar = i + 1 == length, 
       isFirstChar = i == 0, 
       nextIsUpper = false, 
       nextIsLower = false; 

     if (!isLastChar) 
     { 
      nextIsUpper = char.IsUpper(s[i + 1]);      
      nextIsLower = !nextIsUpper && !s[i + 1].Equals('_'); 
     } 

     if (!char.IsUpper(currentChar)) 
     { 
      stringBuilder.Append(char.ToLowerInvariant(currentChar)); 

      if (nextIsUpper) 
      { 
       stringBuilder.Append('_'); 
       addedByLower = true; 
      } 

      continue; 
     } 

     if (nextIsLower && !addedByLower && !isFirstChar) 
     { 
      stringBuilder.Append('_'); 
     } 

     addedByLower = false; 

     stringBuilder.Append(char.ToLowerInvariant(currentChar)); 
    } 

    return stringBuilder.ToString(); 
} 

現在我們可以創建一個自定義值提供商查找使用我們上面定義的ToSnakeCase()擴展方法蛇套管查詢參數。

public class SnakeCaseQueryValueProvider : QueryStringValueProvider, IValueProvider 
{ 
    public SnakeCaseQueryValueProvider(
     BindingSource bindingSource, 
     IQueryCollection values, 
     CultureInfo culture) 
     : base(bindingSource, values, culture) 
    { 
    } 

    public override bool ContainsPrefix(string prefix) 
    { 
     return base.ContainsPrefix(prefix.ToSnakeCase()); 
    } 

    public override ValueProviderResult GetValue(string key) 
    { 
     return base.GetValue(key.ToSnakeCase()); 
    } 
} 

我們也必須實現一個工廠,我們的價值提供者:

public class SnakeCaseQueryValueProviderFactory : IValueProviderFactory 
{ 
    public Task CreateValueProviderAsync(ValueProviderFactoryContext context) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException(nameof(context)); 
     } 

     var valueProvider = new SnakeCaseQueryValueProvider(
      BindingSource.Query, 
      context.ActionContext.HttpContext.Request.Query, 
      CultureInfo.CurrentCulture); 

     context.ValueProviders.Add(valueProvider); 

     return Task.CompletedTask; 
    } 
} 

唯一剩下要做的就是註冊在啓動類的ConfigureServices方法的價值提供者。

public void ConfigureServices(IServiceCollection services) 
{ 
    services 
     .AddMvc(options => 
     { 
      options.ValueProviderFactories.Add(new SnakeCaseQueryValueProviderFactory()); 
     }) 
     .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver 
     { 
      NamingStrategy = new SnakeCaseNamingStrategy() 
     }); 
} 

希望這會有所幫助!

我寫了一個博客張貼關於它的一切都在這裏:http://www.sorting.se/enable-snake-cased-query-parameters-in-your-restfull-asp-net-core-web-api/

+0

偉大的工作!這是解決方案 –