2014-10-31 75 views
0

有沒有在ASP.NET MVC 5中將控制器操作中的參數從一種類型轉換爲另一種類型的方法?ASP.NET MVC:在模型綁定中投射的類型

例子。操作方法如下:

public string Test(Guid input) { 
    return ""; 
} 

如果該方法與參數調用「輸入=你好」,然後我得到消息的錯誤:「參數字典包含的非參數‘輸入’無效項可空的類型'System.Guid'用於'RealtyGuide.WebSite.Controllers.HomeController'中的方法'System.String Test(System.Guid)'。可選參數必須是引用類型,可爲空類型或聲明爲可選參數。」

我想要的是嘗試根據特定(自定義)規則將參數轉換爲Guid。這是模型綁定的問題嗎?有什麼可能的方法來解決這個任務?對不起我的英語不好。

關於答案。如果您只是想將一個Guid參數指定爲null,如果它是無效的,則查看this answer。如果您正在尋找自定義模型聯編程序的示例,請參閱thisthis答案。

+3

您能否詳細說明您打算如何將Gucci「打招呼」? – 2014-10-31 11:42:32

+3

您有兩種選擇:接受一個字符串作爲輸入,然後根據您的規則進行轉換,或者創建一個自定義模型聯編程序。 – 2014-10-31 11:43:10

+0

@AntP它只是一個例子。一般問題是將Base64字符串轉換爲Guid並向後轉換。 (在我的情況下,可以通過Guid的擴展方法投射Guid-> Base64-string)。 – Hoborg 2014-10-31 12:36:36

回答

2

據@AndreiV意見和@AntP的決定是:

  1. 如果字符串是一個正確的GUID的字符串,然後它會自動綁定(沒有別的需要),

  2. 如果字符串是不是一個正確的GUID串一個應該

2.1。在動作的正文中進行轉換(在我看來,它需要代碼複製),或者

2.2。設置自定義(用戶定義的)模型聯編程序。以下是最後一種方法(模型聯編程序)的代碼。

// This is an example. 
// Note the returning of null which is undesired. 
// Also it does not deal with exceptions handling. Use it only as a stub. 
    public class ExtendedModelBinder : DefaultModelBinder { 
      public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
       if (!(bindingContext.ModelType == typeof(Guid))) 
        return base.BindModel(controllerContext, bindingContext); 
       if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) 
        return null; 
       string input = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue; 
       if (string.IsNullOrEmpty(input)) 
        return null; 
       Guid g; 
       if (Guid.TryParse(input, out g)) 
        return g; 
       var bytes = HttpServerUtility.UrlTokenDecode(s); 
       var result = new Guid(bytes); 
       return result; 
      } 
     } 

登記在的Application_Start是必要的:

ModelBinders.Binders.Add(typeof(Guid), new RealtyGuide.WebSite.Extensions.MyModelBinder()); 

人們可以使用全局屬性,而不是粘合劑的登記(見here),但我不使用它,因爲它需要不必要的重複代碼在我的任務。

參考文獻:如果期望123

0

Trying input =「helo」是一種錯誤的方法。 的Guid必須包含32位數字值的例子(12345678910111213141516171819202)

嘗試此輸入= 12345678910111213141516171819202, 通過給予像GUID值接受它32位的數字值。 那麼該方法將不會顯示相同的錯誤。

var input = 12345678910111213141516171819202; 

public string Test(Guid input) { 
return ""; 
} 
+0

謝謝你的回答。但我的問題是爲所有相應的操作設置自動轉換。可以肯定的是,這個覆蓋率應該處理不正確的數據並處理它。 – Hoborg 2014-10-31 13:55:06

2
答覆Hoborg的示例

https://stackoverflow.com/posts/26676337/revisions 下面將返回空值或GUID參數。

public class NullableGuidBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelType == typeof(Guid?)) 
     { 
      var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 

      string input = valueResult.AttemptedValue; 
      if (string.IsNullOrEmpty(input) || input == "0") 
      { 
       // return null, even if input = 0 
       // however, that is dropdowns' "guid.empty") 
       // base.BindModel(...) would fail converting string to guid, 
       // Guid.Parse and Guid.TryParse would fail since they expect 000-... format 

       // add the property to modelstate dictionary 
       var modelState = new ModelState { Value = valueResult }; 
       bindingContext.ModelState.Add(bindingContext.ModelName, modelState); 
       return null; 
      } 
     } 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

綁定在你的控制器

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> SelectAction(
     [ModelBinder(typeof(NullableGuidBinder))] Guid? id) 
    { 
     // your stuff 
    } 
1

我已經就這個問題尋找關於Guid時,當值無效,優美后備行動結合跌跌撞撞如下。如果不需要知道實際提供的數值,那麼使用nullable GuidGuid?)就可以了。例如。 (這是在的ASP.NET Web API測試):

[Route("Test")] 
[HttpGet] 
public string Test(Guid? input = null) 

如果提供一個有效的Guid,輸入將被填充。否則,它將是null

+0

感謝您的回答。今天我幾乎不能記住我的問題背後的意圖。我的意思是,如果問題的關鍵只是將Guid參數賦值爲null(如果它無效),那麼您的答案絕對適合。但在我看來,我正在尋找一個自定義模型綁定器的例子,因此我寧願將我的答案留作公認的答案。 – Hoborg 2016-12-04 19:05:36