/// <summary>
        ///     Assemble a document from the given template, answers and settings.
        /// </summary>
        /// <param name="template">An instance of the Template class.</param>
        /// <param name="answers">
        ///     Either an XML answer string, or a string containing encoded
        ///     interview answers as posted from a HotDocs browser interview.
        /// </param>
        /// <param name="settings">An instance of the AssembleDocumentResult class.</param>
        /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']" />
        /// <returns>An AssemblyResult object containing all the files and data resulting from the request.</returns>
        public AssembleDocumentResult AssembleDocument(Template template, TextReader answers,
                                                       AssembleDocumentSettings settings, string logRef = "")
        {
            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            using (var client = new HttpClient())
            {
                AssembleDocumentResult adr  = null;
                var packageTemplateLocation = (PackageTemplateLocation)template.Location;
                var packageId = packageTemplateLocation.PackageID;
                var of        = ConvertFormat(settings.Format);
                var timestamp = DateTime.UtcNow;

                var hmac = HMAC.CalculateHMAC(
                    SigningKey,
                    timestamp,
                    SubscriberId,
                    packageId,
                    template.FileName,
                    false,
                    logRef,
                    of,
                    settings.Settings);

                var urlBuilder =
                    new StringBuilder().AppendFormat("{0}/assemble/{1}/{2}/{3}?" +
                                                     "format={4}&" +
                                                     "encodefilenames={5}&" +
                                                     "billingref={6}{7}",
                                                     HostAddress, SubscriberId, packageId, Uri.EscapeDataString(template.FileName),
                                                     of,
                                                     true,
                                                     Uri.EscapeDataString(logRef),
                                                     GetRetrieveFromHubParam());

                if (settings.Settings != null)
                {
                    foreach (var kv in settings.Settings)
                    {
                        urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                    }
                }

                var request = new HttpRequestMessage
                {
                    RequestUri = new Uri(urlBuilder.ToString()),
                    Method     = HttpMethod.Post
                };

                request.Headers.Add("x-hd-date", timestamp.ToString("yyyy-MM-ddTHH:mm:ssZ"));
                request.Headers.Authorization = new AuthenticationHeaderValue("basic", hmac);

                var stringContent = answers == null
                    ? new StringContent(string.Empty)
                    : new StringContent(answers.ReadToEnd());

                request.Content = stringContent;

                request.Content.Headers.TryAddWithoutValidation("Content-Type", "text/xml");

                var result = client.SendAsync(request).Result;

                var parser = new MultipartMimeParser();

                HandleStatusCode(result);

                var streamResult = result.Content.ReadAsStreamAsync().Result;

                var streams = new List <MemoryStream>();

                using (var resultsStream = new MemoryStream())
                {
                    // Each part is written to a file whose name is specified in the content-disposition
                    // header, except for the AssemblyResult part, which has a file name of "meta0.xml",
                    // and is parsed into an AssemblyResult object.
                    parser.WritePartsToStreams(
                        streamResult,
                        h =>
                    {
                        var fileName = GetFileNameFromHeaders(h);
                        if (fileName == null)
                        {
                            return(Stream.Null);
                        }

                        if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                        {
                            return(resultsStream);
                        }

                        var stream = new MemoryStream();
                        streams.Add(stream);
                        return(stream);
                    },
                        (new ContentType(result.Content.Headers.ContentType.ToString())).Boundary);

                    if (resultsStream.Position <= 0)
                    {
                        return(null);
                    }

                    resultsStream.Position = 0;
                    var serializer = new XmlSerializer(typeof(AssemblyResult));
                    var asmResult  = (AssemblyResult)serializer.Deserialize(resultsStream);

                    if (asmResult == null)
                    {
                        return(adr);
                    }

                    for (var i = 0; i < asmResult.Documents.Length; i++)
                    {
                        asmResult.Documents[i].Data = streams[i].ToArray();
                        streams[i].Dispose();
                    }

                    adr = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
                }

                return(adr);
            }
        }
