2012-10-15 57 views
2

我正在嘗試創建Web API模型綁定器,該綁定器將綁定由JavaScript框架的網格組件發送的URL參數。 網格發送指示標準頁面,pageSize和JSON格式的分類器,過濾器和石斑的URL參數。 URL字符串看起來是這樣的:將參數傳遞給Web API模型綁定器

http://localhost/api/inventory?page=1&start=0&limit=10sort=[{"property":"partName","direction":"desc"},{"property":"partStatus","direction":"asc"}]&group=[{"property":"count","direction":"asc"}] 

有問題的模型是庫存它具有簡單,計數(INT)財產和參考部分,(部分)peoperty(這反過來名稱,狀態)。 查看模型/ dto被展平(InventoryViewModel .Count,.PartName,.PartStatus等等) 然後我使用Dynamic Expression Api查詢域模型,將結果映射到查看模型並將其作爲JSON發回。 在模型綁定過程中,我需要通過檢查正在使用的模型和視圖模型來構建表達式。

爲了保持模型聯編程序可重用,我如何傳遞/指定模型和視圖模型類型被使用? 我需要這個爲了構建有效的排序,篩選和分組experssions 注意:我不想傳遞這些作爲網格url params的一部分!

我的一個想法是讓StoreRequest成爲通用的(例如StoreRequest),但我不確定模型綁定器是否可行或如何工作。

樣品API控制器

// 1. model binder is used to transform URL params into StoreRequest. Is there a way to "pass" types of model & view model to it? 
    public HttpResponseMessage Get(StoreRequest storeRequest) 
    { 
      int total; 
      // 2. domain entites are then queried using StoreRequest properties and Dynamic Expression API (e.g. "Order By Part.Name DESC, Part.Status ASC") 
      var inventoryItems = _inventoryService.GetAll(storeRequest.Page, out total, storeRequest.PageSize, storeRequest.SortExpression); 
      // 3. model is then mapped to view model/dto 
      var inventoryDto = _mapper.MapToDto(inventoryItems); 
      // 4. response is created and view model is wrapped into grid friendly JSON 
      var response = Request.CreateResponse(HttpStatusCode.OK, inventoryDto.ToGridResult(total)); 
      response.Content.Headers.Expires = DateTimeOffset.UtcNow.AddMinutes(5); 
      return response; 
    } 

StoreRequestModelBinder

public class StoreRequestModelBinder : IModelBinder 
{ 
    private static readonly ILog Logger = LogManager.GetCurrentClassLogger(); 

    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
     Logger.Debug(m => m("Testing model binder for type: {0}", bindingContext.ModelType)); 
     if (bindingContext.ModelType != typeof(StoreRequest)) 
     { 
      return false; 
     } 
     var storeRequest = new StoreRequest(); 
     // ---------------------------------------------------------------- 
     int page; 
     if (TryGetValue(bindingContext, StoreRequest.PageParameter, out page)) 
     { 
      storeRequest.Page = page; 
     } 
     // ---------------------------------------------------------------- 
     int pageSize; 
     if (TryGetValue(bindingContext, StoreRequest.PageSizeParameter, out pageSize)) 
     { 
      storeRequest.PageSize = pageSize; 
     } 
     // ---------------------------------------------------------------- 
     string sort; 
     if (TryGetValue(bindingContext, StoreRequest.SortParameter, out sort)) 
     { 
      try 
      { 
       storeRequest.Sorters = JsonConvert.DeserializeObject<List<Sorter>>(sort); 
       // TODO: build sort expression using model and viewModel types 
      } 
      catch(Exception e) 
      { 
       Logger.Warn(m=>m("Unable to parse sort parameter: \"{0}\"", sort), e); 
      } 
     } 
     // ---------------------------------------------------------------- 
     bindingContext.Model = storeRequest; 
     return true; 
    } 

    private bool TryGetValue<T>(ModelBindingContext bindingContext, string key, out T result) 
    { 
     var valueProviderResult = bindingContext.ValueProvider.GetValue(key); 
     if (valueProviderResult == null) 
     { 
      result = default(T); 
      return false; 
     } 
     result = (T)valueProviderResult.ConvertTo(typeof(T)); 
     return true; 
    } 
} 

回答

0

只是改變你的控制器的簽名像

public HttpResponseMessage Get([ModelBinder(typeof(StoreRequestModelBinder)]StoreRequest storeRequest) 

問候