- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有没有一种方法可以在派生类中实现更改跟踪而不覆盖基类的 getter 和 setter?
我正在开发一个基于 Entity Framework 的多层项目,数据访问和业务逻辑最终转移到基于 C# 的服务器应用程序。 (数据访问已迁移)客户端使用Delphi 2010。
我已经使用数据传输对象在客户端和服务器之间传递信息,但是有必要从 Delphi 实现我自己的更改跟踪。我最初是通过继承 wsdl 中的 Dto 并“覆盖”getter 和 setter 来实现这一点的。wsdl 导入中的基类(对此没有真正的控制):
// ************************************************************************ //
// XML : DtoCONTAINER_JNL, global, <complexType>
// Namespace : http://k3scs.com/WCF
// ************************************************************************ //
DtoCONTAINER_JNL = class(DtoBase)
private
FJNL_ID: Integer;
FJNL_TYPE_ID: Integer;
FJNL_DATE: TXSDateTime;
published
property JNL_ID: Integer read FJNL_ID write FJNL_ID;
property JNL_TYPE_ID: Integer read FJNL_TYPE_ID write FJNL_TYPE_ID;
property JNL_DATE: TXSDateTime read FJNL_DATE write FJNL_DATE;
派生类:
TDtoCONTAINER_JNL = class(DtoCONTAINER_JNL, IDto)
private
FName : string;
FReferenceCounted : boolean;
_isNew : boolean;
FModified : boolean;
FJNL_ID : integer;
FJNL_TYPE_ID : integer;
FJNL_DATE : TDateTime;
public
property JNL_ID : integer read FJNL_ID write SetJNL_ID;
property JNL_TYPE_ID : integer read FJNL_TYPE_ID write SetJNL_TYPE_ID;
property JNL_DATE : TDateTime read GetJNL_DATE write SetJNL_DATE;
典型的setter方法:
procedure TDtoCONTAINER_JNL.SetJNL_DATE(const value : TDateTime);
begin
ChangedProperties:= DtoGenerics.ChangeTracker('JNL_DATE', value, inherited JNL_DATE, self.IsLoaded, ChangedProperties);
inherited JNL_DATE := DtoGenerics.GetXsDate(value);
end;
典型的吸气方法:
function TDtoCONTAINER_JNL.GetJNL_DATE : TDateTime;
begin
Result := DtoGenerics.GetDate(inherited JNL_DATE);
end;
每当设置属性时,更改跟踪器都会将此属性名称添加到已更改属性列表中以返回到服务器。这使得更新语句具有针对性且高效。问题是每个 getter/setter 实际上都使派生类与基类不兼容,也就是说,多态性被破坏,并且转换不再按预期工作。
上面的类是根据相应的数据库表/实体从 C# 中的 t4 模板生成的,因此更改 100 多个类应该不成问题。
有人有这方面的经验吗?
任何建议将不胜感激。
编辑
Wsdl 导入器主要由常量组成,这些常量使用字符串格式或类似的格式来创建复杂类型的 Delphi 等效项。我进行了以下更改,使用类似的常量名称来轻松识别我的更改,以及将它们放置在与预先存在的代码相关的位置。理想情况下,我会完全摆脱继承,只在 wsdl 中使用类的修改版本,因为即使我将其转换回 Dto 类,我仍然无法提交修改后的 Tdto,因为 Web 服务会拒绝它并显示一条消息就像“期待 DtoObject,但得到 undtoUnit.TdtoObject ”。因此,我用继承来处理 ArrayOfObjects 到 TList 之间的转换,反之亦然。以下是我所记得的最详细的更改:
// In WSDLImpConst
// I changed sRemoteClassDeclPas constant value of 'private' to 'proctected'
// Then I added these after SUnitInit
sTrackerDec = sTrackerProcPrefix+ sTrackerProcArgs + sLineBreak;
sTrackerProc = sTrackerDec + 'begin' + sLineBreak +
' Result:= nProps;' + sLineBreak +
' if (_loaded) and (oVal <> pVal) then' + sLineBreak +
' begin ' + sLineBreak +
' Result := TrackChange(pName, nProps);' + sLineBreak +
' end;' + sLineBreak +
'end;' + sLineBreak ;
sTracker2Dec = sTrackerProcPrefix+ sTracker2ProcArgs + sLineBreak;
sTracker2Proc = sTracker2Dec + 'begin' + sLineBreak +
' Result:= nProps;' + sLineBreak +
' if (_loaded) and (oVal <> DateTimeToXSDateTime(pVal)) then' + sLineBreak +
' begin ' + sLineBreak +
' Result := TrackChange(pName, nProps);' + sLineBreak +
' end;' + sLineBreak +
'end;' + sLineBreak ;
sTracker3Dec = sTrackerProcPrefix+ sTracker3ProcArgs + sLineBreak;
sTracker3Proc = sTracker3Dec + 'begin' + sLineBreak +
' Result:= nProps;' + sLineBreak +
' if nProps = '''' then' + sLineBreak +
' nProps := pName' + sLineBreak +
' else' + sLineBreak +
' nProps := pName + '','' + nProps;' + sLineBreak +
' Result:= nProps;' + sLineBreak +
'end;' + sLineBreak ;
sTracker4Dec = sTrackerProcPrefix+ sTracker4ProcArgs + sLineBreak;
sTracker4Proc = sTracker4Dec + 'begin' + sLineBreak +
' Result:= nProps;' + sLineBreak +
' if (_loaded) and (oVal <> pVal) then' + sLineBreak +
' begin ' + sLineBreak +
' Result := TrackChange(pName, nProps);' + sLineBreak +
' end;' + sLineBreak +
'end;'
//Added my own setters:
sRemoteClassSetterImplPas = 'procedure %0:s.Set%1:s(const A%2:s: %2:s);' + sLineBreak +
'begin' + sLineBreak +
' F%1:s := A%2:s;' + sLineBreak +
'end;' + sLineBreak;
sRemoteClassSetterImplPas2= 'procedure %0:s.Set%1:s(const A%2:s: %2:s);' + sLineBreak +
'begin' + sLineBreak +
' F%1:s := A%2:s;' + sLineBreak +
' F%1:s_Specified := True;' + sLineBreak +
'end;' + sLineBreak;
sRemoteClassSetterImplPas3 = 'procedure %0:s.Set%1:s(const A%2:s: %2:s);' + sLineBreak +
'begin' + sLineBreak +
' ChangedProperties:= TrackChange(''%1:s'', A%2:s, F%1:s, self.IsLoaded, ChangedProperties);' + sLineBreak +
' F%1:s := A%2:s;' + sLineBreak +
'end;' + sLineBreak;
sRemoteClassSetterImplPas4 = 'procedure %0:s.Set%1:s(const A%2:s: %2:s);' + sLineBreak +
'begin' + sLineBreak +
' ChangedProperties:= TrackChange(A%2:s, F%1:s, ''%1:s'', self.IsLoaded, ChangedProperties);' + sLineBreak +
' F%1:s := A%2:s;' + sLineBreak +
'end;' + sLineBreak;
// And for indexed properties
sRemoteClassSetterImplPasIdx2=
'procedure %0:s.Set%1:s(Index: Integer; const A%2:s: %2:s);' + sLineBreak +
'begin' + sLineBreak +
' F%1:s := A%2:s;' + sLineBreak +
' F%1:s_Specified := True;' + sLineBreak +
'end;' + sLineBreak;
sRemoteClassSetterImplPasIdx3 =
'procedure %0:s.Set%1:s(Index: Integer; const A%2:s: %2:s);' + sLineBreak +
'begin' + sLineBreak +
' ChangedProperties:= TrackChange(''%1:s'', A%2:s, F%1:s, self.IsLoaded, ChangedProperties);' + sLineBreak +
' F%1:s := A%2:s;' + sLineBreak +
'end;' + sLineBreak;
sRemoteClassSetterImplPasIdx4 =
'procedure %0:s.Set%1:s(Index: Integer; const A%2:s: %2:s);' + sLineBreak +
'begin' + sLineBreak +
' ChangedProperties:= TrackChange(A%2:s, F%1:s, ''%1:s'', self.IsLoaded, ChangedProperties);' + sLineBreak +
' F%1:s := A%2:s;' + sLineBreak +
'end;' + sLineBreak;
// Added these before the SImplDecl constant:
sIntfFactoryDecl = '_di_%0:s Get%0:s(bool useWSDL=false, AnsiString addr="", THTTPRIO* HTTPRIO=0);' + sLineBreak + sLineBreak;
sTrackerProcPrefix = 'function TrackChange';
sTrackerProcArgs = '(const pName: string; pVal, oVal: variant; _loaded: boolean; nProps: string): string; overload';
sTracker2ProcArgs = '(const pName: string; pVal: TDateTime; oVal: txsdateTime; _loaded:boolean; nProps: string): string; overload;';
sTracker3ProcArgs = '(const pName: string; nProps: string): string; overload;';
sTracker4ProcArgs = '(pVal, oVal: TByteDynArray; const pName: string; _loaded: boolean; nProps: string): string; overload';
sIntfTrackDecl = sTrackerProcPrefix + sTrackerProcArgs+ sLineBreak;
sIntfTrack2Decl = sTrackerProcPrefix + sTracker2ProcArgs+ sLineBreak;
sIntfTrack3Decl = sTrackerProcPrefix + sTracker3ProcArgs+ sLineBreak;
sIntfTrack4Decl = sTrackerProcPrefix + sTracker4ProcArgs+ sLineBreak;
// Then in WSDLPasWriter I added my new constant arrays:
SetterImpl2:array[Boolean] of string = (sRemoteClassSetterImplPas2, sRemoteClassSetterImplPasIdx2);
SetterImpl3:array[Boolean] of string = (sRemoteClassSetterImplPas3, sRemoteClassSetterImplPasIdx3);
SetterImpl4:array[Boolean] of string = (sRemoteClassSetterImplPas4, sRemoteClassSetterImplPasIdx4);
// then modified the setter section in 'WriteComplexTypeClass'
{ Setter }
if UseSetGets or GenSpecifiedSupport(Member) then
begin
if GenSpecifiedSupport(Member) then
begin
WriteFmt(SetterImpl2[HasIndexDecl(Member)],[WSDLType.LangName,
Member.LangName,
Member.DataType.LangName])
end
else
begin
if (ContainsStr(BaseName, 'Dto')) and (not ContainsStr(Member.DataType.LangName, 'XS'))
and (not ContainsStr(Member.DataType.LangName, 'ArrayOf')) then
if (ContainsStr(Member.DataType.LangName, 'TByteDynArray')) then
WriteFmt(SetterImpl4[HasIndexDecl(Member)],[WSDLType.LangName,
Member.LangName,
Member.DataType.LangName])
else
WriteFmt(SetterImpl3[HasIndexDecl(Member)],[WSDLType.LangName,
Member.LangName,
Member.DataType.LangName])
else
WriteFmt(SetterImpl1[HasIndexDecl(Member)],[WSDLType.LangName,
Member.LangName,
Member.DataType.LangName]);
end;
// at WriteInterfaceEnd I added
WriteFmt(sIntfTrackDecl, []);
WriteFmt(sIntfTrack2Decl, []);
WriteFmt(sIntfTrack3Decl, []);
WriteFmt(sIntfTrack4Decl, []);
// at WriteInterfaceBegin I added
WriteLn(sTrackerProc, []);
WriteLn(sTracker2Proc, []);
WriteLn(sTracker3Proc, []);
WriteLn(sTracker4Proc, []);
// finally I changed the wsdlImp dpr and replaced 'AnsiString' (or 'widestring' I can't remember) with 'string'
最佳答案
如果我没记错的话,WSDL 到 Delphi 转换器源代码是 Delphi 企业版及更高版本的一部分(在 wsdlimporter
目录中称为 WSDLImp.dpr
)。
我会对其进行调整以直接生成您自己的类。
关于delphi - 我可以对从 Delphi 2010 中的 wsdl 导入类派生的类实现更改跟踪吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12476023/
为什么 WSDL 引入 wsdl:message?和消息部分? 与在操作参数(输入、输出、故障)中直接使用 XSD 相比,他们可以带来什么优势? 它们(带有 wsdl 消息部分的 wsdl 消息)如何
这个问题看起来很简单,但我找不到合适的地方在 WSDL 文档中设置其定义的版本。 目标是能够很容易地看到它何时过时,以及我将来何时更新它。 我要把它设为 1.0。如果将来我向它添加新操作,我将其设置为
在 WSDL 文件中,函数可以返回类型或元素。到目前为止,我仅使用自定义类型作为结果。但是,我想知道什么时候Element应该比Type更合适?它们有什么区别? 有什么区别吗 和
我在 web sphere 服务器上部署了一个 jax-ws web 服务,当我尝试使用 url 在浏览器中访问 wsdl 时 "Http://localhost:7001/HelloWorldSer
我在使用 SVCUtil 为 WCF 生成代理时遇到错误。错误是 Attempting to download metadata from 'net.pipe://localhost/WebServi
我正在遵循 WSDL-first(由我们的客户提供)方法来开发 WCF 服务,但是从我的 wcf 服务生成的 WSDL 与我们的客户提供给我的 WSDL 略有不同,并且由于这种不匹配,客户在调用我的服
我有嵌套的 WSDL,我想将其扁平化。 wsdl 导入 xsd 文件,这些文件又包含其他文件等。我喜欢把整个东西压平成一个文件,以便将它提供给一个无法执行导入/包含的工具。有没有我可以使用的简单工具(
我正在尝试使用一些统计信息进行 WSDL 解析(使用 c#.net)。我的统计数据取决于 WSDL 中的文档标签。我想知道可以包含文档标签的 wsdl 标签列表来检查它们。 我试图阅读 WS-I 基本
我有一个 WSDL 文件。我想将 wsdl 文件转换为 Web 服务类文件。 是否可以?如果是,请向我详细解释。 最佳答案 在解决方案资源管理器中右键单击 您的项目并转到“添加服务 引用...” 按窗
我正在使用 Axis 为示例 WebService 建模。我现在正在做的是试图了解自动化 wsdl 和代码生成的局限性。 现在对于一些服务器端代码: 这是示例 Web 服务的框架: public cl
我有一个 Silverlight 应用程序,它通过 WCF 服务与服务器端的 ADO.Net 数据实体通信。实际上,我正在使用多个 WCF 服务与三个不同的数据 ADO.Net 数据实体进行通信。我最
是否有使用服务端点地址获取服务 WSDL 的通用方法。我知道这可以通过将 ?wsdl 附加到 Axis2 服务来完成。但是这个属性是否也适用于其他 Web 服务容器? 最佳答案 ?wsdl 适用于所有
例如使用 png归档其 mime-type是“图像/png”;那么 wsdl 的 MIME 类型是什么?文件 ? 最佳答案 text/xml - WSDL 是基于 XML 格式的服务描述。 您可以在“
我的服务是从一个 wsdl 文件中选取的。但是发布的服务 wso2 是 chenged。如果我希望 wso2 像我的 wsdl 文件一样发布。如何设置?例如,我的 wsdl 文件是:
我需要在给定 XSD 文件的情况下生成 WSDL 文件。我该怎么做呢?我可以在VS2005中这样做吗?最简单的方法是什么? 最佳答案 你不能 - XSD 描述数据方面,例如Web 服务的功能 - WS
有什么方法可以从 wsdl 生成 xsd 吗?任何链接或工具也可以。最简单的方法是什么? 最佳答案 您可以使用SoapUI:http://www.soapui.org/这是一个通常很方便的程序。创建一
我启动我的 azure 应用程序,浏览到 svc 文件 http://127.0.0.1:82/transaction.svc ,我得到了通常的结果: You have created a servi
我使用动态端点 wsdl(通过 http 的 wsdl)来生成客户端。这工作得很好。 是否可以从动态wsdl的http链接生成静态wsdl? 问题是动态 wsdl 只能从一台机器访问。 我想在另一台电
我想知道是否可以将请求从一个 wsdl 发送到另一个 wsdl。如果是,那我该怎么做? 流程将是: 我想使用 switchyard 公开一个 wsdl,比如 wsdl-1,它可能有 100 个参数,带
我按照定义的步骤使用 Spring Boot 创建了一个网络服务 here当我尝试下载 wsdl 时,我不得不在 url 中使用 .wsdl 。但是,当我使用 ?wsdl 时,不会下载 wsdl。当我
我是一名优秀的程序员,十分优秀!