2017-05-10 64 views
3

使用ASP.NET 1.1的核心與VS2015(SDK 1.0.0-preview2-003131),我有以下控制器:必需查詢字符串參數在ASP.NET核心

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

正如你所看到的,我有兩個查詢參數。我想要的是要求其中一個(例如:A)。也就是說,我想用一個屬性(如果可能的話)來說這個屬性是必需的。然後,我想在ASP.NET調用我的控制器之前進行驗證。

我本來希望使用Newtonsoft RequiredAttribute來使用與我已用於驗證PUT/POST內容中所需屬性相同的屬性,但由於url不是JSON字符串,因此顯然不使用它。

有沒有建議讓ASP.NET Core自動檢查所需的查詢參數?

請注意,我知道我可以使用可爲空的查詢參數對自己的代碼進行編碼,但這樣做的目的是讓ASP.NET在調用我的控制器之前進行驗證,從而保持我的控制器整潔。

回答

8

您可以考慮使用模型綁定框架

的功能根據文件位置:Customize model binding behavior with attributes

MVC包含一些屬性,你可以用它來指導其默認 模型綁定行爲不同資源。例如,您可以使用 指定屬性是否需要綁定,或者是否應該使用[BindRequired][BindNever] 屬性根本不會發生。

所以我建議你在模型屬性中添加一個BindRequiredAttribute

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

從那裏的框架應該能夠處理綁定和更新模型狀態,這樣就可以在行動檢查模型的狀態

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

另一種選擇是創建一個自定義模型聯編程序,如果所需的查詢字符串不存在,將導致錯誤操作。

參考:Custom Model Binding

+0

如果您希望該屬性具有不同的名稱,該怎麼辦?在[FromQuery(Name =「$ A」)]之前, –

1

使用屬性路由並列出函數的HttpGet屬性中的每個必需參數。

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

這將需要例如/ 5並允許/ 5?B = 6查詢url參數。

0

讓框架爲您完成工作。這裏有一個解決方案,因爲看起來有許多方法可以在ASP.NET Core中完成同樣的事情。但這對我來說很有用,而且很簡單。它似乎是已經給出的一些答案的組合。

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