wake-up-neo.com

Erforderlicher Abfragezeichenfolgenparameter in ASP.NET Core

Unter Verwendung von ASP.NET Core 1.1 mit VS2015 (SDK 1.0.0-Preview2-003131) habe ich den folgenden Controller:

public class QueryParameters
{
    public int A { get; set; }
    public int B { get; set; }
}

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get([FromQuery]QueryParameters parameters)
    {
        return new [] { parameters.A.ToString(), parameters.B.ToString() };
    }        
}

Wie Sie sehen, habe ich zwei Abfrageparameter. Ich möchte, dass einer von ihnen (zB: A) benötigt wird. Das heißt, ich möchte ein Attribut (wenn möglich) verwenden, um zu sagen, dass dieses Attribut erforderlich ist. Dann möchte ich, dass ASP.NET diese Überprüfung durchführt, bevor ich meinen Controller aufrufe.

Ich hätte gerne Newtonsoft RequiredAttribute verwendet, um dieselben Attribute zu verwenden, die ich bereits zum Überprüfen der erforderlichen Eigenschaften im PUT/POST-Inhalt verwendet habe. Da die URL jedoch keine JSON-Zeichenfolge ist, ist dies offensichtlich nicht benutzt.

Gibt es einen Vorschlag, ASP.NET Core automatisch nach den erforderlichen Abfrageparametern suchen zu lassen?

Beachten Sie, dass ich weiß, dass ich den Scheck selbst mit nullwertfähigen Abfrageparametern codieren kann. Dies hat jedoch den Zweck, dass ASP.NET die Validierung vor dem Aufrufen des Controllers durchführt, wodurch der Controller aufgeräumt wird.

8
mabead

Sie können die Modellbindungsfunktion des Frameworks verwenden

Laut Dokumentation hier: Modellbindungsverhalten mit Attributen anpassen

MVC enthält mehrere Attribute, mit denen Sie das Standardverhalten der Modellbindung auf eine andere Quelle lenken können. Beispielsweise können Sie mithilfe der Attribute [BindRequired] Oder [BindNever] Angeben, ob für eine Eigenschaft eine Bindung erforderlich ist oder ob diese überhaupt nicht erfolgen soll.

Daher schlage ich vor, dass Sie der model-Eigenschaft ein BindRequiredAttribute hinzufügen.

public class QueryParameters
{
    [BindRequired]
    public int A { get; set; }
    public int B { get; set; }
}

Von dort sollte das Framework in der Lage sein, den Bindungs- und Aktualisierungsstatus des Modells zu verarbeiten, damit Sie den Status des Modells in der Aktion überprüfen können

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IActionResult Get([FromQuery]QueryParameters parameters)
    {    
        if (ModelState.IsValid)
        {
            return Ok(new [] { parameters.A.ToString(), parameters.B.ToString() });
        }
        return BadRequest();
    }        
}

Die andere Option besteht darin, einen benutzerdefinierten Modellordner zu erstellen, der die Aktion fehlerhaft ausführt, wenn die erforderliche Abfragezeichenfolge nicht vorhanden ist.

Referenz: Custom Model Binding

19
Nkosi

Lassen Sie das Framework die Arbeit für Sie erledigen. Hier ist eine Lösung, wie es scheint, gibt es eine Reihe von Möglichkeiten, um dasselbe in ASP.NET Core zu erreichen. Aber das funktioniert bei mir und ist ganz einfach. Es scheint eine Kombination einiger der bereits gegebenen Antworten zu sein.

public class QueryParameters
{
    [Required]
    public int A { get; set; }

    public int B { get; set; }
}

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    // [HttpGet] isn't needed as it is the default method, but ok to leave in
    // QueryParameters is injected here, the framework takes what is in your query string and does its best to match any parameters the action is looking for. In the case of QueryParameters, you have A and B properties, so those get matched up with the a and b query string parameters
    public IEnumerable<string> Get(QueryParameters parameters)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(); // or whatever you want to do
        }

        return new [] { parameters.a.ToString(), parameters.b.ToString() };
    }        
}
2
Jeff Magill