2009-01-20 35 views
36

Tôi tự hỏi nếu có thể gửi yêu cầu họp cho mọi người mà không cần cài đặt Outlook trên máy chủ và sử dụng COM Interop (mà tôi muốn tránh trên máy chủ bằng mọi giá).Gửi yêu cầu họp Outlook không có Outlook?

Chúng tôi có Exchange 2003 trong Miền Windows 2003 và tất cả người dùng là Người dùng miền. Tôi đoán tôi có thể gửi 'vòng iCal/vCal hoặc một cái gì đó, nhưng tôi tự hỏi nếu có một cách tiêu chuẩn thích hợp để gửi yêu cầu họp thông qua Exchange mà không có Outlook?

Đây là mạng C# /. Nếu nó quan trọng.

+1

Lượng thời gian bạn đã chọn để chờ đợi làm cho tôi nghĩ rằng đề nghị của tôi không phải là chính xác những gì bạn có trong tâm trí. Bạn có ít nhất làm cho nó hoạt động không? – Tomalak

+1

Tôi không có thời gian để kiểm tra nó trước đó. Một thử nghiệm nhanh về nó dường như hoạt động, và tôi đã gửi một Lời mời họp của Outlook đến một tài khoản đã bật POP3 để có được một "bãi chứa thô".Hai bit này đủ tốt để tôi tính toán phần còn lại, vì tôi chỉ cần gửi các cuộc họp nhưng không quan tâm đến câu trả lời –

+1

Trong mọi trường hợp, câu trả lời của bạn rất hữu ích, cảm ơn rất nhiều! –

Trả lời

47

Cách để gửi một yêu cầu họp để Outlook (và có nó được công nhận) đi như thế này:

  • chuẩn bị một tệp iCalendar, hãy chắc chắn để thiết lập các thuộc tính bổ sung, như Outlook cần họ:
  • chuẩn bị thư multipart/alternative:
    • Phần 1: text/html (hoặc bất cứ điều gì bạn thích) - điều này được hiển thị cho độc giả "bình thường" đường bưu điện hoặc như một mùa thu lại và chứa một tóm tắt sự kiện ở dạng có thể đọc được của con người
    • Phần 2: text/calendar; method=REQUEST, giữ nội dung của tệp ics (tham số tiêu đề method phải khớp với phương pháp trong ics). Xem ra cho các mã hóa văn bản chính xác, tuyên bố một tham số tiêu đề charset sẽ không làm tổn thương.
    • Phần 3: Tùy chọn, đính kèm tệp .ics, do đó người đọc thư thông thường có thể cung cấp cho người dùng một cái gì đó để nhấp vào. Outlook không thực sự yêu cầu tệp đính kèm vì nó chỉ đọc phần text/calendar.
  • Gửi thư cho người dùng xem. Nếu bạn có mọi thứ đúng, thư sẽ hiển thị dưới dạng yêu cầu gặp mặt, hoàn thành với các nút tham dự và mục nhập tự động trong lịch người dùng khi chấp nhận.
  • Thiết lập nội dung nào đó xử lý câu trả lời (họ chuyển đến người tổ chức cuộc họp). Tôi chưa thể nhận được theo dõi người tham dự tự động để làm việc với hộp thư Exchange vì sự kiện này sẽ không tồn tại trong lịch tổ chức. Outlook cần UID và SEQUENCES để phù hợp với mong đợi của nó, nhưng với một UID bạn tạo nên điều này sẽ hầu như không hoạt động.

Để được trợ giúp về chi tiết và đặc thù của định dạng tệp ics, hãy đảm bảo truy cập vào iCalendar Specification Excerpts by Masahide Kanzaki. Họ là một ánh sáng trong bóng tối, tốt hơn nhiều so với gặm nhấm theo cách của bạn thông qua RFC 2445. Nhưng sau đó một lần nữa, có thể là một thư viện tiện dụng tồn tại cho .NET.

+0

Tôi chỉ không có thời gian để kiểm tra nó trước đó. Một thử nghiệm nhanh về nó dường như hoạt động, và tôi đã gửi một Lời mời họp của Outlook đến một tài khoản đã bật POP3 để có được một "bãi chứa thô". Hai bit này đủ tốt để tôi tính toán phần còn lại, vì tôi chỉ cần gửi các cuộc họp nhưng không quan tâm đến câu trả lời –

+1

