Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WCF, Web Services, Remoting Новый топик    Ответить
 Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
Доброе время суток, господа форумчане.

Ситуация. Делаю синхронизацию между двумя Exchange Server 2010 SP1, расположенными в двух различных доменах (назовем их внутренним и внешним доменами). Письма, календари, контакты переносятся с одного сервера на другой. Функционал реализуется при помощи EWS Managed API и частично собственно EWS.

Проблема. При переносе писем при помощи методов UploadItems/ExportItems адреса в письмах при экспорте преобразуются из SMTP-маршрутизации в EX-маршрутизацию. Поэтому, после загрузки на внешний сервер письма из внутреннего, я не могу ответить на него из внешнего домена. Точнее могу, но сразу получаю отлуп, так как в письме в качестве отправителя указан эккаунт внутреннего домена, который во внешнем домене, естественно, не обнаруживается.
Я изменил способ экспорта/импорта писем. При экспорте в файл записывается MimeContent письма, а при импорте создается новый объект EmailMessage, который инициализируется прочитанным из файла MimeContent-ом. После сохранения все адреса остаются SMTP-шными, и можно ответить на письмо из внешнего домена. Но теперь другая проблема. Видимо, из-за того, что я создавал новый объект EmailMessage письмо в интерфейсе OWA, например, помечено как неотправленное.

Поиск в гугл по "email message unsent flag" и т.п. ни к чему не привел.

Вопрос. Что необходимо сделать с новым элементом типа EmailMessage чтобы никто не считал, что его необходимо отправить?

P.S. Спешу задать вопрос, а сам уезжаю на дачу, так что прошу извинить, за то, что, скорее всего, до пнд ответить не смогу.
22 авг 13, 14:12    [14741729]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
Вот и вернулся с дачи, а ответа нет. Жаль.
Да и форумов по эксу не нашел.
26 авг 13, 21:23    [14757710]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
AlexeiK
Member

Откуда:
Сообщений: 2840
vagner,

врядли при такой подаче, тебе ктото ответит.
слишком ты ленивый.
27 авг 13, 12:14    [14759695]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
AlexeiK, думаешь проблема в моей лени? Интересно как ты определил, что я ленивый, и даже слишком.
На самом деле все гораздо проще - просто никто не знает ответа.

Так вот проблема решена. Среди расширенных свойств EmailMessage нашлось свойство PidTagMessageFlags, в котором нашелся флажок mfUnsent. Только предупреждаю сразу устанавливать его надо сразу, до первого сохранения элемента, потом он становится ReadOnly.

Теперь следующая проблема - события календаря. Как я уже писал был изменен способ экспорта/импорта с методов UploadItems/ExportItems на работу через MimeContent (в дальнейшем буду называть их первым и вторым вариантом). Если создать просто событие календаря без участников, все прекрасно как в первом так и во втором варианте. Проблемы начинаются, когда некий сторонний ПЯ создает событие календаря и приглашает в него синхронизируемого абонента. При работе по первому варианту - элемент синхронизируется один-в-один, и во внешнем домене событие календаря выглядит точно так же как и во внутреннем, пользователю предлагается возможность подтвердить свое участите в событии. Но, как я уже писал выше, при экспорте произошла подмена типа маршрутизации с smtp-шной на exchange-маршрутизациюю И подтверждение на участие отправленное из внешнего домена никуда не доходит. Во втором варианте (работа через MimeContent) событие во внешнем домене выглядит не так как во внутреннем: нет инициатора события и не предлагается подтвердить в нем свое участие. Видимо, при загрузке через MimeContent, происходит парсинг контента, в процессе которого проверяются все участники события и те участники, которые не находятся в местном AD отбрасываются. А задача стоит дать возможность подтвердить свое участие из внешнего домена.

Ответа здесь я, скорее всего, не получу, но, возможно, напишу его сам. А потом гугл проиндексирует форум и, может быть, это кому-нибудь поможет
27 авг 13, 13:10    [14760163]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
AlexeiK
Member

