【问题标题】:Inheritance and JSON Casting继承和 JSON 转换
【发布时间】:2016-10-16 10:48:31
【问题描述】:

我正在构建一个 Web 服务,它使用 '基本请求'

public class BaseRequest
    {
        public string Operation { get; set; }
        public string SessionToken { get; set; }
        protected dynamic Content { get; set; }
        public bool IsEncrypted { get; set; }

        public override string ToString()
        {
            return RestClient.GetSerializerNative().Serialize(this);
        }

    }

然后,当它进入我正在构建的每个功能的控制器时,我通过“as NewClassType”将其转换为我的专用类型。 但是,我似乎无法让强制转换在一个特定的控制器上工作,我不确定为什么不 - 因为相同的原理在代码的其他地方也适用。

“内容”字段是受保护的动态有两个原因。 根据正在执行的操作,动态内容可以是“任何东西”。 protected 是为了防止继承中的“不明确的名称/字段”异常。

所以我的代码: 我要在这里展示的特殊类型是

public class UploadImageRequest : BaseRequest
    {
        public new UIContent Content { get; set; }
    }
public class UIContent
{
    public string ImageName { get; set; }
    public string ImageHash { get; set; }
    public byte[] BinaryData { get; set; }
}

新关键字是用 UIContent 的定义“覆盖”或“替换”基类中的“内容”。 根据我的其他示例,它应该将动态更改为适当的类型。

那么在Execute方法中的实际实现:

case "uploadimage":
                    BaseRequest uploadImage
                        = Default.GetJSSerializerNative().Deserialize<BaseRequest>(originalContent);

                    _responseToDeliver =
                        operations.uploadimage.Controller.Execute(uploadImage).ToString();

                    break;

然后进入:

public static Response Execute(BaseRequest request)
    {

        Response r = new Response();

        UploadImageRequest uir = request as UploadImageRequest;

        string name, hash = "";
        byte[] data = null;

        if (uir != null)
        {
            name = uir.Content.ImageName;
            hash = uir.Content.ImageHash;
            data = uir.Content.BinaryData;
        }

然而,uir 在强制转换后总是以 null 结束。

在另一个例子中,我有:

case "getshowdata":
                    ShowDataRequest showRequest
                        = Default.GetJSSerializerNative().Deserialize<ShowDataRequest>(originalContent);

                    _responseToDeliver =
                        operations.TvShowInfo.Controller.Execute(showRequest).ToString();

                    break;

ShowDataRequest 如下所示:

public class ShowDataRequest : BaseRequest
    {
        public new ShowDataContentModel Content { get; set; }

    }

    public class ShowDataContentModel
    {
        public string ShowName { get; set; }
    }

在它的控制器中——它完美地工作。 那么我的 UploadImage 操作在这里发生了什么? 为什么不能从 BaseRequest 转换为专用类型,而 ShowDataRequest 可以。

注意:我尝试了各种方法。 case 语句将 BaseRequest 作为我目前为上传反序列化的类型,但我已尝试反序列化为中间类型和各种类型。

例如:

BaseRequest -> ImageRequest

ImageRequest 是两者的基类类型 UploadImageRequest 和 AcquireImageRequest

反序列化为 ImageRequest - 获取内容信息(我将其作为动态) 但是当我然后转换为 Upload 或 Acquire 时 - 整个类都变为空。

想法?

【问题讨论】:

    标签: c# json inheritance casting deserialization


    【解决方案1】:

    我想我知道我的代码出了什么问题。 在我的示例中它起作用:例如 - GetShowData 请求。

    开始时它被反序列化为专用类型。 这意味着它获得了请求生命周期内所需的所有数据。

    然后控制器的执行方法接受一个 BaseRequest 类型作为参数,但 GetShowData 请求继承了这个类,允许它被输入,因为它基本上是一种“BaseRequest”类型,但有额外的数据。 一旦进入 Execute 方法,请求对象仍然是真正的“GetShowData”请求,即使它作为 BaseRequest 进入。

    强制转换 - 实际上并不修改内存中的对象,而只是改变编译器或运行时解释对象的方式,然后可以允许运行时将请求解释为 GetShowData 请求。 之所以可以这样做,是因为请求一开始总是一个 GetShowData 请求,它只是被视为启动 Execute 方法的 BaseRequest。

    我认为我在 UploadImage 请求中出错的地方是我的继承倒退了。 我试图反序列化为 BaseRequest,将其作为 BaseRequest 输入,然后将其“转发”到专用类型。 这不起作用,因为该类最初是作为 BaseRequest 创建的,在这个阶段它不了解专业领域。

    然而,我可以做的是反序列化为专用类型,在 Execute 方法中将其作为该类型输入 - 然后它可以接受 BaseRequest,然后它可以转换回专用类型。

    我记得几年前我认为这类似于洋葱皮。 你可以把洋葱层(专业课),甚至把它们放回去。 (向后投射 - 移除层,投射回原始状态 - 将它们重新打开)

    但你不能穿上从不属于洋葱的层。 例如:将对象转换为从未存在过的类。

    一个例子是

    基本请求 由 NewRequest1 继承 由 NewRequest2 继承

    如果您实例化 NewRequest 的对象 - 您可以转换为 BaseRequest,然后再转换回 NewRequest1,但不能将其转换为 NewRequest2 - 因为它从来不是那种类型。

    如果您实例化 BaseRequest,则不能转换为任何内容,因为它只是使用 BaseRequest 的成员/信息创建的。 在这种情况下尝试投射 BaseRequest 类似于尝试将另一个洋葱的皮肤层粘贴到另一个洋葱上——这不起作用——它们不适合。

    如果有人确实找到了一种方法来使用动态字段“内容”作为违反继承要求的方法来执行转换 - 我很想听听。 例如:如果动态 Content 字段 - 包含类似于专用类的结构,则允许强制转换或反序列化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多