我在 Web API 端点上有以下类和操作。我希望查询字符串
sid
绑定到属性 SportId
,就像 JSON.NET 序列化一样。 SportId
可以很好地用作带有 FromUri
的查询字符串。是否有某种类型的活页夹我可以使用 .NET 4.8 来完成此操作。
public class AppApplicationRequest : AppRequest
{
[JsonProperty(PropertyName = "sid")]
public SportType? SportId { get; set; }
}
public virtual async Task<AppApplicationResponse> Get([FromUri] AppApplicationRequest request)
{
return await _appApplicationsService.GetApplication(request);
}
这是有关如何完成自定义模型绑定程序的一般指南。
以下是如何为 AppApplicationRequest 类创建自定义模型绑定程序的简单示例:
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
using Newtonsoft.Json;
public class AppApplicationRequestBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(AppApplicationRequest))
{
return false;
}
var queryString = actionContext.Request.RequestUri.ParseQueryString();
var appApplicationRequest = new AppApplicationRequest();
if (queryString["sid"] != null)
{
if (Enum.TryParse(typeof(SportType), queryString["sid"], out object parsedSportType))
{
appApplicationRequest.SportId = (SportType)parsedSportType;
}
}
// Add more fields if needed
bindingContext.Model = appApplicationRequest;
return true;
}
}
接下来,注册您的自定义活页夹!这将类似于
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// ... Other configurations
config.BindParameter(typeof(AppApplicationRequest), new AppApplicationRequestBinder());
}
}
现在您可以注释您想要完成的操作,如下所示:
public virtual async Task<AppApplicationResponse> Get([ModelBinder(typeof(AppApplicationRequestBinder))] AppApplicationRequest request)
{
return await _appApplicationsService.GetApplication(request);
}
再次强调,这是笼统的,因为您没有在问题中提供太多具体信息,但我希望这有助于您找到正确的方向。如果您在评论中还有后续问题,请告诉我,我会尽力回答,祝您好运
我认为将
[ModelBinder]
属性与自定义模型绑定器结合使用会更好,因此首先尝试创建一个实现 IModelBinder
接口的自定义模型绑定器,并在 BindModel
方法中,您可以访问查询字符串参数并将它们绑定到 AppApplicationRequest
类的适当属性。
public class AppApplicationRequestModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var request = (AppApplicationRequest)bindingContext.Model;
//get the value of the 'sid' query string parameter
var sidValue = bindingContext.ValueProvider.GetValue("sid").FirstValue;
//converting the 'sid' value to the appropriate enum type
if (Enum.TryParse(sidValue, out SportType sportId))
{
request.SportId = sportId;
}
bindingContext.Result = ModelBindingResult.Success(request);
return Task.CompletedTask;
}
}
现在尝试将
[ModelBinder]
属性应用于 AppApplicationRequest
操作方法中的 Get
参数,指定自定义模型绑定器
public virtual async Task<AppApplicationResponse> Get([ModelBinder(typeof(AppApplicationRequestModelBinder))] AppApplicationRequest request)
{
return await _appApplicationsService.GetApplication(request);
}
或者您可以使用另一个自定义模型绑定器,该绑定器是使用 ASP.NET Web API 2 的
IModelBinder
命名空间中的 System.Web.Http.ModelBinding
接口实现的!
using System;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
public class AppApplicationRequestModelBinder : IModelBinder
{
public Task BindModelAsync(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var request = (AppApplicationRequest)bindingContext.Model;
//get the value of the 'sid' query string parameter
var sidValue = bindingContext.ValueProvider.GetValue("sid").RawValue.ToString();
//converting the 'sid' value to the appropriate enum type
if (Enum.TryParse(sidValue, out SportType sportId))
{
request.SportId = sportId;
}
bindingContext.Result = ModelBindingResult.Success(request);
return Task.CompletedTask;
}
}
public class AppApplicationRequest : AppRequest
{
public SportType? SportId { get; set; }
}
public virtual async Task<AppApplicationResponse> Get([ModelBinder(typeof(AppApplicationRequestModelBinder))] AppApplicationRequest request)
{
return await _appApplicationsService.GetApplication(request);
}
更新
好的,要将查询字符串参数动态绑定到模型,您可以创建适用于任何模型的通用模型绑定器。
看看这个:
public class QueryStringModelBinder<T> : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var model = Activator.CreateInstance<T>();
foreach (var property in typeof(T).GetProperties())
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(property.Name);
if (valueProviderResult != null)
{
var value = valueProviderResult.FirstValue;
var convertedValue = Convert.ChangeType(value, property.PropertyType);
property.SetValue(model, convertedValue);
}
}
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
有了这个,您可以通过将
[ModelBinder]
属性应用于操作方法中的模型参数,将查询字符串参数绑定到任何模型,因此您不需要为每个模型创建单独的模型绑定器!!!
public virtual async Task<AppApplicationResponse> Get([ModelBinder(typeof(QueryStringModelBinder<AppApplicationRequest>))] AppApplicationRequest request)
{
return await _appApplicationsService.GetApplication(request);
}