Откуда:
Сообщений: 2840
vagner
Интересно как ты определил, что я ленивый, и даже слишком.



vagner
Так вот проблема решена. Среди расширенных свойств EmailMessage нашлось свойство PidTagMessageFlags

вот скажи, просмотреть свойства , в msdn или где то там, сколько времени надо? вот и я про это.


да эта тема уже в индексе гугла.
токо проблема в том, что ты пишешь на русском все. нету же класса Календарь? вот как тут тебе помочь?
может ты сам , все так делаешь?
говоришь, что все сложно. но потом делаешь легкий шаг и у тебя победа.
:)


http://www.messageops.com/software/office-365-tools-and-utilities/messageops-exchange-ews-module/using-exportitems-and-uploaditems-cmdlets
тут ваще без программинга все перекидывают с изменением домена почты.

так что че :)
лень, она и есть лень.
27 авг 13, 17:58    [14762409]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
AlexeiK, и не лень тебе упрекать меня в лени? :)

Это у меня первая программа для exchange, я про него до этого слышал только то, что есть такой почтовый сервер.
Свойства класса EmailMessage в msdn просмотрел все. Про то, что этот флажок прячется в расширенных свойствах и подумать не мог.
Потом некоторые косвенные ссылки навели меня на мысль искать этот флажок в расширенных свойствах. И совсем не лень мне было просмотреть 1078 расширенных свойств и найти этот флажок.

Про русский язык я не понял. Здесь я пишу по русски, в гугле - на английском (ну, как умею). Ты о чем?

За ссылку спасибо, только там в первой же строчке написано:
Exchange Web Services in Exchange 2010 SP1 has a new feature that allows the export and upload of items to and from a mailbox in a serialized MAPI stream format.
Подозреваю, что используются те же самые методы веб-сервиса, которые использовал и я, а значит будут ровно те же проблемы, с которыми столкнулся и я. Про разные домены по ссылке ничего не написано.

Алексей, можешь помочь, помоги, пожалуйста.
Попробую сформулировать вопрос короче. Можно ли сделать так, чтобы для указанного элемента (EmailMessage или Appointment) при импорте использовалась SMTP-маршрутизация?
27 авг 13, 22:18    [14763163]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
Интересная деталь. Просматриваю адреса участников события непосредственно перед выгрузкой элемента - все адреса имеют маршрутизацию SMTP. А после выгрузки в файл (спасибо Алексею, благодаря ему я нашел программу просмотра файлов, которые получаются после операции ExportItems) все участники имеют уже муршрутизацию EX.
28 авг 13, 10:02    [14764060]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
AlexeiK
Member

Откуда:
Сообщений: 2840
vagner,

так вот опять.

vagner
все адреса имеют маршрутизацию SMTP


укажи, что за свойство хранит это значение, ведь свойство на английском же, да?
вот , а ты на русском описываешь.
сложно тут помогать тебе.
28 авг 13, 10:25    [14764230]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
AlexeiK
Member

