2017-08-10 40 views
1

我如何复杂的对象转换为查询字符串用于的WebAPI:转换复杂对象查询字符串

export enum FilterCondition { 
    Equal, 
    NotEqual, 
    GreaterThan, 
    LessThan, 
    GreaterThanEqual, 
    LessThanEqual 
} 

export class QueryParameter { 
    propertyName: string; 
    filterCondition: FilterCondition 
    value: string; 
} 

export class QueryOptions { 
    queryParameters: QueryParameter[] = new Array<QueryParameter>(); 
} 

我想编写一个通用的功能到复杂的类型转换为基本查询 我写的这个函数转换一个简单的对象查询字符串

export class QueryStringBuilder { 
    static BuildParametersFromSearch<T>(obj: T): URLSearchParams { 
     let params: URLSearchParams = new URLSearchParams(); 

     const objectKeys = Object.keys(obj) as Array<keyof T>; 
     for (let key of objectKeys) { 
      params.set(key, obj[key]) 
     } 

     return params; 
    } 
} 

但我有麻烦抓我怎么能与枚举和数组等复杂的对象做到这一点递归?任何人都可以指向正确的方向,或者已经做到了这一点?

回答

2

因为任何人想知道如何做到这一点,我写了一个扩展,应该与c#.Net Core 1.1和Typescript 2.2.2 WebApi一起工作,看起来像这样。

记住,你正在使用它,以及

import { URLSearchParams } from '@angular/http'; 
import 'rxjs/add/operator/map' 

export class QueryStringBuilder { 
    static BuildParametersFromSearch<T>(obj: T): URLSearchParams { 
     let params: URLSearchParams = new URLSearchParams(); 

     if (obj == null) 
     { 
      return params; 
     } 

     QueryStringBuilder.PopulateSearchParams(params, '', obj); 

     return params; 
    } 

    private static PopulateArray<T>(params: URLSearchParams, prefix: string, val: Array<T>) { 
     for (let index in val) { 
      let key = prefix + '[' + index + ']'; 
      let value: any = val[index]; 
      QueryStringBuilder.PopulateSearchParams(params, key, value); 
     } 
    } 

    private static PopulateObject<T>(params: URLSearchParams, prefix: string, val: T) { 
     const objectKeys = Object.keys(val) as Array<keyof T>; 

     if (prefix) { 
      prefix = prefix + '.'; 
     } 

     for (let objKey of objectKeys) { 

      let value = val[objKey]; 
      let key = prefix + objKey; 

      QueryStringBuilder.PopulateSearchParams(params, key, value); 
     } 
    } 

    private static PopulateSearchParams<T>(params: URLSearchParams, key: string, value: any) { 
     if (value instanceof Array) { 
      QueryStringBuilder.PopulateArray(params, key, value); 
     } 
     else if (value instanceof Date) { 
      params.set(key, value.toISOString()); 
     } 
     else if (value instanceof Object) { 
      QueryStringBuilder.PopulateObject(params, key, value); 
     } 
     else { 
      params.set(key, value.toString()); 
     } 
    } 
} 

这是工作的所有复杂类型到目前为止,我已经使用,包括这两个进口。

编辑用法我已经包括了所有的import语句我认为重要的是RequestOptionsArgs,RequestOptions的,但我记得他们需要这样只是柜面我已经包括了他们所有人。

import { Injectable } from '@angular/core'; 
import { Http, Headers, RequestOptionsArgs, RequestOptions } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { IHasId } from '../interfaces/interfaces'; 
import 'rxjs/add/operator/map'; 

import { QueryOptions, IFilterNode } from "../models/queryOptions"; 
import { QueryStringBuilder } from "../models/QueryStringBuilder"; 

import 'rxjs/add/operator/map' 

@Injectable() 
export class ProviderBase<T extends IHasId> { 

    getList(filterParams?: IFilterNode): Observable<T[]> { 
     var searchParams = QueryStringBuilder.BuildParametersFromSearch(filterParams); 

     let requestArguments: RequestOptionsArgs = new RequestOptions({ search: searchParams }); 
     return this.http.get(`${this.apiUrl}/${this.route}`, requestArguments).map(res => <T[]>res.json()); 
    } 
} 
+0

的利用方法可能是有用的也 –

+1

@RobMcCabe我会后一个在一秒钟。必须在我的github上找到它 –

+0

@RobMcCabe我已经更新,包括一个示例用法,一些导入是必需的IHasId是我自定义的,所以你可以忽略那个等 –