问题描述
有没有办法从一种类型强制转换参数在控制器的动作到另一个ASP.NET MVC 5?
Is there a way to cast parameter in the controller's action from one type to another in ASP.NET MVC 5?
为例。操作方法如下:
public string Test(Guid input) {
return "";
}
如果该方法与参数调用输入=你好,然后我得到消息的错误:参数词典共包含非可空类型的参数输入无效项的System.Guid'的方法 System.String测试(的System.Guid)'在'RealtyGuide.WebSite.Controllers.HomeController'。一个可选参数必须是引用类型,可空类型,或声明为可选参数。
If the method is invoked with parameters "input=hello" then I get the error with the message: "The parameters dictionary contains a null entry for parameter 'input' of non-nullable type 'System.Guid' for method 'System.String Test(System.Guid)' in 'RealtyGuide.WebSite.Controllers.HomeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."
我要的是尽量根据具体的(自定义)规则参数转换为GUID。它是在模型绑定的问题?什么是解决这一任务的可能途径?对不起,我的英语水平。
What I want is try to cast the parameter to Guid according to specific (custom) rules. Is it a question on model binding? What are the possible ways to solve this task? Sorry for my English.
推荐答案
据@AndreiV意见和@AntP的决定是:1)如果字符串是一个正确的GUID的字符串,然后它会自动绑定(闲来无事需要),2)如果字符串不是一个正确的GUID字符串应该2.1)使在动作的身体转换(在我看来它需要code复制),或2.2)设置自定义(用户定义)模型粘合剂。以下是code的最后一种方法(模型粘合剂)。
According to the comments from @AndreiV and @AntP the decisions are: 1) if the string is a correct Guid-string then it is binded automatically (nothing else is needed), 2) if the string is not a correct Guid-string one should 2.1) make conversion in the action's body (to my mind it entails code duplication), or 2.2) set up the custom (user-defined) model binder. The following is the code for the last approach (model binder).
// 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是必要的:
Registration in Application_Start is necessary:
ModelBinders.Binders.Add(typeof(Guid), new RealtyGuide.WebSite.Extensions.MyModelBinder());
人们可以在全球使用属性,而不是粘结剂的注册(见Method在barkets与参数(?属性?)),但我不会使用它,因为它需要在我的任务不必要的code重复。
One may use attributes instead of registration of the binder globally (see Method parameter with (?attribute?) in barkets ), but I'll not use it, because it entails unnecessary code duplication in my task.
参考文献:
结果
<一href=\"http://stackoverflow.com/questions/6523194/httpserverutility-urltokende$c$c-only-seems-to-return-null\">HttpServerUtility.UrlTokenDe$c$c似乎只返回null
这篇关于ASP.NET MVC:铸造模型类型绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!