Skip to main content
 首页 » 编程设计

c#之WebAPI 模型绑定(bind)之[FromUri] 不适用于 Guid 的枚举

2024年04月17日37tintown

我正在尝试构建一个 RESTApi 端点,用户可以在其中发送多个 ID 来过滤特定资源。

因此我创建了一个请求对象,它可以在我自己的项目中重复使用以保持简单(至少对我而言)。

在构建 GET 调用 QueryString 时,我检查请求对象属性以获取 IEnumerable .如果是这样,我将附加以下值:

var collection = new NameValueCollection(); 
foreach (var pi in request.GetType().GetProperties().Where(p => p.CanRead && p.CanWrite)) 
{ 
    var propVal = pi.GetValue(request, null); 
    if (propVal == null) 
        continue; 
 
    if (pi.PropertyType.IsArray || typeof(IEnumerable).IsAssignableFrom(pi.PropertyType)) 
    { 
        var enumerable = propVal as IEnumerable; 
        if (enumerable != null) 
        { 
            foreach (var singleValue in enumerable) 
            { 
                collection.Add(pi.Name, singleValue.ToString()); 
            } 
        } 
    } 
    else 
    { 
        collection.Add(pi.Name, propVal.ToString()); 
    } 
} 
return collection; 

这将构建我的东西,例如

http://localhost/API/Reporting/EndPoint?Ids=b94a3f1b-15cd-4feb-ac34-bd58bc1c3c2b,77dc84ac-4d48-4cbd-ba12-9de3108a5747

端点接受使用 [FromUri] 从 uri 构建它的请求对象属性。

public TheResponse EndPoint([FromUri] TheRequest request) 

鉴于TheRequest具有 IEnumerable<Guid> Ids {get;set;} 类型的属性.

但是,Ids 属性始终是一个带有空 Guid 的空数组.

如何实现?我在这里需要自定义模型绑定(bind)吗?

根据要求,这是我的请求对象的样子:

public class TheRequest 
{ 
    public IEnumerable<Guid> Ids { get; set; } 
} 

请您参考如下方法:

现在我模拟了一个基于这种情况的集成测试。默认的 [FromUri] 模型绑定(bind)器在绑定(bind) Guid 时存在问题,因为您当前将它们包含在查询字符串中,因为它只是将其读取为一个长字符串

94a3f1b-15cd-4feb-ac34-bd58bc1c3c2b,77dc84ac-4d48-4cbd-ba12-9de3108a5747

它无法解析为有效的 Guid。因此,集合具有一个空的 Guid(default(Guid) 或 Guid.Empty)。

但是如果查询字符串是这样提供的:

/API/Reporting/EndPoint?Ids=b94a3f1b-15cd-4feb-ac34-bd58bc1c3c2b&Ids=77dc84ac-4d48-4cbd-ba12-9de3108a5747

通过将它们分成单独的参数 ?Ids={guid}&Ids={guid} 并对其进行测试,请注意将使用填充的正确参数调用端点。

因此,要么更改 URL 的构造方式,要么,如果无法更改当前格式,则制作自定义模型绑定(bind)器以根据需要解释查询字符串。

自定义模型 Binder 从这里开始Parameter Binding in ASP.NET Web API