2016-12-15 259 views
2

我有ASP.NET的WebAPI操作方法,看起來像這樣:默認值參數

[HttpGet] 
public HttpResponseMessage Test([FromUri] TestRequest request) 
{ 
    request.Process(); 
    return new HttpResponseMessage(HttpStatusCode.OK); 
} 

public class TestRequest 
{ 
    public string TestParam1 { get; set; } 
    public string TestParam2 { get; set; } 

    public void Process() 
    { 
     // do work 
    } 
} 

如果指定的URL請求已參數此工程確定,例如http://localhost/test?TestParam1=1。但是,當查詢字符串爲空時,request param爲空,我在我的方法中得到了NullReferenceException

有沒有辦法告訴WebApi總是使用new TestRequest()的實例作爲方法參數,即使查詢字符串爲空?

+0

沒有自動的方式來做到這一點,而無需創建特定於web api的自定義綁定。如果您想在方法簽名中使用'default(TestRequest)',請參閱http://stackoverflow.com/a/4066357/1260204。 – Igor

回答

1
  1. 定義一個定製的模型綁定:

    public class TestRequestModelBinder : System.Web.Http.ModelBinding.IModelBinder 
    { 
        public bool BindModel(HttpActionContext actionContext, 
              System.Web.Http.ModelBinding.ModelBindingContext bindingContext) 
        { 
         if (bindingContext.ModelType != typeof(TestRequest)) return false; 
    
         bindingContext.Model = new TestRequest(); 
    
         var parameters = actionContext.Request.RequestUri.ParseQueryString(); 
    
         typeof(TestRequest) 
          .GetProperties() 
          .Select(property => property.Name) 
          .ToList() 
          .ForEach(propertyName => 
          { 
           var parameterValue = parameters[propertyName]; 
    
           if(parameterValue == null) return;  
    
           typeof(TestRequest).GetProperty(propertyName).SetValue(bindingContext.Model, parameterValue); 
          }); 
    
         return bindingContext.ModelState.IsValid; 
        } 
    } 
    
  2. 使用它:

    [HttpGet] 
    public HttpResponseMessage Test([System.Web.Http.ModelBinding.ModelBinder(typeof(TestRequestModelBinder))] TestRequest request) 
    { 
        // your code 
    } 
    
0

你只需要測試null

[HttpGet] 
public HttpResponseMessage Test([FromUri] TestRequest request) 
{ 
    if (request == null) 
     request = new TestRequest(); 
    var result = request.Process(); 
+0

這肯定會起作用,但我正在尋找一種方法來指導框架調用'new TestRequest()'。我不想在我的所有API方法中都有空檢查。 –

0

使用空是雖然沒有正確的設計聰明的最簡單方法。

否則,您可以使用自定義模型聯編程序爲您的TestRequest類型創建自定義行爲。你可以找到相同的例子。

+0

你能否指出創建這樣一個活頁夾的任何例子,它將爲傳遞到WebAPI方法的任何類型調用'new TParam()',而不僅僅是'TestRequest'? –

0

只能在參數列表中將默認值設置爲常量,因此它不會按照您的要求工作。

如果你有一個方法簽名是這樣,你可以設置例如

public HttpResponseMessage Test(string request = "ok") 

默認值設置爲「確定」,在你的情況下,國際海事組織,最好的辦法是設置的參數值可爲空和檢查針對控制器

[HttpGet] 
public HttpResponseMessage Test([FromUri] TestRequest? request) 
{ 
    if(request.HasValue) 
    { 
     //Do your thing 
    } 
} 
0

Andriy Tolstoy幫助的答案,我不得不雖然小改得到一些我的整數性質的工作。

這裏是更新ModelBinder我用,在情況下,它可以幫助別人:

public class TestRequestModelBinder : IModelBinder 
{ 
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelType != typeof(TestRequest)) return false; 

     bindingContext.Model = new TestRequest(); 
     var parameters = actionContext.Request.RequestUri.ParseQueryString(); 

     typeof(TestRequest) 
      .GetProperties() 
      .ToList() 
      .ForEach(property => 
      { 
       var parameterValue = parameters[property.Name]; 
       if (parameterValue == null) return; 
       typeof(TestRequest).GetProperty(property.Name).SetValue(bindingContext.Model, Convert.ChangeType(parameterValue, property.PropertyType)); 
      }); 
     return bindingContext.ModelState.IsValid; 
    } 
} 

主要變化是將值轉換爲屬性的原始PropertyType