Xóa tiêu đề sau khỏi Phần 2 đã thực hiện thủ thuật cho tôi: Nội dung-Bố trí: tệp đính kèm; filename = meeting.ics Miễn là tiêu đề này nằm trong thư, Outlook sẽ hiển thị ICS dưới dạng phần đính kèm. – Bob

+0

Đây là những gì xảy ra khi có tiêu đề 'Nội dung-Bố trí: tệp đính kèm'. ;-) – Tomalak

3

Đoạn code dưới đây sẽ gửi một yêu cầu họp theo cách như vậy mà Outlook sẽ hiển thị các nút Chấp nhận/Từ chối.

Lưu ý rằng UID phải là duy nhất cho mỗi cuộc họp, tôi đã sử dụng GUID.

Cũng lưu ý rằng bạn cần phải thay thế CREATED, DTSTART, DTEND, DTSTAMP, LAST-MODIFIED. Đây là ngày/giờ UTC.

var m = new MailMessage(); 

    m.Subject = "Meeting"; 

    m.Body = ""; 

    string iCal = 
@"BEGIN:VCALENDAR 
PRODID:-//Microsoft Corporation//Outlook 14.0 MIMEDIR//EN 
VERSION:2.0 
METHOD:PUBLISH 
X-MS-OLK-FORCEINSPECTOROPEN:TRUE 
BEGIN:VEVENT 
CLASS:PUBLIC 
CREATED:20140423T045933Z 
DESCRIPTION:desc 
DTEND:20140430T080000Z 
DTSTAMP:20140423T045933Z 
DTSTART:20140430T060000Z 
LAST-MODIFIED:20140423T045933Z 
LOCATION:location... 
PRIORITY:5 
SEQUENCE:0 
SUMMARY;LANGUAGE=en-us:Summary... 
TRANSP:OPAQUE 
UID:D8BFD357-88A7-455C-86BC-C2CECA9AC5C6 
X-MICROSOFT-CDO-BUSYSTATUS:BUSY 
X-MICROSOFT-CDO-IMPORTANCE:1 
X-MICROSOFT-DISALLOW-COUNTER:FALSE 
X-MS-OLK-AUTOFILLLOCATION:FALSE 
X-MS-OLK-CONFTYPE:0 
BEGIN:VALARM 
TRIGGER:-PT60M 
ACTION:DISPLAY 
DESCRIPTION:Reminder 
END:VALARM 
END:VEVENT 
END:VCALENDAR"; 

    using (var iCalView = AlternateView.CreateAlternateViewFromString(iCal, new System.Net.Mime.ContentType("text/calendar"))) 
    { 
     m.AlternateViews.Add(iCalView); 

     var c = new SmtpClient(); 

     // Send message 
     c.Send(m); 
    } 

này giả sử bạn có một máy chủ SMTP cục bộ cấu hình trong tập tin cấu hình của bạn:

<system.net> 
    <mailSettings> 
     <smtp deliveryMethod="Network" from="[email protected]"> 
     <network defaultCredentials="true" host="smtp.example.local" /> 
     </smtp> 
    </mailSettings> 
    </system.net> 
5

iCalendar là một giải pháp có mục đích chung tuyệt vời, và thư viện DDay.iCal là một cách tuyệt vời để làm điều này từ .NET, nhưng tôi tin rằng Exchange Web Services (EWS) là một giải pháp tốt hơn trong bối cảnh của câu hỏi gốc (Exchange, C# /. NET).

Và nếu bạn đang sử dụng ngôn ngữ .NET chẳng hạn như C#, bạn nên sử dụng trình bao bọc EWS Managed API giúp đơn giản hóa việc làm việc với EWS.

Từ the docs, dưới đây là cách sử dụng EWS Managed API để tạo ra một cuộc họp và gửi yêu cầu đến khách mời:

// Create the appointment. 
Appointment appointment = new Appointment(service); 

// Set properties on the appointment. Add two required attendees and one optional attendee. 
appointment.Subject = "Status Meeting"; 
appointment.Body = "The purpose of this meeting is to discuss status."; 
appointment.Start = new DateTime(2009, 3, 1, 9, 0, 0); 
appointment.End = appointment.Start.AddHours(2); 
appointment.Location = "Conf Room"; 
appointment.RequiredAttendees.Add("[email protected]"); 
appointment.RequiredAttendees.Add("[email protected]"); 
appointment.OptionalAttendees.Add("[email protected]"); 

// Send the meeting request to all attendees and save a copy in the Sent Items folder. 
appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy); 
+1

Tôi đồng ý, giải pháp này đơn giản hơn nhiều so với các giải pháp khác. Cũng cần lưu ý rằng EWS không yêu cầu Outlook COM interop. – JordanTDN

