Asp.net-Web-Api

為什麼具有可為空參數的 ApiController 方法的 ModelState.IsValid 失敗?

  • August 17, 2012

我有一個接受多個參數的 ApiController 方法,如下所示:

   // POST api/files
   public HttpResponseMessage UploadFile
   (
       FileDto fileDto,
       int? existingFileId,
       bool linkFromExistingFile,
       Guid? previousTrackingId
   )
   {
       if (!ModelState.IsValid)
           return Request.CreateResponse(HttpStatusCode.BadRequest);

       ...
   }

當我對此進行 POST 時,我將FileDto對象放在請求的正文中,並將其他參數放在查詢字元串中。

我已經發現我不能簡單地省略可為空的參數——我需要將它們放在查詢字元串中並帶有一個空值。因此,當我不想為可空參數指定值時,我的查詢如下所示:

http://myserver/api/files?existingFileId=&linkFromExistingFile=true&previousTrackingId=

這確實與我的控制器方法匹配,並且當執行該方法時,可以為空的參數確實是null(如您所料)。

但是ModelState.IsValid,對返回的呼叫false,當我檢查錯誤時,它抱怨兩個可為空的參數。(模型的其他位沒有錯誤)。消息是:

需要一個值,但請求中不存在該值。

為什麼它認為一個值是必需的/不存在的?當然(a)可空值不需要一個值,並且(b)一個值(某種)存在 - 以某種方式為空?

除了第一個答案之外,如果您將所有可選項移到方法聲明的末尾,您應該能夠讓您的程式碼正常工作,允許省略 url 上的前綴,並且我總是將它們設置為 NULL 以獲得良好的衡量標準:

FileDto fileDto,
bool linkFromExistingFile,
Guid? previousTrackingId = null,
int? existingFileId = null

好點re:帶有前綴的空URL值……它與NULL相同……考慮字元串,是?q=空字元串還是空字元串?

我試圖在引發這些錯誤的框架中找到確切的邏輯(並繼續尋找),但在我的實驗過程中,我確實發現直接在 URL 參數上指定綁定似乎繞過了邏輯並允許在前綴後使用空值沒有模型綁定錯誤。

像這樣:

public class ValuesController : ApiController
{
   // GET api/values
   public IEnumerable<string> Get(
       [FromUri(BinderType = typeof(TypeConverterModelBinder))] string q = null,
       [FromUri(BinderType = typeof(TypeConverterModelBinder))] int? value = null)
   {
       if (!ModelState.IsValid)
       {
           throw new HttpResponseException(HttpStatusCode.BadRequest);
       }

       return new string[] { value.HasValue ? value.Value.ToString() : "", q };
   }     
}

引用自:https://stackoverflow.com/questions/12006524