1

I have a Web API model of the lines

class SampleModel
{
    [ComponentExistsValidation]
    public Guid? ComponentID { get; set; }
    ...
}

I need to validate that the ComponentID exists under a given model, and the modelid is available to my controller as a route parameter.

[Route("api/model/addcomponents/{modelid:int}")]
public async Task AddComponents(int modelid, [FromBody]SampleModel[] components)

Here is my validator

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    if (value == null)
        return ValidationResult.Success;
    Guid componentid = (Guid)value;
    int modelid; // How do I get this here?
    Model context_mdl = Model.GetModel(modelid);
    if(!context_mdl.HasComponent(componentid))
    {
        return new ValidationResult(string.Format("Invalid component"));
    }
}

Can I access the modelid route parameter in the validator?

1 Answer 1

3

You should be able to get it from HttpContext.

Add a reference to System.Web.DLL if HTTPContext is unavailable.

Here's an example using IValidatableObject. But I'm sure you can translate it to your attribute if you want.

class SampleModel : IValidatableObject
{
    public Guid? ComponentID { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (value == null)
            return ValidationResult.Success;
        Guid componentid = (Guid)value;
        int modelid = System.Web.HttpContext.Current.Request.RequestContext.RouteData.GetWebApiRouteData("modelid");
        Model context_mdl = Model.GetModel(modelid);
        if(!context_mdl.HasComponent(componentid))
        {
            yield return new ValidationResult(string.Format("Invalid component"));
        }
    }
}

And use an extension heavily influensed from this answer.

public static class WebApiExtensions
{
    public static object GetWebApiRouteData(this RouteData routeData, string key)
    {
        if (!routeData.Values.ContainsKey("MS_SubRoutes"))
            return null;

        object result = ((IHttpRouteData[]) routeData.Values["MS_SubRoutes"]).SelectMany(x => x.Values)
            .Where(x => x.Key == key).Select(x => x.Value).FirstOrDefault();
        return result;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.