Откуда:
Сообщений: 2840
пора уже код показать чтоли.
че стеснятся то.
изза вот таких казусов, все так медленно идет.
28 авг 13, 10:26    [14764240]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
Код (фрагмент, в котором считываются интересующие меня свойства)

			if ( ItemClass == iClass.Appointment )
			{
				Appointment aItem = hItem.BindToItem ( iId
					, new PropertySet ( exProp.epPidTagSentRepresentingAddressType
										, exProp.epPidTagSenderAddressType
										, AppointmentSchema.RequiredAttendees
										, AppointmentSchema.OptionalAttendees
										, exProp.epPidTagOriginalSenderAddressType
										, exProp.epPidTagOriginalSentRepresentingAddressType
									)
					, hf ) as Appointment;

				if ( aItem != null )
				{
					if ( ( aItem.RequiredAttendees != null ) && ( aItem.RequiredAttendees.Count > 0 ) )
						foreach ( Attendee at in aItem.RequiredAttendees )
						{
							LOG.ShowDbg ( "R-Attendee = {0}, RT = {1}, A = {2}.", at.Name, at.RoutingType, at.Address );
							at.RoutingType = hBox.SmtpRoutingType;
						}
					if ( ( aItem.OptionalAttendees != null ) && ( aItem.OptionalAttendees.Count > 0 ) )
						foreach ( Attendee at in aItem.OptionalAttendees )
						{
							LOG.ShowDbg ( "O-Attendee = {0}, RT = {1}, A = {2}.", at.Name, at.RoutingType, at.Address );
							at.RoutingType = hBox.SmtpRoutingType;
						}
					string rt = exProp.getExProp<string> ( aItem, exProp.epPidTagSenderAddressType, "null" );
					LOG.ShowDbg ( "epPidTagSenderAddressType = {0}.", rt );
					rt = exProp.getExProp<string> ( aItem, exProp.epPidTagSentRepresentingAddressType, "null" );
					LOG.ShowDbg ( "epPidTagSentRepresentingAddressType = {0}.", rt );
					rt = exProp.getExProp<string> ( aItem, exProp.epPidTagOriginalSenderAddressType, "null" );
					LOG.ShowDbg ( "epPidTagOriginalSenderAddressType = {0}.", rt );
					rt = exProp.getExProp<string> ( aItem, exProp.epPidTagOriginalSentRepresentingAddressType, "null" );
					LOG.ShowDbg ( "epPidTagOriginalSentRepresentingAddressType = {0}.", rt );
				}
			}


А вот что попало в лог:
10:33:18 : DBG : R-Attendee = Administrator, RT = SMTP, A = Administrator@intad.internal.
10:33:18 : DBG : R-Attendee = test 1. first, RT = SMTP, A = test1@intad.internal.
10:33:18 : DBG : epPidTagSenderAddressType = null.
10:33:18 : DBG : epPidTagSentRepresentingAddressType = null.
10:33:18 : DBG : epPidTagOriginalSenderAddressType = null.
10:33:18 : DBG : epPidTagOriginalSentRepresentingAddressType = null.

После этого открываю содержимое файла, полученного после ExportItems и вижу вот такую картинку
(сорри, не умею встраивать картинки)

К сообщению приложен файл. Размер - 61Kb
28 авг 13, 10:42    [14764416]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
Алексей (я правильно угадал имя? меня Александр если что), моя проблема заключается в том, что я просто наугад тыкаюсь, совершенно не имея представления о том, какие свойства за что отвечают. Исхожу только из их названий.
28 авг 13, 10:50    [14764498]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
Небольшие изменения. Доверившись программе просмотра содержимого ExportItems неверно определил идентификаторы расширенных свойств. Новая версия лога после уточнения по документации от МС

10:59:49 : DBG : R-Attendee = Administrator, RT = SMTP, A = Administrator@intad.internal.
10:59:49 : DBG : R-Attendee = test 1. first, RT = SMTP, A = test1@intad.internal.
10:59:49 : DBG : epPidTagSenderAddressType = EX.
10:59:49 : DBG : epPidTagSentRepresentingAddressType = EX.
10:59:49 : DBG : epPidTagOriginalSenderAddressType = null.
10:59:49 : DBG : epPidTagOriginalSentRepresentingAddressType = null.

К сожалению, в документации не написано можно ли изменять эти свойства. Сейчас попробую.
28 авг 13, 11:07    [14764674]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
AlexeiK
Member

Откуда:
Сообщений: 2840
vagner,

