Avoid the null model when data is not published to the Web API

This question is similar to what I want to achieve:

Avoid null model in ASP.Net Web API if no published properties match model

But he did not answer.

I have a route that accepts a model that is GET:

    [HttpGet, Route("accounts")]
    public AccountListResult Post(AccountListRequest loginRequest)
    {
        return accountService.GetAccounts(loginRequest);
    }

The model is filled with additional data from the action filter.

In this case, all that needs to be known is the UserId, which the action filter adds to the model based on the cookie / header passed with the request.

I want to use all default model bindings in the WebAPI, but I want to avoid null objects.

I do not believe that binding to a model solves my problem.

How to replace the binding behavior of the web API model so that instead of Null I get a new instance when the parameters are not passed

, , , .

+4
2

EDIT: Web API, Web API .

, Action Filter. , .

-API:

public override void OnActionExecuting(HttpActionContext actionContext)
{
     var parameters = actionContext.ActionDescriptor.GetParameters();

     foreach (var parameter in parameters)
     {
         object value = null;

         if (actionContext.ActionArguments.ContainsKey(parameter.ParameterName))
             value = actionContext.ActionArguments[parameter.ParameterName];

         if (value != null)
            continue;

         value = CreateInstance(parameter.ParameterType);
         actionContext.ActionArguments[parameter.ParameterName] = value;
     }

     base.OnActionExecuting(actionContext);
}

protected virtual object CreateInstance(Type type)
{
   // Check for existence of default constructor using reflection if needed
   // and if performance is not a constraint.

   // The below line will fail if the model does not contain a default constructor.
   return Activator.CreateInstance(type);
}

MVC:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var parameters = filterContext.ActionDescriptor.GetParameters();

    foreach (var parameter in parameters)
    {
        if (filterContext.ActionParameters.ContainsKey(parameter.ParameterName))
        {
            object value = filterContext.ActionParameters[parameter.ParameterName];

            if (value == null)
            {
                 // The below line will fail if the model does not contain a default constructor.
                 value = Activator.CreateInstance(parameter.ParameterType);                          
                 filterContext.ActionParameters[parameter.ParameterName] = value;
            }
        }                
    }

    base.OnActionExecuting(filterContext);
}
+4

@Sarathy , . , , ModelState.IsValid - true.

, :

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var parameters = actionContext.ActionDescriptor.GetParameters();

        foreach (var parameter in parameters)
        {
            object value = null;

            if (actionContext.ActionArguments.ContainsKey(parameter.ParameterName))
                value = actionContext.ActionArguments[parameter.ParameterName];

            if (value != null)
                continue;

            value = Activator.CreateInstance(parameter.ParameterType);
            actionContext.ActionArguments[parameter.ParameterName] = value;

            var bodyModelValidator = actionContext.ControllerContext.Configuration.Services.GetBodyModelValidator();
            var metadataProvider = actionContext.ControllerContext.Configuration.Services.GetModelMetadataProvider();

            bodyModelValidator.Validate(value, value.GetType(), metadataProvider, actionContext, string.Empty);
        }

        base.OnActionExecuting(actionContext);
    }
+3

All Articles