我有一个基本视图模型,其Id属性类型为object(所以我可以将它设置为int或Guid),如下所示:
public abstract class BaseViewModel
{
public virtual object Id { get; set; }
}
因此,视图模型来源于此
public class UserViewModel : BaseViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
然后我的HTML呈现为:
<input id="Id" name="Id" type="hidden" value="240" />
<input id="FirstName" name="FirstName" type="text" value="John" />
<input id="LastName " name="LastName " type="text" value="Smith" />
当提交给MVC行动时:
[HttpPost]
public ActionResult EditUser(UserViewModel model)
{
...code omitted...
}
模型属性的值为:
Id: string[0] = "240"
FirstName: string = "John"
LastName: string = "Smith"
我的问题是,为什么我会将一项字符串数组作为 Id 的值,而不仅仅是一个字符串?有没有办法改变这种行为?当我尝试将其解析为期望的类型时,它会导致问题。
答案 0 :(得分:2)
我最终使用自定义模型绑定器解决了这个问题,该绑定器将“Id”对象属性作为特殊情况处理:
public class CustomModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
// apply the default model binding first to leverage the build in mapping logic
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
// since "Id" is a special property on BaseViewModel of type object,
// we need to figure out what it should be and parse it appropriately
if (propertyDescriptor.Name == "Id" && propertyDescriptor.PropertyType == typeof(object))
{
// get the value that the default binder applied
var defaultValue = propertyDescriptor.GetValue(bindingContext.Model);
// this should be a one element string array
if (defaultValue is string[])
{
var defaultArray = defaultValue as string[];
// extract the first element of the array (the actual value of "Id")
var propertyString = defaultArray[0];
object value = propertyString;
// try to convert the ID value to an integer (the most common scenario)
int intResult;
if (int.TryParse(propertyString, out intResult))
{
value = intResult;
}
else
{
// try to convert the ID value to an Guid
Guid guidResult;
if (Guid.TryParse(propertyString, out guidResult)) value = guidResult;
}
// set the model value
propertyDescriptor.SetValue(bindingContext.Model, value);
}
}
}
}
答案 1 :(得分:1)
问题在于将您的id属性键入为object
- 不确定默认绑定应该如何在这里工作,但由于对象可能是任何东西 - 比如具有多个属性本身的复杂对象 - 也许它试图将它找到的所有属性转储到数组中?
如果Id
并不总是一个整数,我建议将其输入为字符串,因为模型绑定机制应该没有任何问题映射几乎任何通过HTTP发送的字符串,所以:< / p>
public abstract class BaseViewModel
{
public virtual string Id { get; set; }
}