我正在构建一个Web服务,它使用的基本模型为
“ BaseRequest”

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”将其转换为我的专用类型。
但是,我似乎无法使转换在一个特定的控制器上工作,我不确定为什么不这样做-因为相同的原理在代码的其他地方也有效。

由于两个原因,“内容”字段是受保护的动态。
动态内容可以是“任何内容”,具体取决于要执行的操作。
受保护的是为了防止继承中的“歧义名称/字段”异常。

所以我的代码:
我要在这里显示的专业类型是

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; }
}


new关键字是使用UIContent的定义从基类“覆盖”或“替换”“ Content”。
在其他示例中,它应该将动态更改为适当的类型。

因此,在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;
        }


但是,在转换后,它总是以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作为我要反序列化为Upload的类型,但是我尝试了反序列化为中间类型和各种类型。

例如:

BaseRequest-> ImageRequest

然后,ImageRequest是两者的基类类型
UploadImageRequest和AcquireImageRequest

反序列化到ImageRequest-为我获取内容信息(我拥有动态信息)
但是当我然后强制转换为Upload或Acquire时,整个类变为null。

有什么想法吗?

最佳答案

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

首先将其反序列化为特殊类型。
这意味着已为请求提供了生命周期所需的所有数据。

然后,Controllers执行方法接受BaseRequest类型作为参数,但是GetShowData请求继承了该类,并允许将其输入,因为它基本上是'BaseRequest'类型,但具有额外的数据。
将请求对象放入Execute方法后,即使它作为BaseRequest输入,它实际上仍然是“ GetShowData”请求。

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

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

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

我记得几年前,我认为这类似于洋葱皮。
您可以取几层洋葱(Specialized类),甚至放回去。
(向后投射-删除图层,然后投射回原始状态-重新打开)

但是您不能放在洋葱不属于的层上。
例如:将对象转换为从未有过的类。

一个例子是

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

如果实例化一个NewRequest对象,则可以将其强制转换为BaseRequest,然后再转换为NewRequest1,但是不能将其强制转换为NewRequest2,因为它从来不是那种类型。

如果实例化BaseRequest,则不能强制转换为任何内容,因为它只能使用BaseRequest的成员/信息创建。
尝试在这种情况下投放BaseRequest,类似于尝试将另一层洋葱的胶带剥离到另一根洋葱上-这根本行不通-它们不合适。

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

08-05 02:27