使用自定义模型绑定器时出现NullReferenceException

时间:2011-07-27 18:03:38

标签: c# asp.net-mvc-3 model-binding custom-model-binder

我正在尝试为抽象类创建一个绑定器。绑定器决定要使用的类的实现。

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].speciesList<Pet>,但在Person对象中,它们被命名为pet.name和{{1当它们在一个pet.species中时,它们只是命名为Petname

解决方案

要为species获取带有正确前缀([n]pet或其他任何内容)的参数名称,我使用了以下代码:

GetValue

如果有人有兴趣,我最终会使用与此answer类似的内容继承bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName); string prefix = ((hasPrefix)&&(bindingContext.ModelName!="")) ? bindingContext.ModelName + "." : ""; 。这是我使用的完整代码:

DefaultModelBinder

1 个答案:

答案 0 :(得分:0)

在您收到错误的行中,values可能为null或GetValue("name")返回的内容可能为null。

我假设您在调用List<Pet>方法时,ValueProvider会返回整个List而不是每个Pet,因此无法获取值{{ 1}}因为"name"类中不存在。

如果没有看到更多代码,我就无法确定。