я не увидел метода, который непосредственно выгружает в файл , твое письмо.
что ж как лениво то все тянется.
тебя пока не ткнешь, ты не двинешься :)
28 авг 13, 11:43    [14764976]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
AlexeiK,

		public static bool saveItem ( ItemId iId, string ItemClass, hFolder hf, string fileName )
		{
			if ( ( iId == null ) || ( string.IsNullOrEmpty ( ItemClass ) ) || ( string.IsNullOrEmpty ( fileName ) || ( hf == null ) ) ) return false;

			if ( ItemClass == iClass.Appointment )
			{
                                          // этот код уже был выше (чтобы не засорять)
			}
                                          // получить содержимое элемента
			byte [ ] data = getItemContent ( iId, ItemClass, hf );
			if ( data == null ) return false;
                                          // записать полученное содержимое в файл
			try
			{
				File.WriteAllBytes ( fileName, data );
				return true;
			}
			catch ( Exception ex )
			{
				LOG.ShowEx ( ex, "ewsExport: Исключение при сохранении элемента в файл '{0}'.", fileName );
				return false;
			}
		}
28 авг 13, 11:57    [14765053]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
Получить содержимое элемента (в случае с Appointment мы попадаем на hEws.gValue.ewsExport ( iId.UniqueId ); )
		/// <summary>
		/// Получить содержимое элемента.
		/// </summary>
		public static byte [ ] getItemContent ( ItemId iId, string ItemClass, hFolder hf )
		{
			if ( ( iId == null ) || ( string.IsNullOrEmpty ( ItemClass ) || ( hf == null ) ) ) return null;

			byte [ ] res = null;

			if ( iClass.IsMC ( ItemClass ) )
			{
				Item i = BindToItem ( iId, new PropertySet ( BasePropertySet.IdOnly, ItemSchema.MimeContent ), hf );
				if ( ( i != null ) && ( i.MimeContent != null ) ) res = i.MimeContent.Content;
			}
			else
			{
				res = hEws.gValue.ewsExport ( iId.UniqueId );
			}

			return res;
		}
28 авг 13, 11:58    [14765064]     Ответить | Цитировать Сообщить модератору
 Re: Exchange EWS - как пометить письмо прочитанным?  [new]
vagner
Member

Откуда:
Сообщений: 1783
Собственно ewsExport
		public byte [ ] ewsExport ( string ItemId )
		{
			if ( string.IsNullOrEmpty ( ItemId ) ) throw new Exception ( "ewsExport: Не указан идентификатор элемента." );

			try
			{
				ExportItemsType eit = new ExportItemsType ( );
				eit.ItemIds = new ItemIdType [ 1 ];
				eit.ItemIds [ 0 ] = new ItemIdType ( );
				eit.ItemIds [ 0 ].Id = ItemId;

				ExportItemsResponseType resp = ews.ExportItems ( eit );
				if ( ( resp == null )
					|| ( resp.ResponseMessages == null )
					|| ( resp.ResponseMessages.Items == null )
					|| ( resp.ResponseMessages.Items.Length == 0 )
					) return null;

				ewsResponseMessage rm = resp.ResponseMessages.Items [ 0 ];
				if ( rm.ResponseClass == ResponseClassType.Error )
				{
					LOG.ShowErr ( "ewsExport: Ошибка при вызове ExportItems '{0}'.", rm.ResponseCode.ToString ( ) );
					return null;
				}
				if ( rm.ResponseClass == ResponseClassType.Warning )
				{
					LOG.ShowWrn ( "ewsExport: Предупреждение при вызове ExportItems '{0}'.", rm.ResponseCode.ToString ( ) );
					//	будем надеяться, что данные все-таки возвращены
					//return false;
				}
				ExportItemsResponseMessageType rItem = rm as ExportItemsResponseMessageType;
				if ( ( rItem == null ) || ( rItem.Data == null ) || ( rItem.Data.Length == 0 ) )
				{
					LOG.ShowErr ( "ewsExport: Ошибки не было, но и данных нет." );
					return null;
				}
				return rItem.Data;
			}
			catch ( Exception ex )
			{
				LOG.ShowEx ( ex, "ewsExport: Исключение при вызове ExportItems." );
				return null;
			}
		}
28 авг 13, 11:59    [14765071]     Ответить | Цитировать Сообщить модератору
Все форумы / WCF, Web Services, Remoting Ответить