我正在开发.NET核心Web API应用程序,在该应用程序中,我希望URL路由值进入Model / FromBody参数。如果发件人模型中存在路由属性。
是否有任何通用解决方案,即适用于所有模型类型。
我们已经找到了自定义模型绑定器,但是它适用于特定于模型类型的绑定器。我正在寻找适用于所有模型类型的自定义模型活页夹。
例如:
Action route: [Route("AH/{userId}")]
Url : ../AH/123
From body:
{
"userId":"",
"Value" : "Some value"
}
现在,路由值123需要映射到FromBody模型属性“ userId”
答案 0 :(得分:0)
您无法从请求正文中填充路线参数。路由参数是URL的一部分,因此必须独立于实际发布的正文而存在。
无论如何,您永远都不应信任来自发帖请求正文的ID之类的东西。始终从URL获取该信息。该URL定义了唯一资源,因此发布到该URL只能影响该唯一资源。如果您依赖发布主体,则恶意用户可以操纵发布的值来潜在地更改他们不应该访问的资源。
答案 1 :(得分:0)
对于您当前的请求,"userId":""
将使请求失败,因为无法将""
转换为int值。
要解决此问题,可以通过以下步骤在模型绑定之前修改请求正文:
ModelResourceFilterAttribute
public class ModelResourceFilterAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
context.HttpContext.Request.EnableRewind();
var routeData = context.RouteData;
var stream = context.HttpContext.Request.Body;
using (var streamReader = new StreamReader(context.HttpContext.Request.Body))
{
var json = streamReader.ReadToEnd();
if (json != "")
{
var jsonObj = JObject.Parse(json);
foreach (var item in routeData.Values)
{
JToken token;
if (jsonObj.TryGetValue(
item.Key,
StringComparison.InvariantCultureIgnoreCase,
out token))
{
var jProperty = token.Parent as JProperty;
if (jProperty != null)
{
jProperty.Value = item.Value.ToString();
}
}
}
var body = jsonObj.ToString(Formatting.Indented);
byte[] byteArray = Encoding.UTF8.GetBytes(body);
//byte[] byteArray = Encoding.ASCII.GetBytes(contents);
context.HttpContext.Request.Body = new MemoryStream(byteArray);
}
}
}
}
注册ModelResourceFilterAttribute
services.AddMvc(options =>
{
options.Filters.Add(typeof(ModelResourceFilterAttribute));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);