Значения маршрутизации атрибутов в параметр модели / FromBody в ASP.NET CORE

Я работаю над приложением веб-API ядра .NET, где мне нужны значения маршрутизации URL в параметре Model / FromBody. Если свойство маршрутизации существует в модели From body.

Есть ли для этого какое-то универсальное решение, т.е. будет работать для всех типов моделей.

Мы уже нашли привязку пользовательской модели, но она работает для конкретного типа модели. Я ищу специальную привязку моделей, которая работает для всех типов моделей.

Например:

Action route: [Route("AH/{userId}")]
Url : ../AH/123
From body: 
{
"userId":"",
"Value" : "Some value"
}

Теперь значение маршрута 123 необходимо сопоставить со свойством модели FromBody "userId".


person Magendran V    schedule 01.07.2019    source источник


Ответы (2)


Вы не можете заполнить параметр маршрута из тела запроса. Параметр маршрута является частью URL-адреса и поэтому должен существовать независимо от того, какое тело фактически отправлено.

Тем не менее, вы никогда не должны доверять чему-то вроде идентификатора, исходящего из тела почтового запроса. Всегда получайте эту информацию из URL-адреса. URL-адрес определяет уникальный ресурс, поэтому публикация по этому URL-адресу может повлиять только на этот уникальный ресурс. Если вы полагаетесь на тело сообщения, злоумышленник может манипулировать опубликованным значением, чтобы потенциально изменить ресурсы, к которым у него не должно быть доступа.

person Chris Pratt    schedule 01.07.2019

Для вашего текущего запроса "userId":"" приведет к сбою запроса, поскольку "" не может быть преобразовано в значение int.

Чтобы решить эту проблему, вы можете изменить тело запроса перед привязкой модели, выполнив следующие действия:

  1. 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);
                }
    
            }            
        }
    }
    
  2. Зарегистрируйтесь ModelResourceFilterAttribute

    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(ModelResourceFilterAttribute));
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
person Edward    schedule 11.07.2019