我正在构建一个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字段-包含类似于特殊类的结构,则可以进行强制转换或反序列化。