Как получить значения тела из запроса HTTP POST в ASP.NET Web API ValueProvider?

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

Я прочитал здесь, что, если вы хотите связать сложный тип (т.е. тип, который не является string, int и т.д.) в веб-API, хороший подход заключается в создании настраиваемого связующего объекта.

У меня есть настраиваемое связующее устройство (BlogPostModelBinder), которое, в свою очередь, использует пользовательский поставщик стоимости (BlogPostValueProvider). Я не понимаю, как и где я могу получить данные из тела запроса в BlogPostValueProvider?

Внутри связующего объекта это то, что, как я думал, будет правильным способом, например, получить название.

public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
   ...
   var title= bindingContext.ValueProvider.GetValue("Title");
   ...
}

в то время как BlogPostValueProvider выглядит следующим образом:

 public class BlogPostValueProvider : IValueProvider
 {
    public BlogPostValueProvider(HttpActionContext actionContext)
    {
       // I can find request header information in the actionContext, but not the body.
    }

    public ValueProviderResult GetValue(string key)
    {
       // In some way return the value from the body with the given key.
    }
 }

Это может быть разрешено более простым способом, но поскольку я изучаю Web API, было бы неплохо заставить его работать.

Моя проблема в том, что я не могу найти, где хранится тело запроса.

Спасибо за любое руководство!

Ответ 1

Здесь сообщение в блоге об этом от Рика Стралла. Его пост почти отвечает на ваш вопрос. Чтобы адаптировать свой код к вашим потребностям, вы должны сделать следующее.

Внутри конструктора поставщика значений прочитайте тело запроса следующим образом.

Task<string> content = actionContext.Request.Content.ReadAsStringAsync();
string body = content.Result;

Ответ 2

Мне нужно было сделать это в ActionFilterAttribute для ведения журнала, и решение, которое я нашел, это использовать ActionArguments в actionContext, как в

public class ExternalApiTraceAttribute : ActionFilterAttribute
{


    public override void OnActionExecuting(HttpActionContext actionContext)
    {
       ...

        var externalApiAudit = new ExternalApiAudit()
        {

            Method = actionContext.Request.Method.ToString(),
            RequestPath = actionContext.Request.RequestUri.AbsolutePath,
            IpAddresss = ((HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"]).Request.UserHostAddress,
            DateOccurred = DateTime.UtcNow,
            Arguments = Serialize(actionContext.ActionArguments)
        };