2015-02-26 6 views
5

So che è possibile utilizzare gli attributi di convalida su un modello per la convalida in questo modo:Web API singola stringa di parametri di convalida utilizzando la convalida

public class CommunicationQuery 
{ 
    [RegularExpression("[0-9]{0,10}", ErrorMessage = "Please enter a valid policy number")] 
    public string PolicyId { get; set; } 
    [RegularExpression("[0-9]{0,10}", ErrorMessage = "Please enter a valid member number")] 
    public string MemberId { get; set; } 
} 

public IEnumerable<Communication> Get([FromUri]CommunicationQuery documentQuery) 
{ 

} 

Ma è possibile convalidare una singola stringa utilizzando convalida attributi come Questo?

public async Task<HttpResponseMessage> Get([RegularExpression("[0-9]{0,10}")]string id) 
{ 

} 

Questo non sembra funzionare. L'unico modo in cui sono riuscito a farlo è quello di creare un oggetto wrapper e utilizzare [FromUri], utilizzare un valore personalizzato ActionFilterAttribute sull'azione stessa o convalidare manualmente il parametro nell'azione del controller utilizzando un'espressione regolare.

+2

vincoli del percorso Web API utile anche per la validazione come [Percorso ("XYZ/{id: int: maxlength (10)}")] – 111

risposta

3

Se stai usando attributi Routing per gestire i percorsi in entrata nel tuo controller, si può sempre fare qualcosa di simile:

[Route("{Id:regex([0-9]{0,10})}")] 
public async Task<HttpResponseMessage> Get(string id) 
{ 

} 

ci sono diversi vincoli di percorso, come documentato sul Attribute Routing overview documentation.

Solleva la domanda sul motivo per cui si accetta una stringa numerica di lunghezza 10 come ID. dovrete fare attenzione quando lo si analizza in un int che non superi lo 2,147,483,647, poiché si tratta della dimensione massima per un intero predefinito.

3

Le altre due soluzioni funzioneranno solo per gli attributi di percorso. Tuttavia, se si vogliono validare un parametro di query si potrebbe fare qualcosa di simile:

public class MinWithStatusAttribute : ParameterBindingAttribute 
{ 
    private readonly int _minValue; 
    public MinWithStatusAttribute(int minValue) 
    { 
     _minValue = minValue; 
    } 

    public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter) => new MinWithStatusParameterBinding(parameter, _minValue); 
} 

public class MinWithStatusParameterBinding : HttpParameterBinding, IValueProviderParameterBinding 
{ 
    private readonly int _minValue; 
    public HttpParameterBinding DefaultUriBinding; 

    public MinWithStatusParameterBinding(HttpParameterDescriptor desc, int minValue) 
     : base(desc) 
    { 
     _minValue = minValue; 
     var defaultUrl = new FromUriAttribute(); 
     this.DefaultUriBinding = defaultUrl.GetBinding(desc); 
     this.ValueProviderFactories = defaultUrl.GetValueProviderFactories(desc.Configuration); 
    } 


    public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) 
    { 
     return DefaultUriBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken).ContinueWith((tsk) => 
     { 
      var currentBoundValue = this.GetValue(actionContext); 
      if (!(currentBoundValue is int)) return; //if it is not an Int, return. 
      var currentBoundInt = (int)currentBoundValue; 
      if (currentBoundInt >= _minValue) return; //If the value provided is greater than or equal to the min value, return. Else throw an error 
      var preconditionFailedResponse = actionContext.Request.CreateResponse(HttpStatusCode.PreconditionFailed, $"The parameter {DefaultUriBinding.Descriptor.ParameterName} must be greater than or equal to {_minValue}" }); 
      throw new HttpResponseException(preconditionFailedResponse); 
     }, cancellationToken); 
    } 

    public IEnumerable<ValueProviderFactory> ValueProviderFactories { get; } //IValueProviderParameterBinding 
} 

Questo è per un intero, ma si potrebbe facilmente modificare per lavorare con regex stringa. Ora può essere applicato al parametro di query in quanto tale:

public IHttpActionResult SendEmailToCandidate(int id, [MinWithStatus(3)]int company_id, [MinWithStatus(3)]int recruiter_id, string subject, string body) 
    { 
     //Do stuff in your controller method. If they enter less than 3 it will display an error with Http status code 412 precondition failed. 
    } 
Problemi correlati