简体   繁体   中英

How to dynamically generate an ics file?

I'm using Ical.net to create a calendar file and then I need to make it available using a url that has an ics extension. I need to feed it to another application that expects an ics file. Similar to how google provides an ics link for your calendar.

I was able to generate then feed an ics file to the response and when I access the controller link, an ics file is downloaded by my browser. See code below.

        Response.ContentType = "text/calendar"

        Response.AddHeader("content-disposition", "attachment;filename=" + "calendar.ics");
        Response.Clear();

        using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8))
        {
            writer.Write(serializedCalendar);
        }
        Response.End();

My url is: http://test.com/home/calendar but my application is not accepting this url. I need a url like http://test.com/home/calendar/calendar.ics (Like how google calendar has a secret link for ics file)

How do I go about doing this while making sure that everytime the url is accessed, the file is dynamically generated with fresh data?

Build a formatter (add whatever you need into that formatter), then like here register your handler in you routes


public class ICalFormatter : BufferedMediaTypeFormatter
{
    public ICalFormatter ()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/iCal"));
    }

    public override bool CanReadType(Type type)
    {
        return false;
    }

    public override bool CanWriteType(Type type)
    {
        if (type == typeof(AppointmentModel))
        {
            return true;
        }
        else
        {
            Type enumerableType = typeof(IEnumerable<AppointmentModel>);
            return enumerableType.IsAssignableFrom(type);
        }
    }

    public override void WriteToStream(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content)
    {
        using (var writer = new StreamWriter(writeStream))
        {
            writer.WriteLine("BEGIN:VCALENDAR");
            writer.WriteLine("VERSION:2.0");
            var appointments = value as IEnumerable<AppointmentModel>;
            if (appointments != null)
            {
                foreach (var appointment in appointments)
                {
                    WriteAppointment(appointment, writer);
                }
            }
            else
            {
                var singleAppointment = value as AppointmentModel;
                if (singleAppointment == null)
                {
                    throw new InvalidOperationException("Cannot serialize type");
                }
                WriteAppointment(singleAppointment, writer);
            }
            writer.WriteLine("END:VCALENDAR");
        }
        writeStream.Close();
    }

    private void WriteAppointment(AppointmentModel appointment, StreamWriter writer)
    {
        writer.WriteLine("BEGIN:VEVENT");
        writer.WriteLine("UID:" + appointment.Id);
        writer.WriteLine("DTSTART:" + string.Format("{0:yyyyMMddTHHmmssZ}", appointment.From));
        writer.WriteLine("DTEND:" + string.Format("{0:yyyyMMddTHHmmssZ}", appointment.Until));
        writer.WriteLine("SUMMARY:" + appointment.Title);
        writer.WriteLine("END:VEVENT");
    }
}

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

       config.Formatters.Add(new ICalFormatter());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM