Required query string parameter in ASP.NET Core

北城以北 提交于 2019-12-01 15:49:00

问题


Using ASP.NET Core 1.1 with VS2015 (sdk 1.0.0-preview2-003131), I have the following 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() };
    }        
}

As you can see, I have two query parameters. What I would like is to have one of them (ex: A) to be required. That is, I would like to use an attribute (if possible) to say that this attribute is required. Then, I would like like ASP.NET to do this validation before even calling my controller.

I would have liked to use the Newtonsoft RequiredAttribute to use the same attributes as I already use to validate the required properties in the PUT/POST content, but since the url is not a JSON string, it is obviously not used.

Any suggestion to have ASP.NET Core automatically check for required query parameters?

Note that I know that I can code the check myself using nullable query parameters but that beats the purpose of letting ASP.NET do the validation before calling my controller, thus keeping my controller tidy.


回答1:


You can consider using the model binding feature of the framework

According to documentation here: Customize model binding behavior with attributes

MVC contains several attributes that you can use to direct its default model binding behavior to a different source. For example, you can specify whether binding is required for a property, or if it should never happen at all by using the [BindRequired] or [BindNever] attributes.

So I suggest you add a BindRequiredAttribute to the model property.

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

From there the framework should be able to handle the binding and updating model state so that you can check the state of the model in the action

[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();
    }        
}

The other option would be to create a custom model binder that would fault the action if the required query string is not present.

Reference: Custom Model Binding




回答2:


Let the framework do the work for you. Here is one solution, as it appears there are a number of ways to accomplish the same thing in ASP.NET Core. But this is what works for me and is quite simple. It seems to be a combination of some of the answers already given.

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() };
    }        
}



回答3:


Use attribute routing and list each required parameter in the function's HttpGet attribute.

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

This will require e.g /5 and allow /5?B=6 query url parameters.




回答4:


Use model validation. You can define a ViewModel and use DataAnnotations to mark property A as [Required]. Then in your action just check if ModelState.IsValid. You can also easily do this using an action filter as shown in this article: https://msdn.microsoft.com/en-us/magazine/mt767699.aspx



来源:https://stackoverflow.com/questions/43895485/required-query-string-parameter-in-asp-net-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!