派生抽象类 asp.net mvc 的 JSON 自定义绑定器 null

发布于 2024-11-27 11:41:12 字数 2041 浏览 4 评论 0原文

我为抽象类制作了一个自定义活页夹。绑定器决定使用哪个实现。 它工作得很好,但是当我将抽象类中不存在的属性添加到子类时,它始终为空。

以下是抽象类 Pet 和派生类 DogCat 的代码。

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 string parasite { get;set; } 
}


public class DefaultPetBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType)
    {
        bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
        string prefix = ((hasPrefix)&&(bindingContext.ModelName!="")) ? bindingContext.ModelName + "." : "";

        // get the parameter species
        ValueProviderResult result;
        result = bindingContext.ValueProvider.GetValue(prefix+"species");

        if (result.AttemptedValue.Equals("cat")){
            //var model = base.CreateModel(controllerContext, bindingContext, typeof(Cat));
            return base.CreateModel(controllerContext,bindingContext,typeof(Cat));
        }
        else (result.AttemptedValue.Equals("dog"))
        {
            return base.CreateModel(controllerContext,bindingContext,typeof(Dog));
        }
    }
}

控制器仅接受 Pet 参数并将其作为 JSON 返回。

如果我发送,

{name:"Odie", species:"dog"}

我会返回

{"talk":"Bark!","name":"Odie","species":"dog"}

对于 Cat,有一个寄生属性,该属性在抽象类 Pet 中不存在。如果我发送,

{"parasite":"cockroaches","name":"Oggy","species":"cat"}

我会回来,

{"talk":"Miaow.","parasite":null,"name":"Oggy","species":"cat"}

我已经尝试过其他更复杂的类,这只是一个简单的例子。 我查看了调试器,寄生虫值位于值提供程序中,绑定器返回的模型包含寄生虫的字段。 谁能看出问题出在哪里吗?

I have made a custom binder for an abstract class. The binder decides which implementation to use.
It works well, but when I add a property which does not exist in the abstract class to a child class, it is always null.

Here is the code for the abstract class Pet and derived classes Dog and Cat.

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 string parasite { get;set; } 
}


public class DefaultPetBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType)
    {
        bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
        string prefix = ((hasPrefix)&&(bindingContext.ModelName!="")) ? bindingContext.ModelName + "." : "";

        // get the parameter species
        ValueProviderResult result;
        result = bindingContext.ValueProvider.GetValue(prefix+"species");

        if (result.AttemptedValue.Equals("cat")){
            //var model = base.CreateModel(controllerContext, bindingContext, typeof(Cat));
            return base.CreateModel(controllerContext,bindingContext,typeof(Cat));
        }
        else (result.AttemptedValue.Equals("dog"))
        {
            return base.CreateModel(controllerContext,bindingContext,typeof(Dog));
        }
    }
}

The controller just takes a Pet parameter and returns it as JSON.

If I send

{name:"Odie", species:"dog"}

I get back

{"talk":"Bark!","name":"Odie","species":"dog"}

For the Cat, there is a parasite property which does not exist in the abstract class Pet. If I send

{"parasite":"cockroaches","name":"Oggy","species":"cat"}

I get back

{"talk":"Miaow.","parasite":null,"name":"Oggy","species":"cat"}

I have tried this with other more complex classes, this is just a simple example.
I have looked in the debugger, the parasite value is in the value provider, the model the binder returns contains a field for the parasite.
Can anyone see where the problem is?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葬心 2024-12-04 11:41:12

尝试这样:

protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType)
{
    bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
    string prefix = ((hasPrefix)&&(bindingContext.ModelName!="")) ? bindingContext.ModelName + "." : "";

    // get the parameter species
    ValueProviderResult result;
    result = bindingContext.ValueProvider.GetValue(prefix+"species");

    if (result.AttemptedValue.Equals("cat")) 
    {
        var model = Activator.CreateInstance(typeof(Cat));
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(Cat));
        return model;
    }
    else if (result.AttemptedValue.Equals("dog"))
    {
        var model = Activator.CreateInstance(typeof(Dog));
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(Dog));
        return model;
    }

    throw new Exception(string.Format("Unknown type \"{0}\"", result.AttemptedValue));
}

Try like this:

protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType)
{
    bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
    string prefix = ((hasPrefix)&&(bindingContext.ModelName!="")) ? bindingContext.ModelName + "." : "";

    // get the parameter species
    ValueProviderResult result;
    result = bindingContext.ValueProvider.GetValue(prefix+"species");

    if (result.AttemptedValue.Equals("cat")) 
    {
        var model = Activator.CreateInstance(typeof(Cat));
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(Cat));
        return model;
    }
    else if (result.AttemptedValue.Equals("dog"))
    {
        var model = Activator.CreateInstance(typeof(Dog));
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(Dog));
        return model;
    }

    throw new Exception(string.Format("Unknown type \"{0}\"", result.AttemptedValue));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文