我正在嘗試創建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;
}
}