有没有办法在ASP.NET MVC 5中将控制器操作中的参数从一种类型转换为另一种类型?
实施例。行动方法如下:
public string Test(Guid input) {
return "";
}
如果使用参数调用方法" input = hello"然后我收到错误消息:"参数字典包含参数'输入'的空条目。非可空类型的System.Guid'方法' System.String测试(System.Guid)'在RealtyGuide.WebSite.Controllers.HomeController'中。可选参数必须是引用类型,可以为空的类型,或者声明为可选参数。"
我想要的是尝试根据特定(自定义)规则将参数强制转换为Guid。这是关于模型绑定的问题吗?有哪些方法可以解决这个问题?抱歉我的英文。
关于答案。如果您只想为Guid参数指定null,如果它无效,请查看this answer。如果您正在寻找自定义模型绑定器的示例,请查看this和this个答案。
答案 0 :(得分:2)
根据@AndreiV和@AntP的评论,决定是:
如果字符串是正确的Guid字符串,那么它会自动绑定(不需要任何其他内容),
如果字符串不是正确的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),但我不会使用它,因为它在我的任务中需要不必要的代码重复。
答案 1 :(得分: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
}
答案 2 :(得分:1)
当在值无效时搜索Guid
绑定操作与优雅后备时,我偶然发现了这个问题。如果不必知道实际提供的值,那么使用nullable Guid
(Guid?
)就可以了。例如。 (这是在ASP.NET Web API中测试的):
[Route("Test")]
[HttpGet]
public string Test(Guid? input = null)
如果提供了有效的Guid
,则会填充输入。否则,它将是null
。
答案 3 :(得分:0)
尝试输入=&#34; helo&#34;是一种错误的方法。 Guid必须包含32位数值示例(12345678910111213141516171819202)
尝试此输入= 12345678910111213141516171819202, 通过给出32位数字的值,Guid值接受它。 然后该方法将不会显示相同的错误。
var input = 12345678910111213141516171819202;
public string Test(Guid input) {
return "";
}