3

Bạn có thể gửi yêu cầu họp qua đường bưu điện đến triển vọng sử dụng iCal Standard (RFC 5545)

Bạn không thể gửi các vật phẩm todo theo cách này. Bạn có thể gửi "Cuộc hẹn" nhưng chúng xuất hiện trong triển vọng dưới dạng tệp đính kèm .ics mà phải được chấp nhận "một cách mù quáng".

Yêu cầu gặp mặt xuất hiện trong triển vọng với bản xem trước tốt đẹp và có thể được chấp nhận hoặc được chỉnh sửa lại. Chương trình gửi có thể sửa đổi hoặc hủy cuộc họp sau khi được gửi.

Nó easieset để tạo ra một mục iCal hợp lệ với DDay.iCal .Net Library

Đoạn code dưới đây là một ví dụ làm việc hoàn tất. Nó xây dựng một chuỗi với một yêu cầu họp iCal hợp lệ và gửi nó qua thư.

Mã này tạo ra một mail với:

  • cơ thể văn bản đơn giản cho khách hàng mail đơn giản
  • HTML cơ thể cho diplay trong mail client hiện đại
  • iCal yêu cầu họp như AlternateView (sẽ hiển thị trong Outlook)
  • yêu cầu họp iCal dưới dạng tệp đính kèm (có thể sử dụng trong các ứng dụng thư khác ngoài triển vọng)

Mã cho thấy làm thế nào để thêm:

  • mô tả văn bản dưới dạng HTML, trông đẹp hơn trong quan điểm
  • ưu tiên, tầm nhìn (public/private/bí mật)
  • tổ chức bắt buộc (sẽ hiển thị trong triển vọng thay vì gửi mail)
  • người tham dự tùy chọn
  • báo thức tùy chọn
  • tệp đính kèm tùy chọn cho cuộc họp. sẽ hiển thị trong lịch triển vọng của

Một số chi tiết quan trọng:

  • email người gửi (hoặc tùy chọn tổ chức) và hộp thư người nhận phải khác nhau để làm cho công việc này trong quan điểm
  • PHƯƠNG trong .ics và PHƯƠNG PHÁP trong Mime.ContentType phải khớp với
  • Cuộc họp phải nằm trong tương lai để thực hiện công việc này trong triển vọng
  • phần .ics phải là phần thay thế cuối cùng trong thư MIME

Các chi tiết chính xác về cách thức triển vọng giải thích .ics file được chi tiết hóa trong [MS-OXCICAL]: iCalendar to Appointment Object Conversion Algorithm

Chúng tôi sẽ sử dụng các cụm:

using System; 
using System.IO; 
using System.Net.Mail; 
using DDay.iCal; 
using DDay.iCal.Serialization.iCalendar; 

Đối DDay.iCal đủ để tải về DDay.iCal binary Files của nó. Nếu bạn muốn thêm một số tính năng tốt nhất là xem xét các nguồn DDay.iCal vì tài liệu đã lỗi thời và các nguồn chứa các bài kiểm tra khá hoàn chỉnh để thực hiện tất cả các tính năng của nó.

const string filepath = @"C:\temp\ical.test.ics"; 
// use PUBLISH for appointments 
// use REQUEST for meeting requests 
const string METHOD = "REQUEST"; 

// Properties of the meeting request 
// keep guid in sending program to modify or cancel the request later 
Guid uid = Guid.Parse("2B127C67-73B3-43C5-A804-5666C2CA23C9"); 
string VisBetreff = "This is the subject of the meeting request"; 
string TerminVerantwortlicherEmail = "[email protected]"; 
string bodyPlainText = "This is the simple iCal plain text msg"; 
string bodyHtml = "This is the simple <b>iCal HTML message</b>"; 
string location = "Meeting room 101"; 
// 1: High 
// 5: Normal 
// 9: low 
int priority = 1; 
//===================================== 
MailMessage message = new MailMessage(); 

message.From = new MailAddress("[email protected]"); 
message.To.Add(new MailAddress(TerminVerantwortlicherEmail)); 
message.Subject = "[VIS-Termin] " + VisBetreff; 

// Plain Text Version 
message.Body = bodyPlainText; 

// HTML Version 
string htmlBody = bodyHtml; 
AlternateView HTMLV = AlternateView.CreateAlternateViewFromString(htmlBody, 
    new System.Net.Mime.ContentType("text/html")); 

