我正在尝试为抽象类创建一个绑定器。绑定器决定要使用的类的实现。
public abstract class Pet
{
public string name { get; set; }
public string species { get; set; }
abstract public string talk { get; }
}
public class Dog : Pet
{
override public string talk { get { return "Bark!"; } }
}
public class Cat : Pet
{
override public string talk { get { return "Miaow."; } }
}
public class Livestock : Pet
{
override public string talk { get { return "Mooo. Mooo. Fear me."; } }
}
所以我有一个带Pet的控制器,粘合剂决定(取决于种类的字符串)它是狗,猫还是牲畜。
public class PetBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var values = (ValueProviderCollection)bindingContext.ValueProvider;
var name = (string)values.GetValue("name").ConvertTo(typeof(string));
var species = (string)values.GetValue("species").ConvertTo(typeof(string));
if (species == "dog")
{
return new Dog { name = name, species = "dog" };
}
else if (species == "cat")
{
return new Cat { name = name, species = "cat" };
}
else
{
return new Livestock { name = name, species = species };
}
}
}
public class HomeController : Controller
{
public JsonResult WorksFine(Pet pet)
{
return Json(pet);
}
public JsonResult DoesntWork(List<Pet> pets)
{
return Json(pets);
}
}
这很好用,但是只要宠物在另一个结构中(如List<Pet>
或另一个对象),我就会得到一个NullReferenceException(在PetBinder中的var name = (string)values.GetValue("name").ConvertTo(typeof(string));
行)。我做错了什么?
我添加了一个Person类来测试。它还给了我一个NullReferenceException。
public class Person
{
public string name { get; set; }
public Pet pet { get; set; }
}
public class HomeController : Controller
{
public JsonResult PersonAction(Person p)
{
return Json(p);
}
}
ccurrens说var name = (string)values.GetValue("name").ConvertTo(typeof(string));
返回null的原因是因为它无法从列表中获取值。
我在[n].name
中看到它们被命名为[n].species
和List<Pet>
,但在Person
对象中,它们被命名为pet.name
和{{1当它们在一个pet.species
中时,它们只是命名为Pet
和name
。
要为species
获取带有正确前缀([n]
或pet
或其他任何内容)的参数名称,我使用了以下代码:
GetValue
如果有人有兴趣,我最终会使用与此answer类似的内容继承bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
string prefix = ((hasPrefix)&&(bindingContext.ModelName!="")) ? bindingContext.ModelName + "." : "";
。这是我使用的完整代码:
DefaultModelBinder
答案 0 :(得分:0)
在您收到错误的行中,values
可能为null或GetValue("name")
返回的内容可能为null。
我假设您在调用List<Pet>
方法时,ValueProvider会返回整个List
而不是每个Pet
,因此无法获取值{{ 1}}因为"name"
类中不存在。
如果没有看到更多代码,我就无法确定。