public IEnumerator GetEnumerator() { string strError = ""; long nStart = 0; long nPerCount = -1; long nCount = 0; ErrorCodeValue kernel_errorcode = ErrorCodeValue.NoError; // 2017/10/1 if (this.BatchSize != 0) { nPerCount = this.BatchSize; } while (true) { ResInfoItem[] items = null; long lRet = this.Channel.Dir(this.Path, nStart, nPerCount, this.Lang, this.Style, out items, out kernel_errorcode, out strError); if (lRet == -1) { if (this.Channel.ErrorCode != ErrorCode.NoError) { throw new ChannelException(Channel.ErrorCode, strError); } goto ERROR1; } if (items == null || items.Length == 0) { yield break; } if (items != null) { foreach (ResInfoItem item in items) { yield return(item); } nStart += items.Length; nCount += items.Length; } if (nCount >= lRet) { yield break; } } ERROR1: throw new Exception(strError); }
internal TextAnalyticsError(ErrorCodeValue code, string message, string target, InnerError innerError, IReadOnlyList <TextAnalyticsError> details) { Code = code; Message = message; Target = target; InnerError = innerError; Details = details; }
public Result( string strError, ErrorCodeValue errorcode, int nValue) { this.ErrorCode = errorcode; this.ErrorString = strError; this.Value = nValue; }
// 设置值 public void SetValue( string strError = "", ErrorCodeValue errorcode = ErrorCodeValue.CommonError, int nValue = -1) { this.ErrorCode = errorcode; this.ErrorString = strError; this.Value = nValue; }
internal TextAnalyticsError(ErrorCodeValue code, string message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } Code = code; Message = message; }
internal TextAnalyticsError(ErrorCodeValue code, string message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } Code = code; Message = message; Details = new ChangeTrackingList <TextAnalyticsError>(); }
internal static TextAnalyticsError DeserializeTextAnalyticsError(JsonElement element) { ErrorCodeValue code = default; string message = default; Optional <string> target = default; Optional <InnerError> innererror = default; Optional <IReadOnlyList <TextAnalyticsError> > details = default; foreach (var property in element.EnumerateObject()) { if (property.NameEquals("code")) { code = new ErrorCodeValue(property.Value.GetString()); continue; } if (property.NameEquals("message")) { message = property.Value.GetString(); continue; } if (property.NameEquals("target")) { target = property.Value.GetString(); continue; } if (property.NameEquals("innererror")) { if (property.Value.ValueKind == JsonValueKind.Null) { property.ThrowNonNullablePropertyIsNull(); continue; } innererror = InnerError.DeserializeInnerError(property.Value); continue; } if (property.NameEquals("details")) { if (property.Value.ValueKind == JsonValueKind.Null) { property.ThrowNonNullablePropertyIsNull(); continue; } List <TextAnalyticsError> array = new List <TextAnalyticsError>(); foreach (var item in property.Value.EnumerateArray()) { array.Add(DeserializeTextAnalyticsError(item)); } details = array; continue; } } return(new TextAnalyticsError(code, message, target.Value, innererror.Value, Optional.ToList(details))); }
/// <summary> /// The NspiSeekEntries method searches for and sets the logical position in a specific table /// to the first entry greater than or equal to a specified value. /// </summary> /// <param name="reserved">A DWORD value that is reserved for future use. Ignored by the server.</param> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="target">A PropertyValue_r value holding the value that is being sought.</param> /// <param name="table">The value NULL or a PropertyTagArray_r value. /// It holds a list of Minimal Entry IDs that comprise a restricted address book container.</param> /// <param name="propTags">It contains a list of the proptags of the columns /// that client wants to be returned for each row returned.</param> /// <param name="rows">It contains the address book container rows the server returns in response to the request.</param> /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue NspiSeekEntries(uint reserved, ref STAT stat, PropertyValue_r target, PropertyTagArray_r?table, PropertyTagArray_r?propTags, out PropertyRowSet_r?rows, bool needRetry = true) { ErrorCodeValue result = 0; STAT inputStat = stat; if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp") { result = this.nspiRpcAdapter.NspiSeekEntries(reserved, ref stat, target, table, propTags, out rows, needRetry); } else { result = this.nspiMapiHttpAdapter.SeekEntries(reserved, ref stat, target, table, propTags, out rows); } this.VerifyNspiSeekEntries(result, rows, inputStat, stat); this.VerifyTransport(); return(result); }
/// <summary> /// The NspiGetMatches method returns an Explicit Table. /// </summary> /// <param name="reserved">A DWORD value reserved for future use.</param> /// <param name="stat">A STAT block describing a logical position in a specific address book container.</param> /// <param name="proReserved">A PropertyTagArray_r reserved for future use.</param> /// <param name="reserved2">A DWORD value reserved for future use. Ignored by the server.</param> /// <param name="filter">The value NULL or a Restriction_r value. /// It holds a logical restriction to apply to the rows in the address book container specified in the stat parameter.</param> /// <param name="propName">The value NULL or a PropertyName_r value. /// It holds the property to be opened as a restricted address book container.</param> /// <param name="requested">A DWORD value. It contains the maximum number of rows to return in a restricted address book container.</param> /// <param name="outMids">A PropertyTagArray_r value. On return, it holds a list of Minimal Entry IDs that comprise a restricted address book container.</param> /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value. /// It contains a list of the proptags of the columns that client wants to be returned for each row returned.</param> /// <param name="rows">A reference to a PropertyRowSet_r value. It contains the address book container rows the server returns in response to the request.</param> /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue NspiGetMatches(uint reserved, ref STAT stat, PropertyTagArray_r?proReserved, uint reserved2, Restriction_r?filter, PropertyName_r?propName, uint requested, out PropertyTagArray_r?outMids, PropertyTagArray_r?propTags, out PropertyRowSet_r?rows, bool needRetry = true) { ErrorCodeValue result = 0; STAT inputStat = stat; if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp") { result = this.nspiRpcAdapter.NspiGetMatches(reserved, ref stat, proReserved, reserved2, filter, propName, requested, out outMids, propTags, out rows, needRetry); } else { result = this.nspiMapiHttpAdapter.GetMatches(reserved, ref stat, proReserved, reserved2, filter, propName, requested, out outMids, propTags, out rows); } this.VerifyNspiGetMatches(result, rows, outMids, inputStat, stat); this.VerifyTransport(); return(result); }
/// <summary> /// Clean up the environment. /// </summary> protected override void TestCleanup() { bool transportIsMAPI = Common.GetConfigurationPropertyValue("TransportSeq", this.Site).ToLower(CultureInfo.InvariantCulture) == "mapi_http"; if (bool.Parse(Common.GetConfigurationPropertyValue("MS-OXNSPI_Supported", this.Site)) && (!transportIsMAPI || (transportIsMAPI && Common.IsRequirementEnabled(2003, this.Site)))) { if (this.IsRequireToDeleteAddressBookMember) { uint flagsOfModLinkAtt = (uint)NspiModLinkAtFlag.fDelete; uint propTagOfModLinkAtt = (uint)AulProp.PidTagAddressBookMember; ErrorCodeValue result = this.ProtocolAdatper.NspiModLinkAtt(flagsOfModLinkAtt, propTagOfModLinkAtt, this.midToBeModified, this.entryIdToBeDeleted); ErrorCodeValue expectedResult = ErrorCodeValue.Success; if (!Common.IsRequirementEnabled(1340, this.Site) && this.IsEphemeralEntryID == true) { expectedResult = ErrorCodeValue.GeneralFailure; // The Exchange 2013 returns "GeneralFailure" when the Ephemeral Entry ID is used to modify the PidTagAddressBookMember value. } Site.Assert.AreEqual <ErrorCodeValue>(expectedResult, result, "NspiModLinkAtt method should return Success in Exchange 2010 and Exchange 2013."); } if (this.IsRequireToDeleteAddressBookPublicDelegate) { uint flagsOfModLinkAtt = (uint)NspiModLinkAtFlag.fDelete; uint propTagOfModLinkAtt = (uint)AulProp.PidTagAddressBookPublicDelegates; ErrorCodeValue result = this.ProtocolAdatper.NspiModLinkAtt(flagsOfModLinkAtt, propTagOfModLinkAtt, this.midToBeModified, this.entryIdToBeDeleted); ErrorCodeValue expectedResult = ErrorCodeValue.Success; if (!Common.IsRequirementEnabled(1340, this.Site)) { expectedResult = ErrorCodeValue.GeneralFailure; // The Exchange 2013 returns "GeneralFailure" when the Ephemeral Entry ID is used to modify the PidTagAddressBookMember value. } Site.Assert.AreEqual <ErrorCodeValue>(expectedResult, result, "NspiModLinkAtt method should return Success in Exchange 2010, and Exchange 2013 will return GeneralFailure."); } this.ProtocolAdatper.Reset(); } base.TestCleanup(); }
// 修改数据库信息 // parameters: // logicNames 逻辑库名。ArrayList。每个元素为一个string[2]类型。其中第一个字符串为名字,第二个为语言代码 // return: // -1 出错 // 0 成功(基于WebService接口CreateDb的返回值) public long DoSetDBInfo( string strOldDbName, List<string[]> logicNames, string strType, string strSqlDbName, string strKeysDef, string strBrowseDef, out string strError) { strError = ""; LogicNameItem[] logicnames = new LogicNameItem[logicNames.Count]; for (int i = 0; i < logicnames.Length; i++) { logicnames[i] = new LogicNameItem(); string[] cols = (string[])logicNames[i]; logicnames[i].Lang = cols[1]; logicnames[i].Value = cols[0]; } REDO: try { REDOCREATE: IAsyncResult soapresult = this.ws.BeginSetDbInfo(strOldDbName, logicnames, strType, strSqlDbName, strKeysDef, strBrowseDef, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndSetDbInfo(soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDOCREATE; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } this.ClearRedoCount(); return result.Value; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
// 删除数据库 // return: // -1 出错 // 0 成功(基于WebService接口DeleteDb的返回值) public long DoDeleteDB(string strDBName, out string strError) { strError = ""; REDO: try { REDOINITIAL: IAsyncResult soapresult = this.ws.BeginDeleteDb(strDBName, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndDeleteDb(soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strDBName, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDOINITIAL; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } this.ClearRedoCount(); return result.Value; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
void ConvertErrorCode(Result result) { this.ClearRedoCount(); this.OriginErrorCode = result.ErrorCode; if (result.ErrorCode == ErrorCodeValue.NoError) { this.ErrorCode = ChannelErrorCode.None; // 2008/7/29 } else if (result.ErrorCode == ErrorCodeValue.NotFound) { this.ErrorCode = ChannelErrorCode.NotFound; } else if (result.ErrorCode == ErrorCodeValue.PartNotFound) { this.ErrorCode = ChannelErrorCode.PartNotFound; } else if (result.ErrorCode == ErrorCodeValue.EmptyContent) { this.ErrorCode = ChannelErrorCode.EmptyRecord; } else if (result.ErrorCode == ErrorCodeValue.TimestampMismatch) { this.ErrorCode = ChannelErrorCode.TimestampMismatch; } else if (result.ErrorCode == ErrorCodeValue.NotLogin) { this.ErrorCode = ChannelErrorCode.NotLogin; } /* else if (result.ErrorCode == ErrorCodeValue.NoHasManagement) { this.ErrorCode = ChannelErrorCode.NoHasManagement; } */ else if (result.ErrorCode == ErrorCodeValue.NotHasEnoughRights) { this.ErrorCode = ChannelErrorCode.NotHasEnoughRights; } else if (result.ErrorCode == ErrorCodeValue.AlreadyExist) { this.ErrorCode = ChannelErrorCode.AlreadyExist; } else if (result.ErrorCode == ErrorCodeValue.AlreadyExistOtherType) { this.ErrorCode = ChannelErrorCode.AlreadyExistOtherType; } else if (result.ErrorCode == ErrorCodeValue.ApplicationStartError) { this.ErrorCode = ChannelErrorCode.ApplicationStartError; } else if (result.ErrorCode == ErrorCodeValue.NotFoundSubRes) { this.ErrorCode = ChannelErrorCode.NotFoundSubRes; } else if (result.ErrorCode == ErrorCodeValue.Canceled) { this.ErrorCode = ChannelErrorCode.RequestCanceled; } else { this.ErrorCode = ChannelErrorCode.OtherError; } }
// 保存修改后的读者记录DOM // return: // -2 时间戳冲突 // -1 error // 0 没有必要保存(changed标志为false) // 1 成功保存 public int SaveLoginReaderDom( out string strError) { strError = ""; if (this.ReaderInfo == null) { strError = "尚未装载过ReaderInfo"; return(0); } if (string.IsNullOrEmpty(this.UserID) == true) { strError = "尚未登录"; return(0); } if (this.IsReader == false) { strError = "当前登录的用户不是读者类型"; return(-2); } if (this.ReaderInfo.ReaderDomChanged == false) { return(0); } XmlDocument readerdom = this.ReaderInfo.ReaderDom; byte[] output_timestamp = null; string strOutputPath = ""; string strOutputXml = ""; long lRet = 0; string strExistingXml = ""; ErrorCodeValue kernel_errorcode = ErrorCodeValue.NoError; // 注:保存读者记录本来是为上传透着个性头像,修改 preference 等用途提供的。如果用代理帐户做这个操作,就要求代理帐户具有修改读者记录的权限,同时修改哪些字段就得不到限制了。可以考虑在 dp2library,增加一种功能,在代理帐户修改读者记录的时候,模仿读者权限来进行限制? LibraryChannel channel = this.GetChannel(true); // this.GetChannel(true, this.m_strParameters); try { lRet = // this.Channel. channel.SetReaderInfo( null, "change", this.ReaderInfo.ReaderDomPath, readerdom.OuterXml, "", // sessioninfo.Account.ReaderDomOldXml, // strOldXml this.ReaderInfo.ReaderDomTimestamp, out strExistingXml, out strOutputXml, out strOutputPath, out output_timestamp, out kernel_errorcode, out strError); if (lRet == -1) { if (// this.Channel. channel.ErrorCode == ErrorCode.TimestampMismatch || kernel_errorcode == ErrorCodeValue.TimestampMismatch) { return(-2); } return(-1); } } finally { //ReleaseTempChannel(temp); this.ReturnChannel(channel); } int nRet = OpacApplication.LoadToDom(strOutputXml, out readerdom, out strError); if (nRet == -1) { strError = "装载读者记录进入XML DOM时发生错误: " + strError; return(-1); } this.ReaderInfo.ReaderDom = readerdom; RefreshReaderAccount(ref this.ReaderInfo, readerdom); this.ReaderInfo.ReaderDomChanged = false; this.ReaderInfo.ReaderDomTimestamp = output_timestamp; return(1); }
// 获得dpKernel版本号 // return: // -1 出错。错误信息在strError中 // 0 成功 public int GetVersion(out string strVersion, out string strError) { strError = ""; strVersion = ""; REDO: try { IAsyncResult soapresult = this.ws.BeginGetVersion( null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; /* if (soapresult.IsCompleted) break; * */ } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndGetVersion(soapresult); if (result.Value == -1) { ConvertErrorCode(result); strError = result.ErrorString; return -1; } if (result.Value == 0) { strVersion = result.ErrorString; return 0; } this.ClearRedoCount(); return 1; } catch (Exception ex) { int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
// 修改密码 // 参数strUserName和 strOldPassword可以为null。这种情况下, // 本函数直接去修改密码,如果此时channel确实已经登录过,就正好不需要 // 其他前提条件;如果此时channel尚未登录过,函数Login()的固有机制 // 可能会弹出登录对话框。 // parameters: // bManager 是否以管理员身份进行修改。管理员方式的特点,是 // 1) 必须用管理员帐户先登录(这个帐户和即将被修改的帐户可以没有联系) // 2) 用特殊的WebServiceAPI ChangeOtherPassword() // return: // -1 出错。错误信息在strError中 // 0 成功。 public int ChangePassword( string strUserName, string strOldPassword, string strNewPassword, bool bManager, out string strError) { strError = ""; int nRet = 0; if (bManager == true) { if (strUserName == null) { strError = "bManager参数为true时,strUserName参数不能为null..."; return -1; } } if (strUserName != null && strOldPassword != null && bManager == false) { // return: // -1 出错。错误信息在strError中 // 0 登录失败。错误信息也在strError // 1 登录成功 nRet = this.Login(strUserName, strOldPassword, out strError); if (nRet == -1) return -1; if (nRet == 0) { strError = "原密码不正确"; return -1; } } REDO: try { IAsyncResult soapresult = null; if (bManager == false) { soapresult = this.ws.BeginChangePassword( strNewPassword, null, null); } else { soapresult = this.ws.BeginChangeOtherPassword( strUserName, strNewPassword, null, null); } for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = null; if (bManager == false) { result = this.ws.EndChangePassword(soapresult); } else { result = this.ws.EndChangeOtherPassword(soapresult); } if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed nRet = this.UiLogin( strUserName == null ? ("密码修改操作被延迟。请先用旧密码 对 拟修改密码的帐户进行一次登录,以便修改密码操作自动继续进行...") : ("请先用旧密码对帐户 '" + strUserName + "' 进行一次登录,以便修改密码操作顺利进行...") , "", LoginStyle.None, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; if (result.ErrorCode == ErrorCodeValue.NotHasEnoughRights)//ErrorCodeValue.NoHasManagement) { // return: // -1 error // 0 login failed // 1 login succeed nRet = this.UiLogin( "请先用具备管理员权限的帐户登录,才能修改帐户 '" + strUserName + "' 密码...", "", LoginStyle.None, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } /* ConvertErrorCode(result); strError = result.ErrorString; * */ // 原来在这里,稍晚 return -1; } this.ClearRedoCount(); return 0; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
// 获得检索结果的浏览格式 // 浅包装版本 public long DoGetSearchResult( string strResultSetName, long lStart, long lMax, string strColumnStyle, string strLang, DigitalPlatform.Stop stop, out Record[] searchresults, out string strError) { strError = ""; searchresults = null; REDO: try { IAsyncResult soapresult = this.ws.BeginGetRecords( strResultSetName, lStart, lMax, strLang, strColumnStyle, // "id,cols" null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } // Record[] records = null; Result result = this.ws.EndGetRecords( out searchresults, // records, soapresult); if (result.Value == -1) { // 2011/4/18 if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } else { // Debug.Assert(records != null, "WebService GetRecords() API record参数返回值不应为null"); } #if NO // 将结果移出 searchresults = new Record[records.Length]; // SearchResult for (int i = 0; i < records.Length; i++) { searchresults[i] = records[i]; } #endif this.ClearRedoCount(); return result.Value; // 结果集内总数 } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; // 2013/2/11 if (this.ErrorCode == ChannelErrorCode.QuotaExceeded) { if (lMax > 1 || lMax == -1) lMax = 1; // 修改为最小数量重做一次 else return -1; } goto REDO; } }
// 保存资源记录 // parameters: // strPath 格式: 库名/记录号/object/对象xpath // bTailHint 是否为最后一次写入操作。这是一个暗示参数,本函数将根据此参数为最后一次写入操作设置特殊的超时时间。 // 假定有时整个资源尺寸很大,虽然每次局部写入耗时不多,但是最后一次写入因为服务器要执行整个资源转存 // 的操作后API才返回,所以可能会耗费类似20分钟这样的长时间,导致WebService API超时失败。 // 本参数是一个暗示操作(本函数也不担保一定要做什么操作),如果调用者不清楚它的含义,可以使用false。 public long DoSaveResObject(string strPath, string strObjectFileName, // 任延华加,该参数代表存放对象数据的文件名 string strLocalPath, // 该参数代表本地文件名,有时会与strObjectFileName不同 string strMime, string strLastModifyTime, // 2007/12/13 string strRange, bool bTailHint, byte[] timestamp, out byte[] output_timestamp, out string strError) { strError = ""; output_timestamp = null; FileInfo fi = new FileInfo(strObjectFileName); if (fi.Exists == false) { strError = "文件 '" + strObjectFileName + "'不存在..."; return -1; } byte[] baTotal = null; long lRet = RangeList.CopyFragment( strObjectFileName, strRange, out baTotal, out strError); if (lRet == -1) return -1; string strOutputPath = ""; // int nOldTimeout = -1; if (bTailHint == true) { /* nOldTimeout = this.Timeout; this.Timeout = 20 * 60 * 1000; * */ } REDO: try { REDOSAVE: // string strMetadata = "<file mimetype='" + strMime + "' localpath='" + strLocalPath + "'/>"; string strMetadata = BuildMetadataXml(strMime, strLocalPath, strLastModifyTime); IAsyncResult soapresult = this.ws.BeginWriteRes(strPath, strRange, fi.Length, // 这是整个包尺寸,不是本次chunk的尺寸。因为服务器显然可以从baChunk中看出其尺寸,不必再专门用一个参数表示这个尺寸了 baTotal, // null, // attachmentid strMetadata, "", // style timestamp, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndWriteRes( out strOutputPath, out output_timestamp, soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDOSAVE; } ConvertErrorCode(result); strError = result.ErrorString; if (result.ErrorCode == ErrorCodeValue.TimestampMismatch) { this.ErrorCode = ChannelErrorCode.TimestampMismatch; strError = "时间戳不匹配。\r\n\r\n请求的时间戳 [" + ByteArray.GetHexTimeStampString(timestamp) + "] 响应的时间戳 [" + ByteArray.GetHexTimeStampString(output_timestamp) + "]"; return -1; } // 原来在这里,稍晚 return -1; } } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } finally { /* if (bTailHint == true) this.Timeout = nOldTimeout; * */ } this.ClearRedoCount(); return 0; }
// 2009/7/19 // 获取检索命中结果 // 获得某一列信息的版本 public long DoGetSearchResultOneColumn( string strResultSetName, long lStart, long lMax, string strLang, DigitalPlatform.Stop stop, int nColumn, out List<string> aLine, out string strError) { strError = ""; aLine = new List<string>(); Record[] records = null; long nPerCount = lMax; // -1; int nCount = 0; long lTotalCount = -1; for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; return -1; } } REDO: try { IAsyncResult soapresult = this.ws.BeginGetRecords( strResultSetName, lStart, nPerCount, strLang, "id,cols", // 不要cols null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndGetRecords( out records, soapresult); if (result.Value == -1) { // 2011/4/21 if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } else { Debug.Assert(records != null, "WebService GetRecords() API record参数返回值不应为null"); lTotalCount = result.Value; if (lMax != -1) lTotalCount = Math.Min(lTotalCount, lMax); } if (records != null) { lStart += records.Length; nCount += records.Length; nPerCount = lTotalCount - lStart; } // 做事 for (int i = 0; i < records.Length; i++) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; return -1; } stop.SetMessage("正在装入 " + Convert.ToString(lStart + i) + " / " + ((lTotalCount == -1) ? "?" : Convert.ToString(lTotalCount))); } Record record = records[i]; aLine.Add(record.Cols[nColumn]); } if (nCount >= result.Value || nCount >= lTotalCount) break; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; // 2013/2/11 if (this.ErrorCode == ChannelErrorCode.QuotaExceeded) { if (nPerCount > 1 || nPerCount == -1) nPerCount = 1; // 修改为最小数量重做一次 else return -1; } goto REDO; } } this.ClearRedoCount(); return 0; }
// 2012/11/11 // 成批写入XML记录 // 浅包装版本 // 每个元素中Xml成员内放了一条完整的XML记录。如果记录不完整,请不要使用此API。 // results中返回和inputs一样数目的元素,每个元素表示对应的inputs元素写入是否成功,返回时间戳和实际写入的路径 // 在中途出错的情况下,results中的元素数目会比inputs中的少,但从前到后顺序是固定的,可以对应 public long DoWriteRecords( DigitalPlatform.Stop stop, RecordBody[] inputs, string strStyle, out RecordBody[] results, out string strError) { strError = ""; results = null; REDO: try { IAsyncResult soapresult = this.ws.BeginWriteRecords( inputs, strStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } // Record[] records = null; Result result = this.ws.EndWriteRecords( out results, soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } else { // 可以在这里检查返回参数 } this.ClearRedoCount(); return result.Value; // 结果集内总数 } catch (Exception ex) { int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
// 获取浏览记录 public long DoBrowse( BrowseList listView, string strLang, DigitalPlatform.Stop stop, string strResultSetName, string strOutputStyle, out string strError) { strError = ""; Record[] records = null; long nStart = 0; long nPerCount = -1; int nCount = 0; bool bOutputKeyID = StringUtil.IsInList("keyid", strOutputStyle); long lTotalCount = -1; for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; return -1; } } nPerCount = -1; // 2013/2/12 REDO: try { IAsyncResult soapresult = this.ws.BeginGetRecords( strResultSetName, nStart, nPerCount, strLang, strOutputStyle, //"id,cols", null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndGetRecords( out records, soapresult); if (result.Value == -1) { // 2011/4/21 if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } else { Debug.Assert(records != null, "WebService GetRecords() API record参数返回值不应为null"); lTotalCount = result.Value; if (nStart == 0 && stop != null) stop.SetProgressRange(0, lTotalCount); } if (records != null) { nCount += records.Length; } listView.BeginUpdate(); try { // 做事 for (int i = 0; i < records.Length; i++) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; return -1; } stop.SetMessage("正在装入 " + Convert.ToString(nStart + i) + " / " + ((lTotalCount == -1) ? "?" : Convert.ToString(lTotalCount))); } Record record = records[i]; string[] cols = null; if (bOutputKeyID == true) { cols = new string[(record.Cols == null ? 0 : record.Cols.Length) + 1]; cols[0] = BuildDisplayKeyString(record.Keys); if (cols.Length > 1) Array.Copy(record.Cols, 0, cols, 1, cols.Length - 1); } else cols = record.Cols; listView.NewLine(record.Path + " @" + this.Url, cols); // record.ID 放入第一列 // record.Cols 放入其他列(如果为keyid方式,key在这一群的第一列) } if (stop != null) stop.SetProgressValue(nStart + records.Length); } finally { listView.EndUpdate(); } if (nCount >= result.Value) break; if (records != null) { nStart += records.Length; } } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; // 2013/2/11 if (this.ErrorCode == ChannelErrorCode.QuotaExceeded) { if (nPerCount > 1 || nPerCount == -1) nPerCount = 1; // 修改为最小数量重做一次 else return -1; } goto REDO; } } this.ClearRedoCount(); if (stop != null) stop.HideProgress(); return 0; }
// 获得浏览格式记录 // parameter: // nStart 起始序号 // nLength 长度 public int GetRichRecords( string strResultSetName, long nStart, long nLength, string strStyle, string strLang, out List<RichRecord> aRecord, out string strError) { strError = ""; aRecord = new List<RichRecord>(); long nPerCount = nLength; int nCount = 0; long lTotalCount = nLength; for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 try { string strRange = nStart.ToString() + "-" + (nStart + nPerCount - 1).ToString(); IAsyncResult soapresult = this.ws.BeginGetRichRecords( strResultSetName, strRange, strLang, strStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } RichRecord[] records = null; Result result = this.ws.EndGetRichRecords( out records, soapresult); if (result.Value == -1) { strError = result.ErrorString; return -1; } else { if (records == null) throw new Exception("WebService GetRichRecords() API record参数返回值不应为null"); //lTotalCount = result.Value; } // 做事 for (int i = 0; i < records.Length; i++) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 RichRecord record = records[i]; aRecord.Add(record); nStart++; nCount++; if (lTotalCount != -1 && nCount >= lTotalCount) break; } nPerCount -= records.Length; if (nPerCount <= 0) break; if (lTotalCount != -1 && nCount >= lTotalCount) break; if (nCount >= result.Value) break; } catch (Exception ex) { strError = ExceptionUtil.GetAutoText(ex); return -1; } } // end of for return 0; }
// 获得浏览格式记录 // parameter: // nStart 起始序号 // nLength 长度 public int GetRecords( string strResultSetName, long nStart, long nLength, string strLang, out ArrayList aRecord, out string strError) { strError = ""; aRecord = new ArrayList(); long nPerCount = -1; // BUG? 这里有一点问题,可能获取过多的记录,超过nLength int nCount = 0; long lTotalCount = nLength; for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 try { IAsyncResult soapresult = this.ws.BeginGetRecords( strResultSetName, nStart, nPerCount, strLang, "id,cols", null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Record[] records = null; Result result = this.ws.EndGetRecords( out records, soapresult); if (result.Value == -1) { strError = result.ErrorString; return -1; } else { if (records == null) throw new Exception("WebService GetRecords() API record参数返回值不应为null"); //lTotalCount = result.Value; } // 做事 for (int i = 0; i < records.Length; i++) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 Record record = records[i]; // 换成自己的类型,包含一个在结果集的序号 dp2opacRecord opacRecord = new dp2opacRecord(); opacRecord.Record = record; opacRecord.IndexOfResult = nStart; aRecord.Add(opacRecord); nStart++; nCount++; if (lTotalCount != -1 && nCount >= lTotalCount) break; } if (lTotalCount != -1 && nCount >= lTotalCount) break; if (nCount >= result.Value) break; } catch (Exception ex) { strError = ExceptionUtil.GetAutoText(ex); return -1; } } // end of for return 0; }
public static string ToSerialString(this ErrorCodeValue value) => value switch {
// 模拟创建检索点 public long DoGetKeys( string strRecPath, string strXmlBody, string strLang, // string strStyle, ViewAccessPointForm dlg, DigitalPlatform.Stop stop, out string strError) { strError = ""; if (strRecPath == "") { strError = "记录路径为空时无法模拟创建检索点"; return -1; } KeyInfo[] keys = null; int nStart = 0; int nPerCount = -1; int nCount = 0; dlg.Clear(); long lTotalCount = -1; for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; return -1; } } REDO: try { IAsyncResult soapresult = this.ws.BeginCreateKeys( strXmlBody, strRecPath, nStart, nPerCount, strLang, // strStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndCreateKeys( out keys, soapresult); if (result.Value == -1) { // 2011/4/21 if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } else { Debug.Assert(keys != null, "WebService GetRecords() API record参数返回值不应为null"); lTotalCount = result.Value; } if (keys != null) { nStart += keys.Length; nCount += keys.Length; } // 做事 for (int i = 0; i < keys.Length; i++) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; return -1; } stop.SetMessage("正在装入 " + Convert.ToString(nStart + i) + " / " + ((lTotalCount == -1) ? "?" : Convert.ToString(lTotalCount))); } KeyInfo keyInfo = keys[i]; dlg.NewLine(keyInfo); } if (nCount >= result.Value) break; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } } this.ClearRedoCount(); return 0; }
// 根据指定的记录路径获得浏览格式记录 // parameter: // aRecord 返回的浏览记录信息。一个ArrayList数组。每个元素为一个string[],所包含的内容 // 根据strStyle而定。如果strStyle中有id,则aRecord每个元素中的string[]第一个字符串就是id,后面是各列内容。 public int GetBrowseRecords(string[] paths, string strStyle, out ArrayList aRecord, out string strError) { strError = ""; aRecord = new ArrayList(); int nStart = 0; bool bIncludeID = StringUtil.IsInList("id", strStyle, true); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 try { int nPerCount = paths.Length - nStart; string[] temppaths = new string[nPerCount]; Array.Copy(paths, nStart, temppaths, 0, nPerCount); IAsyncResult soapresult = this.ws.BeginGetBrowse( temppaths, strStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Record[] records = null; Result result = this.ws.EndGetBrowse( out records, soapresult); if (result.Value == -1) { strError = result.ErrorString; return -1; } else { if (records == null) throw new Exception("WebService GetBrowse() API record参数返回值不应为null"); //lTotalCount = result.Value; } // 做事 for (int i = 0; i < records.Length; i++) { Record record = records[i]; if (bIncludeID == true) { string[] cols = new string[record.Cols.Length + (bIncludeID == true ? 1 : 0)]; if (bIncludeID) cols[0] = record.Path; if (record.Cols.Length > 0) Array.Copy(record.Cols, 0, cols, (bIncludeID == true ? 1 : 0), record.Cols.Length); aRecord.Add(cols); } else { aRecord.Add(record.Cols); } } nStart += records.Length; if (nStart >= paths.Length) break; } catch (Exception ex) { strError = ExceptionUtil.GetAutoText(ex); return -1; } } // end of for return 0; }
// 列资源目录 public long DoDir(string strPath, string strLang, string strStyle, out ResInfoItem[] results, out string strError) { strError = ""; results = null; ResInfoItem[] items = null; int nStart = 0; int nPerCount = -1; int nCount = 0; ArrayList aItem = new ArrayList(); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 REDO: try { REDODIR: IAsyncResult soapresult = this.ws.BeginDir(strPath, nStart, nPerCount, strLang, strStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndDir( out items, soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDODIR; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } if (items != null) { nStart += items.Length; nCount += items.Length; } // 做事 for (int i = 0; i < items.Length; i++) { aItem.Add(items[i]); } if (nCount >= result.Value) break; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } } // end of for results = new ResInfoItem[aItem.Count]; for (int i = 0; i < results.Length; i++) { results[i] = (ResInfoItem)aItem[i]; } this.ClearRedoCount(); return 0; }
// 保存资源记录 // parameters: // strPath 格式: 库名/记录号/object/对象xpath // strRange 本次想发送给服务器的局部。本函数将把这部分内容复制到内存byte[]结构中, // 因此,调用者必须考虑用合适的尺寸,避免超过内存极限引起进程被杀死。 // bTailHint 是否为最后一次写入操作。这是一个暗示参数,本函数将根据此参数为最后一次写入操作设置特殊的超时时间。 // 假定有时整个资源尺寸很大,虽然每次局部写入耗时不多,但是最后一次写入因为服务器要执行整个资源转存 // 的操作后API才返回,所以可能会耗费类似20分钟这样的长时间,导致WebService API超时失败。 // 本参数是一个暗示操作(本函数也不担保一定要做什么操作),如果调用者不清楚它的含义,可以使用false。 public long DoSaveResObject(string strPath, Stream file, long lTotalLength, string strStyle, // 2005/11/4 string strMetadata, string strRange, bool bTailHint, byte[] timestamp, out byte[] output_timestamp, out string strOutputPath, out string strError) { //string strLocalPath, // 该参数代表本地文件名,有时会与strObjectFileName不同 //string strMime; this.ErrorCode = ChannelErrorCode.None; strError = ""; output_timestamp = null; strOutputPath = ""; byte[] baTotal = null; if (file != null) { if (file.Position + lTotalLength > file.Length) { strError = "文件从当前位置 " + Convert.ToString(file.Position) + " 开始到末尾长度不足 " + Convert.ToString(lTotalLength); return -1; } long lRet = RangeList.CopyFragment( file, lTotalLength, strRange, out baTotal, out strError); if (lRet == -1) return -1; } else { baTotal = new byte[0]; // 这是一个缺憾。应当许可为null } // int nOldTimeout = -1; if (bTailHint == true) { /* nOldTimeout = this.Timeout; this.Timeout = 20 * 60 * 1000; * */ } REDO: try { REDOSAVE: // string strMetadata = "<file mimetype='"+strMime+"' localpath='" + strLocalPath + "'/>"; IAsyncResult soapresult = this.ws.BeginWriteRes(strPath, strRange, lTotalLength, // 这是整个包尺寸,不是本次chunk的尺寸。因为服务器显然可以从baChunk中看出其尺寸,不必再专门用一个参数表示这个尺寸了 baTotal, // null, // attachmentid strMetadata, strStyle, // style timestamp, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndWriteRes( out strOutputPath, out output_timestamp, soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDOSAVE; } ConvertErrorCode(result); strError = result.ErrorString; if (result.ErrorCode == ErrorCodeValue.TimestampMismatch) { this.ErrorCode = ChannelErrorCode.TimestampMismatch; // output_timestamp 在出错情况下,也会返回服务器端希望的时间戳 strError = "时间戳不匹配。\r\n\r\n请求的时间戳 [" + ByteArray.GetHexTimeStampString(timestamp) + "] 响应的时间戳 [" + ByteArray.GetHexTimeStampString(output_timestamp) + "]"; return -1; } // 原来在这里,稍晚 return -1; } } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } finally { /* if (bTailHint == true) this.Timeout = nOldTimeout; * */ } this.ClearRedoCount(); return 0; }
// 写入资源。原始版本。2007/5/27 public long WriteRes(string strResPath, string strRanges, long lTotalLength, byte[] baContent, string strMetadata, string strStyle, byte[] baInputTimestamp, out string strOutputResPath, out byte[] baOutputTimestamp, out string strError) { this.ErrorInfo = ""; strError = ""; strOutputResPath = ""; baOutputTimestamp = null; REDO: try { REDOSAVE: IAsyncResult soapresult = this.ws.BeginWriteRes(strResPath, strRanges, lTotalLength, baContent, // null, // attachmentid strMetadata, strStyle, baInputTimestamp, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndWriteRes( out strOutputResPath, out baOutputTimestamp, soapresult); this.ErrorInfo = result.ErrorString; // 无论是否返回错误,都将result的ErrorString放到Channel中 if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strResPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDOSAVE; } ConvertErrorCode(result); strError = result.ErrorString; if (result.ErrorCode == ErrorCodeValue.TimestampMismatch) { this.ErrorCode = ChannelErrorCode.TimestampMismatch; strError = "时间戳不匹配。\r\n\r\n请求的时间戳 [" + ByteArray.GetHexTimeStampString(baInputTimestamp) + "] 响应的时间戳 [" + ByteArray.GetHexTimeStampString(baOutputTimestamp) + "]"; return -1; } // 原来Convert....在这里,稍晚 return -1; } this.ClearRedoCount(); return result.Value; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
// 登录 // return: // -1 出错。错误信息在strError中 // 0 登录失败。错误信息也在strError // 1 登录成功 public int Login(string strUserName, string strPassword, out string strError) { strError = ""; REDO: try { IAsyncResult soapresult = this.ws.BeginLogin(strUserName, strPassword, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndLogin(soapresult); if (result.Value == -1) { ConvertErrorCode(result); strError = result.ErrorString; return -1; } if (result.Value == 0) { strError = result.ErrorString; return 0; } this.ClearRedoCount(); return 1; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
// 检索 // return: // -1 error // 0 not found // >=1 命中记录条数 public long DoSearchWithoutLoginDlg( string strQueryXml, string strResultSetName, string strOutputStyle, out string strError) { strError = ""; REDO: this.BeginSearch(); try { //REDOSEARCH: IAsyncResult soapresult = this.ws.BeginSearch( strQueryXml, strResultSetName, strOutputStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndSearch(soapresult); if (result.Value == -1) { ConvertErrorCode(result); strError = result.ErrorString; return -1; } this.ClearRedoCount(); return result.Value; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } finally { this.EndSearch(); } }
// ( 扩展功能后的)检索 // parameters: // strQuery XML检索式 // strResultSetName 结果集名 // strSearchStyle 检索风格 // lRecordCount 希望获得的记录数量。-1表示尽可能多。如果为0,表示不想获得任何记录 // 总是从偏移量0开始获得记录 // strRecordStyle 获得记录的风格。以逗号分隔,id表示取id,cols表示取浏览格式 // xml timestamp metadata 分别表示要获取的记录体的XML字符串、时间戳、元数据 // return: // -1 error // 0 not found // >=1 命中记录条数 public long DoSearchEx(string strQueryXml, string strResultSetName, string strSearchStyle, long lRecordCount, string strLang, string strRecordStyle, out Record[] records, out string strError) { strError = ""; records = null; REDO: this.BeginSearch(); try { REDOSEARCH: IAsyncResult soapresult = this.ws.BeginSearchEx( strQueryXml, strResultSetName, strSearchStyle, lRecordCount, strLang, strRecordStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndSearchEx( out records, soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDOSEARCH; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } this.ClearRedoCount(); return result.Value; } catch (Exception ex) { int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } finally { this.EndSearch(); } }
// 刷新数据库记录keys // parameters: // strStyle next prev outputpath forcedeleteoldkeys // forcedeleteoldkeys 要在创建新keys前强制删除一下旧有的keys? 如果为包含,则强制删除原有的keys;如果为不包含,则试探着创建新的keys,如果有旧的keys和新打算创建的keys重合,那就不重复创建;如果旧的keys有残余没有被删除,也不管它们了 // 包含 一般用在单条记录的处理;不包含 一般用在预先删除了所有keys表的内容行以后在循环重建库中每条记录的批处理方式 public long DoRebuildResKeys(string strPath, string strStyle, out string strOutputResPath, out string strError) { strError = ""; strOutputResPath = ""; /* int nOldTimeout = this.Timeout; this.Timeout = 20 * 60 * 1000; */ REDO: try { IAsyncResult soapresult = this.ws.BeginRebuildResKeys(strPath, strStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndRebuildResKeys( out strOutputResPath, soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; /* if (result.ErrorCode == ErrorCodeValue.TimestampMismatch) { this.ErrorCode = ChannelErrorCode.TimestampMismatch; Debug.Assert(output_timestamp != null, "WebService API RebuildResKeys() TimestampMismatch时必须返回旧时间戳 ..."); strError = "时间戳不匹配。\r\n\r\n请求的时间戳 [" + ByteArray.GetHexTimeStampString(timestamp) + "] 响应的时间戳 [" + ByteArray.GetHexTimeStampString(output_timestamp) + "]"; return -1; }*/ // 原来在这里,稍晚 return -1; } } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } finally { // this.Timeout = nOldTimeout; } this.ClearRedoCount(); return 0; }
// 批处理任务 // return: // -1 出错。错误信息在strError中 // 0或者其他 成功 public int DoBatchTask(string strName, string strAction, TaskInfo info, out TaskInfo[] results, out string strError) { results = null; strError = ""; REDO: try { IAsyncResult soapresult = this.ws.BeginBatchTask(strName, strAction, info, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndBatchTask( out results, soapresult); if (result.Value == -1) { // 2011/4/21 if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } this.ClearRedoCount(); if (result.Value == 0) { strError = result.ErrorString; return 0; } return 0; } catch (Exception ex) { int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
// return: // 0 主流程需返回-1 // 1 需要重做API int ConvertWebError(Exception ex0, out string strError) { this.WcfException = ex0; // System.TimeoutException if (ex0 is System.TimeoutException) { this.ErrorCode = ErrorCodeValue.RequestTimeOut; this.AbortIt(); strError = GetExceptionMessage(ex0); return 0; } if (ex0 is System.ServiceModel.Security.MessageSecurityException) { System.ServiceModel.Security.MessageSecurityException ex = (System.ServiceModel.Security.MessageSecurityException)ex0; this.ErrorCode = ErrorCodeValue.RequestError; // 一般错误 this.AbortIt(); // return ex.Message + (ex.InnerException != null ? " InnerException: " + ex.InnerException.Message : "") ; strError = GetExceptionMessage(ex); if (this.m_nRedoCount == 0) { this.m_nRedoCount++; return 1; // 重做 } return 0; } if (ex0 is CommunicationObjectFaultedException) { CommunicationObjectFaultedException ex = (CommunicationObjectFaultedException)ex0; this.ErrorCode = ErrorCodeValue.RequestError; // 一般错误 this.AbortIt(); strError = GetExceptionMessage(ex); // 2011/7/2 if (this.m_nRedoCount == 0) { this.m_nRedoCount++; return 1; // 重做 } return 0; } if (ex0 is EndpointNotFoundException) { EndpointNotFoundException ex = (EndpointNotFoundException)ex0; this.ErrorCode = ErrorCodeValue.RequestError; // 一般错误 this.AbortIt(); strError = "服务器 " + this.Url + " 没有响应"; return 0; } if (ex0 is System.ServiceModel.CommunicationException && ex0.InnerException is System.ServiceModel.QuotaExceededException) { this.ErrorCode = ErrorCodeValue.RequestError; // 一般错误 this.MaxReceivedMessageSize *= 2; // 下次扩大一倍 this.AbortIt(); strError = GetExceptionMessage(ex0); if (this.m_nRedoCount == 0 && this.MaxReceivedMessageSize < 1024 * 1024 * 10) { this.m_nRedoCount++; return 1; // 重做 } return 0; } this.ErrorCode = ErrorCodeValue.RequestError; // 一般错误 if (this.m_ws != null) { this.AbortIt(); // 一般来说异常都需要重新分配Client()。如果有例外,可以在前面分支 } strError = GetExceptionMessage(ex0); return 0; }
// 复制记录 // return: // -1 出错。错误信息在strError中 // 0或者其他 成功 public int DoCopyRecord(string strOriginRecordPath, string strTargetRecordPath, bool bDeleteOriginRecord, string strMergeStyle, out string strIdChangeList, out byte[] baOutputTimeStamp, out string strOutputPath, out string strError) { strIdChangeList = ""; baOutputTimeStamp = null; strOutputPath = ""; strError = ""; REDO: try { IAsyncResult soapresult = this.ws.BeginCopyRecord(strOriginRecordPath, strTargetRecordPath, bDeleteOriginRecord, strMergeStyle, null, null); for (; ; ) { /* try { Application.DoEvents(); // 出让界面控制权 } catch { } // System.Threading.Thread.Sleep(10); // 避免CPU资源过度耗费 */ DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndCopyRecord( out strIdChangeList, out strOutputPath, out baOutputTimeStamp, soapresult); if (result.Value == -1) { // 2011/4/21 if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } this.ClearRedoCount(); if (result.Value == 0) { strError = result.ErrorString; return 0; } return 0; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }
// 获得资源。原始版本。2007/5/27 // -1 出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。 // 0 成功 public long GetRes(string strResPath, long lStart, int nLength, string strStyle, out byte[] baContent, out string strMetadata, out string strOutputResPath, out byte[] baOutputTimestamp, out string strError) { baContent = null; strMetadata = ""; strError = ""; strOutputResPath = ""; baOutputTimestamp = null; // string strID = ""; this.ErrorCode = ChannelErrorCode.None; this.ErrorInfo = ""; REDO: try { // string strStyle = "content,data"; IAsyncResult soapresult = this.ws.BeginGetRes(strResPath, lStart, nLength, strStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndGetRes( out baContent, // out strID, out strMetadata, out strOutputResPath, out baOutputTimestamp, soapresult); // 即便不是返回-1,也可能有错误码和错误信息字符串 ConvertErrorCode(result); strError = result.ErrorString; if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strResPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } return -1; } this.ClearRedoCount(); return result.Value; } // end try catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } // return 0; }
internal static TextAnalyticsError DeserializeTextAnalyticsError(JsonElement element) { ErrorCodeValue code = default; string message = default; string target = default; InnerError innerError = default; IReadOnlyList <TextAnalyticsError> details = default; foreach (var property in element.EnumerateObject()) { if (property.NameEquals("code")) { code = property.Value.GetString().ToErrorCodeValue(); continue; } if (property.NameEquals("message")) { message = property.Value.GetString(); continue; } if (property.NameEquals("target")) { if (property.Value.ValueKind == JsonValueKind.Null) { continue; } target = property.Value.GetString(); continue; } if (property.NameEquals("innerError")) { if (property.Value.ValueKind == JsonValueKind.Null) { continue; } innerError = InnerError.DeserializeInnerError(property.Value); continue; } if (property.NameEquals("details")) { if (property.Value.ValueKind == JsonValueKind.Null) { continue; } List <TextAnalyticsError> array = new List <TextAnalyticsError>(); foreach (var item in property.Value.EnumerateArray()) { if (item.ValueKind == JsonValueKind.Null) { array.Add(null); } else { array.Add(DeserializeTextAnalyticsError(item)); } } details = array; continue; } } return(new TextAnalyticsError(code, message, target, innerError, details)); }
// 获得资源。返回字符串版本。适用于获得主记录体。 // return: // -1 出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。 // 0 成功 public long GetRes(string strPath, string strStyle, out string strResult, out string strMetaData, out byte[] baOutputTimeStamp, out string strOutputResPath, out string strError) { strMetaData = ""; strResult = ""; strError = ""; strOutputResPath = ""; baOutputTimeStamp = null; this.ErrorCode = ChannelErrorCode.None; this.ErrorInfo = ""; // string id = ""; byte[] baContent = null; long lStart = 0; int nPerLength = -1; byte[] baTotal = null; // 2012/3/28 // List<byte> bytes = new List<byte>(); if (StringUtil.IsInList("attachmentid", strStyle) == true) { strError = "目前不支持 attachmentid"; return -1; } for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 REDO: try { // string strStyle = "content,data"; IAsyncResult soapresult = this.ws.BeginGetRes(strPath, lStart, nPerLength, strStyle, null, null); for (; ; ) { /* try { Application.DoEvents(); // 出让界面控制权 } catch { } // System.Threading.Thread.Sleep(10); // 避免CPU资源过度耗费 */ DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } // string strMetadata; // string strOutputResPath; Result result = this.ws.EndGetRes( out baContent, // out id, out strMetaData, out strOutputResPath, out baOutputTimeStamp, soapresult); // 即便不是返回-1,也可能有错误码和错误信息字符串 ConvertErrorCode(result); strError = result.ErrorString; if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } /* ConvertErrorCode(result); strError = result.ErrorString; */ return -1; } if (StringUtil.IsInList("data", strStyle) != true) break; baTotal = ByteArray.Add(baTotal, baContent); // bytes.AddRange(baContent); Debug.Assert(baContent.Length <= result.Value, "每次返回的包尺寸[" + Convert.ToString(baContent.Length) + "]应当小于result.Value[" + Convert.ToString(result.Value) + "]"); lStart += baContent.Length; if (lStart >= result.Value) break; // 结束 baContent = null; } // end try catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } } // end of for this.ClearRedoCount(); if (StringUtil.IsInList("data", strStyle) != true) return 0; #if NO byte [] baTemp = new byte[bytes.Count]; bytes.CopyTo(baTemp); strResult = Encoding.UTF8.GetString(baTemp); #endif // 转换成字符串 strResult = ByteArray.ToString(baTotal/*, Encoding.UTF8*/ ); // 将来做自动识别编码方式 return 0; }
// 2008/11/14 // 刷新数据库定义 // return: // -1 出错 // 0 成功(基于WebService接口InitializeDb的返回值) public long DoRefreshDB( string strAction, string strDBName, bool bClearAllKeyTables, out string strError) { strError = ""; /* int nOldTimeout = this.Timeout; this.Timeout = 20 * 60 * 1000; // 加大超时时间 * */ REDO: try { REDO_REFRESH: IAsyncResult soapresult = this.ws.BeginRefreshDb( strAction, strDBName, bClearAllKeyTables, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndRefreshDb(soapresult); if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strDBName, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO_REFRESH; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } this.ClearRedoCount(); return result.Value; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } finally { // this.Timeout = nOldTimeout; } }
// 获得资源。写入文件的版本。特别适用于获得资源,也可用于获得主记录体。 // parameters: // fileTarget 文件。注意在调用函数前适当设置文件指针位置。函数只会在当前位置开始向后写,写入前不会主动改变文件指针。 // strStyleParam 一般设置为"content,data,metadata,timestamp,outputpath"; // input_timestamp 若!=null,则本函数会把第一个返回的timestamp和本参数内容比较,如果不相等,则报错 // return: // -1 出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。 // 0 成功 public long GetRes(string strPath, Stream fileTarget, FlushOutput flushOutputMethod, DigitalPlatform.Stop stop, string strStyleParam, byte[] input_timestamp, out string strMetaData, out byte[] baOutputTimeStamp, out string strOutputPath, out string strError) { strError = ""; baOutputTimeStamp = null; strMetaData = ""; strOutputPath = ""; this.ErrorCode = ChannelErrorCode.None; this.ErrorInfo = ""; string strStyle = strStyleParam; if (StringUtil.IsInList("attachment", strStyle) == true) { Debug.Assert(false, "attachment style暂时不能使用"); } // 检查参数 if (StringUtil.IsInList("data", strStyle) == false) { if (fileTarget != null) { strError = "strStyle参数中若不包含data风格,则无法获得数据..."; return -1; } } if (StringUtil.IsInList("data", strStyle) == true) { if (fileTarget == null) { strError = "strStyle参数中若包含data风格,而fileTarget为null,会浪费通讯资源..."; return -1; } } bool bHasMetadataStyle = false; if (StringUtil.IsInList("metadata", strStyle) == true) { bHasMetadataStyle = true; } // string id = ""; byte[] baContent = null; long lStart = 0; int nPerLength = -1; byte[] old_timestamp = null; byte[] timestamp = null; long lTotalLength = -1; for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 if (stop != null && stop.State != 0) { strError = "用户中断"; return -1; } REDO: try { string strMessage = ""; string strPercent = ""; if (lTotalLength != -1) { double ratio = (double)lStart / (double)lTotalLength; strPercent = String.Format("{0,3:N}", ratio * (double)100) + "%"; } if (stop != null) { strMessage = "正在下载 " + Convert.ToString(lStart) + "-" + (lTotalLength == -1 ? "?" : Convert.ToString(lTotalLength)) + " " + strPercent + " " + strPath; stop.SetMessage(strMessage); } IAsyncResult soapresult = this.ws.BeginGetRes(strPath, fileTarget == null ? 0 : lStart, fileTarget == null ? 0 : nPerLength, strStyle, null, null); for (; ; ) { /* try { Application.DoEvents(); // 出让界面控制权 } catch { } // System.Threading.Thread.Sleep(10); // 避免CPU资源过度耗费 */ DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } // string strOutputResPath; Result result = this.ws.EndGetRes( out baContent, // out id, out strMetaData, out strOutputPath, out timestamp, soapresult); // 即便不是返回-1,也可能有错误码和错误信息字符串 ConvertErrorCode(result); strError = result.ErrorString; if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } /* ConvertErrorCode(result); strError = result.ErrorString; */ return -1; } if (bHasMetadataStyle == true) { StringUtil.RemoveFromInList("metadata", true, ref strStyle); bHasMetadataStyle = false; } lTotalLength = result.Value; if (StringUtil.IsInList("timestamp", strStyle) == true /* && lTotalLength > 0 * */ ) // 2012/1/11 { if (input_timestamp != null) { if (ByteArray.Compare(input_timestamp, timestamp) != 0) { strError = "下载过程中发现时间戳和input_timestamp参数中的时间戳不一致,下载失败 ..."; return -1; } } if (old_timestamp != null) { if (ByteArray.Compare(old_timestamp, timestamp) != 0) { strError = "下载过程中发现时间戳变化,下载失败 ..."; return -1; } } } old_timestamp = timestamp; if (fileTarget == null) break; // 写入文件 if (StringUtil.IsInList("attachment", strStyle) == true) { Debug.Assert(false, "attachment style暂时不能使用"); /* Attachment attachment = ws.ResponseSoapContext.Attachments[id]; if (attachment == null) { strError = "id为 '" +id+ "' 的attachment在WebService响应中没有找到..."; return -1; } StreamUtil.DumpStream(attachment.Stream, fileTarget); nStart += (int)attachment.Stream.Length; Debug.Assert(attachment.Stream.Length <= result.Value, "每次返回的包尺寸["+Convert.ToString(attachment.Stream.Length)+"]应当小于result.Value["+Convert.ToString(result.Value)+"]"); */ } else { Debug.Assert(StringUtil.IsInList("content", strStyle) == true, "不是attachment风格,就应是content风格"); Debug.Assert(baContent != null, "返回的baContent不能为null"); Debug.Assert(baContent.Length <= result.Value, "每次返回的包尺寸[" + Convert.ToString(baContent.Length) + "]应当小于result.Value[" + Convert.ToString(result.Value) + "]"); fileTarget.Write(baContent, 0, baContent.Length); if (flushOutputMethod != null) { if (flushOutputMethod() == false) { strError = "FlushOutputMethod()用户中断"; return -1; } } lStart += baContent.Length; } if (lStart >= result.Value) break; // 结束 } // end try catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } } // end of for baOutputTimeStamp = timestamp; this.ClearRedoCount(); return 0; }
// 保存Xml记录 public long DoSaveTextRes(string strPath, string strXml, bool bInlucdePreamble, string strStyle, byte[] timestamp, out byte[] output_timestamp, out string strOutputPath, out string strError) { this.ErrorInfo = ""; strError = ""; strOutputPath = ""; output_timestamp = null; int nDoCount = 0; int nChunkMaxLength = 500 * 1024; // chunk size。为了提升速度,应该尽量大。 原来是 4096 int nStart = 0; byte[] baInputTimeStamp = null; //byte[] baOutputTimeStamp = null; output_timestamp = null; byte[] baPreamble = Encoding.UTF8.GetPreamble(); byte[] baTotal = Encoding.UTF8.GetBytes(strXml); if (bInlucdePreamble == true && baPreamble != null && baPreamble.Length > 0) { byte[] temp = null; temp = ByteArray.Add(temp, baPreamble); baTotal = ByteArray.Add(temp, baTotal); } long lTotalLength = baTotal.Length; if (timestamp != null) { baInputTimeStamp = ByteArray.Add(baInputTimeStamp, timestamp); } for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 // 切出chunk int nThisChunkSize = nChunkMaxLength; if (nThisChunkSize + nStart > lTotalLength) { nThisChunkSize = (int)lTotalLength - nStart; // 最后一次 if (nThisChunkSize <= 0 && nDoCount > 1) break; } byte[] baChunk = new byte[nThisChunkSize]; Array.Copy(baTotal, nStart, baChunk, 0, baChunk.Length); REDO: try { REDOSAVE: string strMetadata = ""; string strRange = ""; int nEnd = nStart + baChunk.Length - 1; // 2008/10/17 changed if (nEnd >= nStart) strRange = Convert.ToString(nStart) + "-" + Convert.ToString(nEnd); IAsyncResult soapresult = this.ws.BeginWriteRes(strPath, strRange, //nStart, lTotalLength, // 这是整个包尺寸,不是本次chunk的尺寸。因为服务器显然可以从baChunk中看出其尺寸,不必再专门用一个参数表示这个尺寸了 baChunk, // null, // attachmentid strMetadata, strStyle, baInputTimeStamp, null, null); nDoCount++; for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Result result = this.ws.EndWriteRes( out strOutputPath, out output_timestamp/*baOutputTimeStamp*/, soapresult); this.ErrorInfo = result.ErrorString; // 无论是否返回错误,都将result的ErrorString放到Channel中 strError = result.ErrorString; // 2007/6/28 服务于 带有局部path的保存中返回值放在strError的情况 if (result.Value == -1) { if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin(strPath, out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDOSAVE; } ConvertErrorCode(result); // strError = result.ErrorString; if (result.ErrorCode == ErrorCodeValue.TimestampMismatch) { this.ErrorCode = ChannelErrorCode.TimestampMismatch; strError = "时间戳不匹配。\r\n\r\n请求的时间戳 [" + ByteArray.GetHexTimeStampString(baInputTimeStamp) + "] 响应的时间戳 [" + ByteArray.GetHexTimeStampString(output_timestamp/*baOutputTimeStamp*/) + "]"; return -1; } // 原来Convert....在这里,稍晚 return -1; } nStart += baChunk.Length; if (nStart >= lTotalLength) break; Debug.Assert(strOutputPath != "", "outputpath不能为空"); strPath = strOutputPath; // 如果第一次的strPath中包含'?'id, 必须用outputpath才能正确继续 baInputTimeStamp = output_timestamp; //baOutputTimeStamp; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } } // end of for // output_timestamp = baOutputTimeStamp; this.ClearRedoCount(); return 0; }
// 2009/11/6 // 根据指定的记录路径获得浏览格式记录 // 浅包装版本 // parameter: public long GetBrowseRecords(string[] paths, string strStyle, out Record[] searchresults, out string strError) { strError = ""; searchresults = null; REDO: try { IAsyncResult soapresult = this.ws.BeginGetBrowse( paths, strStyle, null, null); for (; ; ) { DoIdle(); // 出让控制权,避免CPU资源耗费过度 bool bRet = soapresult.AsyncWaitHandle.WaitOne(100, false); if (bRet == true) break; } if (this.m_ws == null) { strError = "用户中断"; this.ErrorCode = ChannelErrorCode.RequestCanceled; return -1; } Record[] records = null; Result result = this.ws.EndGetBrowse( out records, soapresult); if (result.Value == -1) { // 2011/4/21 if (result.ErrorCode == ErrorCodeValue.NotLogin && this.Container != null) { // return: // -1 error // 0 login failed // 1 login succeed int nRet = this.UiLogin("", out strError); if (nRet == -1 || nRet == 0) { return -1; } goto REDO; } ConvertErrorCode(result); strError = result.ErrorString; return -1; } else { if (records == null) throw new Exception("WebService GetBrowse() API record参数返回值不应为null"); //lTotalCount = result.Value; } // 将结果移出 searchresults = new Record[records.Length]; // SearchResult for (int i = 0; i < records.Length; i++) { searchresults[i] = records[i]; /* SearchResult searchresult = new SearchResult(); searchresults[i] = searchresult; Record record = records[i]; searchresult.Path = record.ID; searchresult.Keys = record.Keys; searchresult.Cols = record.Cols; * */ } this.ClearRedoCount(); return result.Value; } catch (Exception ex) { /* strError = ConvertWebError(ex); return -1; * */ int nRet = ConvertWebError(ex, out strError); if (nRet == 0) return -1; goto REDO; } }