NullReference
NullReference

Reputation: 4484

Can a Web API ActionFilterAttribute have access to model?

I'd like to be able to do some permission checks in a web api ActionFilter, so I need to be able to pull out the object ID. I can do this on a GET since I have access to RouteData, but is it possible to get access to the searlized viewModel object in an action filter for a PUT\POST?

 public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext == null)
        {
            throw new ArgumentNullException("actionContext");
        }

       //Get ID from searlized object and check permissions for a POST\PUT? 
    }

Upvotes: 12

Views: 6944

Answers (3)

Tohid
Tohid

Reputation: 6679

Let me follow @André Scartezini's answer and add a sample code I wrote.

It is an ActionFilter to automatically log posted data to a Web API method. It's not the best solution to do the job but just a sample code to show how to access the model from inside an ActionFilter attribute.

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace LazyDIinWebApi.Models
{
    public class LogPostDataAttribute : ActionFilterAttribute
    {
        public override async Task OnActionExecutingAsync(
            HttpActionContext actionContext, 
            CancellationToken cancellationToken)
        {
            Collection<HttpParameterDescriptor> parameters
                = actionContext.ActionDescriptor.GetParameters();
            HttpParameterDescriptor parameter
                = parameters == null ? null : parameters.FirstOrDefault();

            if (parameter != null)
            {
                string parameterName = parameter.ParameterName;
                Type parameterType = parameter.ParameterType;

                object parameterValue = 
                    actionContext.ActionArguments == null && !actionContext.ActionArguments.Any() ? 
                        null : 
                        actionContext.ActionArguments.First().Value;

                string logMessage = 
                    string.Format("Parameter {0} (Type: {1}) with value of '{2}'"
                        , parameterName, parameterType.FullName, parameterValue ?? "/null/");

                // use any logging framework, async is better!
                System.Diagnostics.Trace.Write(logMessage);
            }

            base.OnActionExecuting(actionContext);
        }
    }
}

And this is how to use it:

    // POST: api/myapi
    [LogPostData]
    public void Post(MyEntity myEntity)
    {
         // Your code here
    }

Upvotes: 0

Sixto Saez
Sixto Saez

Reputation: 12680

You have access to the serialized model through this property:

actionContext.Response.Content

It may be some work to determine what to deserialize from that property though. The Web API documentation is pretty sparse right now but here is the official docs. The Response.Content type is HttpReponseMessage so you should find more details for deserialization by searching for that.

Upvotes: 0

Andr&#233; Scartezini
Andr&#233; Scartezini

Reputation: 236

Have you tried the ActionArguments property?

Upvotes: 14

Related Questions