gpt4 book ai didi

c# - WebApi - 从 Uri 和 Body 绑定(bind)

转载 作者:IT王子 更新时间:2023-10-29 04:00:14 26 4
gpt4 key购买 nike

是否可以同时从 Uri 和 Body 绑定(bind)一个模型?

例如,给定以下内容:

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

public class ProductsController : ApiController
{
public HttpResponseMessage Put(UpdateProduct model)
{

}
}

public class UpdateProduct
{
int Id { get; set;}
string Name { get; set; }
}

是否可以创建自定义 Binder 以便PUT

/api/products/1

使用 JSON 正文:

{
"Name": "Product Name"
}

将导致 UpdateProduct 模型填充有 Id = 1Name = "Product Name"

更新

我知道我可以将 Action 签名更改为

public HttpResponseMessage Put(int id, UpdateProduct model)
{

}

但是正如问题中所述,我特别想绑定(bind)到单个模型对象

我也把这个问题发到了WebApi Codeplex discussion forum

最佳答案

这是 odyth 答案的改进版本:

  1. 也适用于无形体请求,并且
  2. 除了从路由值中获取参数外,还从查询字符串中获取参数。

为简洁起见,我只发布了 ExecuteBindingAsyncCore 方法和一个新的辅助方法,该类的其余部分是相同的。

private async Task ExecuteBindingAsyncCore(ModelMetadataProvider metadataProvider, HttpActionContext actionContext,
HttpParameterDescriptor paramFromBody, Type type, HttpRequestMessage request, IFormatterLogger formatterLogger,
CancellationToken cancellationToken)
{
var model = await ReadContentAsync(request, type, Formatters, formatterLogger, cancellationToken);

if(model == null) model = Activator.CreateInstance(type);

var routeDataValues = actionContext.ControllerContext.RouteData.Values;
var routeParams = routeDataValues.Except(routeDataValues.Where(v => v.Key == "controller"));
var queryStringParams = new Dictionary<string, object>(QueryStringValues(request));
var allUriParams = routeParams.Union(queryStringParams).ToDictionary(pair => pair.Key, pair => pair.Value);

foreach(var key in allUriParams.Keys) {
var prop = type.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);
if(prop == null) {
continue;
}
var descriptor = TypeDescriptor.GetConverter(prop.PropertyType);
if(descriptor.CanConvertFrom(typeof(string))) {
prop.SetValue(model, descriptor.ConvertFromString(allUriParams[key] as string));
}
}

// Set the merged model in the context
SetValue(actionContext, model);

if(BodyModelValidator != null) {
BodyModelValidator.Validate(model, type, metadataProvider, actionContext, paramFromBody.ParameterName);
}
}

private static IDictionary<string, object> QueryStringValues(HttpRequestMessage request)
{
var queryString = string.Join(string.Empty, request.RequestUri.ToString().Split('?').Skip(1));
var queryStringValues = System.Web.HttpUtility.ParseQueryString(queryString);
return queryStringValues.Cast<string>().ToDictionary(x => x, x => (object)queryStringValues[x]);
}

关于c# - WebApi - 从 Uri 和 Body 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17645877/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com