Skip to main content
 首页 » 编程设计

c#之将参数传递给 Web API 模型联编程序

2024年01月01日51arxive

我正在尝试创建 Web API 模型绑定(bind)器,它将绑定(bind)由 javascript 框架的网格组件发送的 URL 参数。 Grid 发送 URL 参数,指示标准页面、pageSize 和 JSON 格式的排序器、过滤器和分组器。 URL 字符串如下所示:

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

所讨论的模型是 Inventory,它具有简单的 Count (int) 属性和一个引用 Part (Part) 属性(后者又具有 Name、Status)。 View 模型/dto 被展平(InventoryViewModel .Count、.PartName、.PartStatus 等) 我用 Dynamic Expression Api然后查询域模型,将结果映射到 View 模型并将其作为 JSON 发送回。 在模型绑定(bind)期间,我需要通过检查正在使用的模型和 View 模型来构建表达式。

为了保持模型绑定(bind)器可重用,我如何传递/指定正在使用的模型和 View 模型类型? 我需要这个来构建有效的排序、过滤和分组 expsessions 注意:我不想将这些作为网格 url 参数的一部分传递!

我的一个想法是使 StoreRequest 通用(例如 StoreRequest),但我不确定模型绑定(bind)器是否或如何工作。

示例 API Controller

// 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; 
    } 
} 

请您参考如下方法:

只需更改您的 Controller 签名即可

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

问候