// iCal 
IICalendar iCal = new iCalendar(); 
iCal.Method = METHOD; 
iCal.ProductID = "My Metting Product";    

// Create an event and attach it to the iCalendar. 
Event evt = iCal.Create<Event>(); 
evt.UID = uid.ToString(); 

evt.Class = "PUBLIC"; 
// Needed by Outlook 
evt.Created = new iCalDateTime(DateTime.Now); 

evt.DTStamp = new iCalDateTime(DateTime.Now); 
evt.Transparency = TransparencyType.Transparent; 

// Set the event start/end times 
evt.Start = new iCalDateTime(2014, 10, 3, 8, 0, 0); 
evt.End = new iCalDateTime(2014, 10, 3, 8, 15, 0); 
evt.Location = location; 

//var organizer = new Organizer("[email protected]"); 
//evt.Organizer = organizer; 

// Set the longer description of the event, plain text 
evt.Description = bodyPlainText; 

// Event description HTML text 
// X-ALT-DESC;FMTTYPE=text/html 
var prop = new CalendarProperty("X-ALT-DESC"); 
prop.AddParameter("FMTTYPE", "text/html"); 
prop.AddValue(bodyHtml); 
evt.AddProperty(prop); 

// Set the one-line summary of the event 
evt.Summary = VisBetreff; 
evt.Priority = priority; 

//--- attendes are optional 
IAttendee at = new Attendee("mailto:[email protected]"); 
at.ParticipationStatus = "NEEDS-ACTION"; 
at.RSVP = true; 
at.Role = "REQ-PARTICIPANT"; 
evt.Attendees.Add(at); 

// Let’s also add an alarm on this event so we can be reminded of it later. 
Alarm alarm = new Alarm(); 

// Display the alarm somewhere on the screen. 
alarm.Action = AlarmAction.Display; 

// This is the text that will be displayed for the alarm. 
alarm.Summary = "Upcoming meeting: " + VisBetreff; 

// The alarm is set to occur 30 minutes before the event 
alarm.Trigger = new Trigger(TimeSpan.FromMinutes(-30)); 

//--- Attachments 
string filename = "Test.docx"; 

// Add an attachment to this event 
IAttachment attachment = new DDay.iCal.Attachment(); 
attachment.Data = ReadBinary(@"C:\temp\Test.docx"); 
attachment.Parameters.Add("X-FILENAME", filename); 
evt.Attachments.Add(attachment); 

iCalendarSerializer serializer = new iCalendarSerializer(); 
serializer.Serialize(iCal, filepath); 

// the .ics File as a string 
string iCalStr = serializer.SerializeToString(iCal); 

// .ics as AlternateView (used by Outlook) 
// text/calendar part: method=REQUEST 
System.Net.Mime.ContentType calendarType = 
    new System.Net.Mime.ContentType("text/calendar"); 
calendarType.Parameters.Add("method", METHOD); 
AlternateView ICSview = 
    AlternateView.CreateAlternateViewFromString(iCalStr, calendarType); 

// Compose 
message.AlternateViews.Add(HTMLV); 
message.AlternateViews.Add(ICSview); // must be the last part 

// .ics as Attachment (used by mail clients other than Outlook) 
Byte[] bytes = System.Text.Encoding.ASCII.GetBytes(iCalStr); 
var ms = new System.IO.MemoryStream(bytes); 
var a = new System.Net.Mail.Attachment(ms, 
    "VIS-Termin.ics", "text/calendar"); 
message.Attachments.Add(a);  

// Send Mail 
SmtpClient client = new SmtpClient(); 
client.Send(message); 

Ở đây ReadBinary() chức năng:

private static byte[] ReadBinary(string fileName) 
{ 
    byte[] binaryData = null; 
    using (FileStream reader = new FileStream(fileName, 
     FileMode.Open, FileAccess.Read)) 
    { 
     binaryData = new byte[reader.Length]; 
     reader.Read(binaryData, 0, (int)reader.Length); 
    } 
    return binaryData; 
} 

đơn giản nhất của nó để cấu hình SmtpClient trong tập tin cấu hình như thế này:

<configuration> 
    ... 
    <system.net> 
    <mailSettings> 
     <smtp> 
     <network host="mysmtp.server.com" port="25" userName="mySmtpUserName" password="myPassword" /> 
     </smtp> 
    </mailSettings> 
    </system.net> 
    ... 
+0

Cảm ơn bạn đã phản hồi kỹ lưỡng! Tiết kiệm rất nhiều thử và lỗi –

Các vấn đề liên quan