使用自定义TextWriter时,Sitecore MVC OutputStream不可用

时间:2016-01-12 10:09:45

标签: asp.net-mvc sitecore asp.net-mvc-routing sitecore8 sitecore-mvc

基于这个答案:https://stackoverflow.com/a/2343089/3889469

我在提交表单时无法提供vCard。

@using (Html.BeginRouteForm(MvcSettings.SitecoreRouteName, FormMethod.Post, new { name = "vCard_verify", @class = "vCardVerify" }))
            {
                @Html.AntiForgeryToken()
                @Html.Sitecore().FormHandler("Content", "vCard")
                @Html.Hidden("vCardGuid")

                <div id="g-recaptcha-vCard"></div>
            }

控制器操作:

[HttpPost]
        [ValidateAntiForgeryToken]
        public vCardResult vCard()
        {
            NameValueCollection formNvc = Request.Form;
            string Guid =  formNvc["vCardGuid"];
            var context = new SitecoreContext();
            var person = context.GetItem<Person>(Guid);

            var card = new VCard
            {
                FirstName = person.First_Name,
                LastName = person.Last_Name,
                StreetAddress = "street",
                City = "city",
                State = "state",
                Zip = "zip",
                CountryName = "USA",
                Organization = "Org",
                JobTitle = person.Title,
                Phone = person.Phone,
                Fax = "Fax",
                Image = "image",
                HomePage = "google.com",
                Email = person.Email_Address
            };

            return new vCardResult(card);
        }

public class vCardResult : ActionResult
    {
        private VCard _card;

        protected vCardResult() { }

        public vCardResult(VCard card)
        {
            _card = card;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            var response = HttpContext.Current.Response; // context.HttpContext.Response;
            response.ContentType = "text/vcard";
            response.AddHeader("Content-Disposition", "attachment; fileName=" + _card.FirstName + " " + _card.LastName + ".vcf");

            var cardString = _card.ToString();
            var inputEncoding = Encoding.Default;
            var outputEncoding = Encoding.GetEncoding("windows-1257");
            var cardBytes = inputEncoding.GetBytes(cardString);
            var outputBytes = Encoding.Convert(inputEncoding,
                                    outputEncoding, cardBytes);

            response.BinaryWrite(outputBytes);
            //response.OutputStream.Write(outputBytes, 0, outputBytes.Length);
            //response.End();
        }
    }

    public class VCard
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Organization { get; set; }
        public string JobTitle { get; set; }
        public string StreetAddress { get; set; }
        public string Zip { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string CountryName { get; set; }
        public string Phone { get; set; }
        public string Fax { get; set; }
        public string Email { get; set; }
        public string HomePage { get; set; }
        public string Image { get; set; }

        public override string ToString()
        {
            var builder = new StringBuilder();
            builder.AppendLine("BEGIN:VCARD");
            builder.AppendLine("VERSION:4.0");
            // Name
            builder.AppendLine("N:" + LastName + ";" + FirstName + ";;;");
            // Full name
            builder.AppendLine("FN:" + FirstName + " " + LastName);
            //Company
            builder.AppendLine("ORG:" + Organization);
            //Title
            builder.AppendLine("TITLE:" + JobTitle);
            //Phone
            builder.AppendLine("TEL;TYPE=work:" + Phone);
            //Fax
            builder.AppendLine("TEL;TYPE=fax:" + Fax);
            // Address
            builder.Append("ADR;TYPE=work;LABEL=\"" + StreetAddress + "\n" + City + ", " + State + " " + Zip + "\n" + CountryName + "\":;;");
            builder.Append(StreetAddress + ";");
            builder.Append(City + ";");
            builder.Append(State + ";");
            builder.Append(Zip + ";");
            builder.AppendLine(CountryName);
            // Photo
            builder.AppendLine("PHOTO; MEDIATYPE = image / png:" + Image);
            //Site
            builder.AppendLine("URL;" + HomePage);
            //Email
            builder.AppendLine("EMAIL:" + Email);
            builder.AppendLine("END:VCARD");
            return builder.ToString();
        }
    }

我得到的错误是:使用自定义TextWriter时,OutputStream不可用。 我相信在我的动作被调用之前已经发送了标题,但我不确定替代方案是什么?如何强制下载文件并仍然使用Sitecore 8 MVC加载当前页面?

1 个答案:

答案 0 :(得分:1)

事实证明,我必须重新路由到一个新动作才能在sitecore开始构建实际页面之前先传递我自己的标题。

所以我的帖子功能改为:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult vCard(string vCardGuid)
{
      if (string.IsNullOrEmpty(vCardGuid))
          return Redirect("/People");

      return RedirectToAction("DownloadvCard", new { vGuid = vCardGuid });
}

新的DownloadvCard功能基本上是旧的vCard功能

[HttpGet]
public vCardResult DownloadvCard(string vGuid)
{
    var context = new SitecoreContext();
    var person = context.GetItem<Person>(vGuid);
    Item personItem = Database.GetDatabase("master").GetItem(ID.Parse(vGuid));
    //Photo
    ImageField img = personItem.Fields["Person Thumbnail"];
    MediaItem image = new MediaItem(img.MediaItem);
    var imageURL = MediaManager.GetMediaUrl(image, new MediaUrlOptions() { AbsolutePath = true, AlwaysIncludeServerUrl = true });

    //Url
    var options = LinkManager.GetDefaultUrlOptions();
    options.AlwaysIncludeServerUrl = true;
    string url = LinkManager.GetItemUrl(personItem, options);

    Location office = new Location();
    foreach (var loc in person.Offices)
    {
        office = loc;
        break;
    }

    var card = new VCard();
    card.FirstName = person.First_Name;
    card.LastName = person.Last_Name;
    card.StreetAddress = office.Location_Address;
    card.StreetAddress2 = office.Location_Address_2;
    card.City = office.Location_City;
    card.State = office.Location_State;
    card.Zip = office.Location_Zip;
    card.CountryName = "USA";
    card.Organization = "O'Connor Davies";
    card.JobTitle = person.Person_Title;
    card.Phone = person.Phone;
    card.Fax = office.Location_Fax;
    card.Image = imageURL.Replace(".ashx",".png");
    card.HomePage = url;
    card.Email = person.Email_Address;


    return new vCardResult(card);
}

其余的保持不变。 快乐的编码;)