Beispiel #2
0
        public AssembleDocumentResult AssembleDocument(Template template, TextReader answers,
                                                       AssembleDocumentSettings settings, string logRef)
        {
            using (var client = new HttpClient())
            {
                AssembleDocumentResult adr     = null;
                var    stringContent           = new StringContent(answers.ReadToEnd());
                var    packageTemplateLocation = (PackageTemplateLocation)template.Location;
                string packageId = packageTemplateLocation.PackageID;

                OutputFormat of = ConvertFormat(settings.Format);

                var urlBuilder =
                    new StringBuilder(string.Format(HostAddress + "/assemble/0/{0}/{1}?format={2}&encodefilenames={3}", packageId,
                                                    HttpUtility.UrlEncode(template.FileName), of, true));

                if (settings.Settings != null)
                {
                    foreach (var kv in settings.Settings)
                    {
                        urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                    }
                }

                HttpResponseMessage result = client.PostAsync(urlBuilder.ToString(), stringContent).Result;

                var _parser = new MultipartMimeParser();

                HandleErrorStream(result, result.IsSuccessStatusCode);
                Stream streamResult = result.Content.ReadAsStreamAsync().Result;

                string outputDir = Path.GetTempPath();
                Directory.CreateDirectory(outputDir);
                using (var resultsStream = new MemoryStream())
                {
                    // Each part is written to a file whose name is specified in the content-disposition
                    // header, except for the AssemblyResult part, which has a file name of "meta0.xml",
                    // and is parsed into an AssemblyResult object.
                    _parser.WritePartsToStreams(
                        streamResult,
                        h =>
                    {
                        string fileName = GetFileNameFromHeaders(h);
                        if (fileName != null)
                        {
                            if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                            {
                                return(resultsStream);
                            }

                            return(new FileStream(Path.Combine(outputDir, fileName), FileMode.Create));
                        }
                        return(Stream.Null);
                    },
                        (new ContentType(result.Content.Headers.ContentType.ToString())).Boundary);

                    if (resultsStream.Position > 0)
                    {
                        resultsStream.Position = 0;
                        var serializer = new XmlSerializer(typeof(AssemblyResult));
                        var asmResult  = (AssemblyResult)serializer.Deserialize(resultsStream);
                        if (asmResult != null)
                        {
                            adr = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
                        }
                    }
                }
                return(adr);
            }
        }
        /// <summary>
        ///     GetInterview returns an HTML fragment suitable for inclusion in any standards-mode web page, which embeds a HotDocs
        ///     interview
        ///     directly in that web page.
        /// </summary>
        /// <param name="template">The template for which to return an interview.</param>
        /// <param name="answers">The answers to use when building an interview.</param>
        /// <param name="settings">The <see cref="InterviewSettings" /> to use when building an interview.</param>
        /// <param name="markedVariables">
        ///     The variables to highlight to the user as needing special attention.
        ///     This is usually populated with <see cref="AssembleDocumentResult.UnansweredVariables" />
        ///     from <see cref="AssembleDocument" />.
        /// </param>
        /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']" />
        /// <returns>Returns the results of building the interview as an <see cref="InterviewResult" /> object.</returns>
        public InterviewResult GetInterview(Template template, TextReader answers, InterviewSettings settings,
                                            IEnumerable <string> markedVariables, string logRef = "")
        {
            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            using (var client = new HttpClient())
            {
                var packageTemplateLocation = (PackageTemplateLocation)template.Location;
                var packageId = packageTemplateLocation.PackageID;
                var timestamp = DateTime.UtcNow;

                var hmac = HMAC.CalculateHMAC(
                    SigningKey,
                    timestamp,
                    SubscriberId,
                    packageId,
                    template.FileName,
                    false,
                    logRef,
                    settings.Format,
                    settings.InterviewFilesUrl,
                    settings.Settings);

                var urlBuilder = new StringBuilder().AppendFormat("{0}/interview/{1}/{2}/{3}?" +
                                                                  "format={4}&" +
                                                                  "markedvariables{5}&" +
                                                                  "tempimageurl={6}&" +
                                                                  "encodeFileNames={7}&" +
                                                                  "billingref={8}" +
                                                                  "{9}",
                                                                  HostAddress, SubscriberId, packageId, Uri.EscapeDataString(template.FileName),
                                                                  settings.Format,
                                                                  markedVariables != null && markedVariables.Any()
                        ? "=" + Uri.EscapeDataString(string.Join(",", settings.MarkedVariables))
                        : null,
                                                                  Uri.EscapeDataString(settings.InterviewFilesUrl),
                                                                  true,
                                                                  Uri.EscapeDataString(logRef),
                                                                  GetRetrieveFromHubParam());

                foreach (var kv in settings.Settings)
                {
                    urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                }

                var request = new HttpRequestMessage
                {
                    RequestUri = new Uri(urlBuilder.ToString()),
                    Method     = HttpMethod.Post
                };

                request.Headers.Add("x-hd-date", timestamp.ToString("yyyy-MM-ddTHH:mm:ssZ"));
                request.Headers.Authorization = new AuthenticationHeaderValue("basic", hmac);

                var stringContent = answers == null
                    ? new StringContent(string.Empty)
                    : new StringContent(answers.ReadToEnd());

                request.Content = stringContent;

                var result = client.SendAsync(request).Result;

                HandleStatusCode(result);

                var streamResult = result.Content.ReadAsStreamAsync().Result;

                var parser    = new MultipartMimeParser();
                var outputDir = Path.GetTempPath();
                Directory.CreateDirectory(outputDir);
                var streams = new List <MemoryStream>();

                using (var resultsStream = new MemoryStream())
                {
                    // Each part is written to a file whose name is specified in the content-disposition
                    // header, except for the BinaryObject[] part, which has a file name of "meta0.xml",
                    // and is parsed into an BinaryObject[] object.
                    parser.WritePartsToStreams(
                        streamResult,
                        h =>
                    {
                        var fileName = GetFileNameFromHeaders(h);

                        if (string.IsNullOrEmpty(fileName))
                        {
                            return(Stream.Null);
                        }

                        if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                        {
                            return(resultsStream);
                        }

                        // The following stream will be closed by the parser
                        var stream = new MemoryStream();
                        streams.Add(stream);
                        return(stream);
                    },
                        (new ContentType(result.Content.Headers.ContentType.ToString())).Boundary);

                    if (resultsStream.Position <= 0)
                    {
                        return(null);
                    }

                    resultsStream.Position = 0;
                    var serializer = new XmlSerializer(typeof(BinaryObject[]));
                    var binObjects = (BinaryObject[])serializer.Deserialize(resultsStream);

                    for (var i = 0; i < binObjects.Length; i++)
                    {
                        binObjects[i].Data = streams[i].ToArray();
                        streams[i].Dispose();
                    }

                    var interviewContent = Util.ExtractString(binObjects[0]);
                    return(new InterviewResult {
                        HtmlFragment = interviewContent
                    });
                }
            }
        }
