context.GetInput <model>返回基类,而不是$ Type中指定的派生类

我使用Azure耐用函数,尝试使用context.GetInput<model>()函数,该函数返回指定的模型。使用的模型具有一个参数,该参数是作为派生类的另一个模型。从context.GetInput<model>()输出的模型返回具有基类而不是派生类的模型。

我检查了在上下文中指定的$ type,它显示了派生类,但是在检查输出模型时,结果是基类。

例如:

public class Student{
   public Book book {get;set;}
}
public class Textbook:Book {
   public string classfor {get;set;}
}
public class Book {
   public string title {get;set;}
}

[activityTrigger] DurableactivityContextBase context是该函数的参数。

那我会打电话给

var model = context.GetInput<Student>()

上下文包括

{
  "$type": "Student","book" : {
       "$type": "Textbook","classfor" : "Math","title" : "PreAlgebra"
    }
}

结果是 包含书籍而不是教科书的学生模型,其中标题被分配为“ PreAlgebra”

我希望学生模型的输出中包含具有以下属性的教科书:

title = "PreAlgebra"
classfor = "Math"

但实际的学生输出包含具有属性的书

title = "PreAlgebra"
tianjing_anbey 回答:context.GetInput <model>返回基类,而不是$ Type中指定的派生类

我遇到了与上周相同的问题。不幸的是,目前Azure函数(甚至是2.x)不支持持久功能的多态性。持久上下文将您的对象序列化为JSON,但是无法传递GitHub中所述的JSON序列化设置。也有another issue关于这个特定问题。

就我而言,我有一个抽象基类,但是您可以对派生类型使用相同的方法。您可以创建一个自定义JSON转换器,该转换器将处理反序列化期间选择正确的类型。因此,例如,如果您具有这种继承:

[JsonConverter(typeof(DerivedTypeConverter))]
public abstract class Base
{ 
    [JsonProperty("$type")]
    public abstract string Type { get; }
}

public class Child : Base
{
    public override string Type => nameof(Child);
}

public class Child2 : Base
{
    public override string Type => nameof(Child2);
}

然后,您可以拥有一个JSON转换器:

public class BaseDerivedTypeConverter : DefaultContractResolver
{
    // You need this to protect yourself against circular dependencies
    protected override JsonConverter ResolveContractConverter(Type objectType)
    {
        return typeof(Base).IsAssignableFrom(objectType) && !objectType.IsAbstract
            ? null
            : base.ResolveContractConverter(objectType);
    }
}

public class DerivedTypeConverter : JsonConverter
{
    private static readonly JsonSerializerSettings Settings =
        new JsonSerializerSettings()
        {
            ContractResolver = new BaseDerivedTypeConverter()
        };

    public override bool CanConvert(Type objectType) => (objectType == typeof(Base));

    public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
    {
        JObject jsonObject = JObject.Load(reader);

        // Make checks if jsonObject["$type"].Value<string>() has a supported type
        // You can have a static dictionary or a const array of supported types

        // You can leverage the array or dictionary to get the type you want again
        var type = Type.GetType("Full namespace to the type you want",false); // the false flag means that the method call won't throw an exception on error

        if (type != null)
        {
            return JsonConvert.DeserializeObject(jsonObject.ToString(),type,Settings);
        }
        else
        {
            throw new ValidationException("No valid $type has been specified!");
        }
    }

    public override bool CanWrite => false;

    public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer) => throw new NotImplementedException();
}

在我使用context.GetInput<Base>()时,我可以得到ChildChild1,因为Base是抽象的。

根据您的实际情况,它可以是BookStudent。这也适用于其他持久功能操作,例如

var foobar = await context.CallActivityAsync<Base>("FuncName",context.GetInput<int>());

转换器将处理此问题,您将在foobar中获得所需的对象。

,

根据我的理解,“教科书”类是“书”的扩展,因此“书”是父类,“教科书”是子类。在您的上下文中,您想将子类(教科书)转换为父类(书本)。 此后,“ book”将仅具有属性“ title”(这是它们的常用属性),而没有特定的属性“ classfor” 。您可以参考以下代码:

enter image description here

,

跟踪更新,以将Json序列化传递给Azure Functions here,显示该更新将在v2.1中发布!

本文链接:https://www.f2er.com/3143463.html

大家都在问