Beispiel #4
0
        public InterviewResult GetInterview(Template template, TextReader answers, InterviewSettings settings,
                                            IEnumerable <string> markedVariables, string logRef)
        {
            using (var client = new HttpClient())
            {
                var    packageTemplateLocation = (PackageTemplateLocation)template.Location;
                string packageId = packageTemplateLocation.PackageID;

                var urlBuilder = new StringBuilder(string.Format(
                                                       HostAddress +
                                                       "/interview/0/{0}/{1}?format={2}&markedvariables{3}&tempimageurl={4}&encodeFileNames={5}",
                                                       packageId, HttpUtility.UrlEncode(template.FileName), settings.Format,
                                                       markedVariables != null
                        ? "=" + HttpUtility.UrlEncode(string.Join(",", settings.MarkedVariables))
                        : null, HttpUtility.UrlEncode(settings.InterviewFilesUrl), true));

                foreach (var kv in settings.Settings)
                {
                    urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                }

                StringContent stringContent = answers == null
                    ? new StringContent(String.Empty)
                    : new StringContent(answers.ReadToEnd());

                HttpResponseMessage result = client.PostAsync(urlBuilder.ToString(), stringContent).Result;

                HandleErrorStream(result, result.IsSuccessStatusCode);
                Stream streamResult = result.Content.ReadAsStreamAsync().Result;
                if (!result.IsSuccessStatusCode)
                {
                    using (var streamReader = new StreamReader(streamResult))
                    {
                        string error = streamReader.ReadToEnd();
                        throw new Exception(error);
                    }
                }

                var    parser    = new MultipartMimeParser();
                string outputDir = Path.GetTempPath();
                Directory.CreateDirectory(outputDir);

                using (var resultsStream = new MemoryStream())
                {
                    // Each part is written to a file whose name is specified in the content-disposition
                    // header, except for the BinaryObject[] part, which has a file name of "meta0.xml",
                    // and is parsed into an BinaryObject[] object.
                    parser.WritePartsToStreams(
                        streamResult,
                        h =>
                    {
                        string fileName = GetFileNameFromHeaders(h);

                        if (!string.IsNullOrEmpty(fileName))
                        {
                            if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                            {
                                return(resultsStream);
                            }
                            // The following stream will be closed by the parser
                            return(new FileStream(Path.Combine(outputDir, fileName), FileMode.Create));
                        }
                        return(Stream.Null);
                    },
                        (new ContentType(result.Content.Headers.ContentType.ToString())).Boundary);

                    if (resultsStream.Position > 0)
                    {
                        resultsStream.Position = 0;
                        var    serializer       = new XmlSerializer(typeof(BinaryObject[]));
                        var    binObjects       = (BinaryObject[])serializer.Deserialize(resultsStream);
                        string interviewContent = Util.ExtractString(binObjects[0]);
                        return(new InterviewResult {
                            HtmlFragment = interviewContent
                        });
                    }
                    return(null);
                }
            }
        }