Welcome Guest Search | Active Topics | Sign In | Register

ASP.NET MVC5 with OWIN Options
Cypress North
Posted: Thursday, April 2, 2015 11:21:16 AM
Rank: Newbie
Groups: Member

Joined: 5/28/2014
Posts: 9
I've been unable to get the MVCToPDF conversion to work on a new project using the latest version of Microsoft.Owin.Security as our authentication mechanism. We have version 5.0.84.2 of the EO.Pdf library.

Every attempt at generating a PDF, even the simplest examples result in the following error:

Quote:
Exception information:
Exception type: HttpException
Exception message: Server cannot append header after HTTP headers have been sent.
at System.Web.HttpHeaderCollection.SetHeader(String name, String value, Boolean replace)
at System.Web.HttpHeaderCollection.Set(String name, String value)
at Microsoft.Owin.Host.SystemWeb.CallHeaders.AspNetResponseHeaders.Set(String key, String[] values)
at Microsoft.Owin.Host.SystemWeb.CallHeaders.AspNetResponseHeaders.set_Item(String key, String[] value)
at Microsoft.Owin.Infrastructure.OwinHelpers.SetHeaderUnmodified(IDictionary`2 headers, String key, String[] values)
at Microsoft.Owin.Infrastructure.OwinHelpers.AppendHeaderUnmodified(IDictionary`2 headers, String key, String[] values)
at Microsoft.Owin.HeaderDictionary.AppendValues(String key, String[] values)
at Microsoft.Owin.Infrastructure.ChunkingCookieManager.AppendResponseCookie(IOwinContext context, String key, String value, CookieOptions options)
at Microsoft.Owin.Security.Cookies.CookieAuthenticationHandler.<ApplyResponseGrantAsync>d__f.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseCoreAsync>d__b.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<TeardownAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware`2.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware`2.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware`2.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware`2.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContextStage.<RunApp>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.<DoFinalWork>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow()
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar)
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar)
at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
eo_support
Posted: Thursday, April 2, 2015 1:13:34 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,196
Hi,

You will need to configure your route so that Owin does not touch the route that generates PDF file. A quick search yielded this page that you may find useful:

http://www.strathweb.com/2014/04/ignoring-routes-asp-net-web-api/

Thanks!
Cypress North
Posted: Thursday, April 2, 2015 3:59:47 PM
Rank: Newbie
Groups: Member

Joined: 5/28/2014
Posts: 9
Yes, that does seem to be what needs to be done. Owin is expecting an auth cookie with the request but it doesn't look like the cookies exist when the PDF generation process makes the request.

The link provided is for ignoring routes entirely so that they can be handled by the WebApi routes instead (or served static files). I can't for the life of me figure out how to get Owin to ignore authenticating a specific route.

Is there any way for the PDF request to be made using the current user making the Http request or to include the domain cookies?
eo_support
Posted: Thursday, April 2, 2015 5:14:24 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,196
Hi,

You can pass the request cookies to the PDF converter through HtmlToPdf.Options.Cookies. However it looks that the the problem is with the response cookies, not request cookies. That part would depends on when you send the PDF file down to the client. We are not familiar with OWin but it appears that it tries to send down a cookie with a response where the code has already started to write Response.OutputStream. At that time it's too late to send HTTP header to the client since the server has already started to send the body down to the client (in this case the PDF file content). So the key for this is to start sending the file after OWin has done it's business. If that's not possible, then you may wish to consider use a single page/Url to send the PDF file down to the client browser and exclude that from the route entirely.

Thanks!
Cypress North
Posted: Thursday, April 2, 2015 5:37:38 PM
Rank: Newbie
Groups: Member

Joined: 5/28/2014
Posts: 9
I think it turned out to be a cookie issue after all. I've got it working without messing with OWIN, however I have one more question. How can I apply formatting to the RenderedPDF before returning it to the client? I've tried the following:

Quote:
[Route("{id:int}/print")]
[EO.Pdf.Mvc5.RenderAsPDF(AutoConvert = false)]
public ActionResult Print(int id, bool pdf = false)
{

using (BillingContext ctx = new BillingContext())
{
InvoiceService invoiceService = new InvoiceService(ctx);
Invoice invoice = invoiceService.Get(id);
if (invoice == null || invoice.accountId != currentUser.accountId.Value)
{
throw new HttpException((int)HttpStatusCode.BadRequest, "Invoice not found");
}

PrintViewModel model = new PrintViewModel(currentUser, invoice);

if (pdf)
{
HtmlToPdf.Options.PageSize = EO.Pdf.PdfPageSizes.A4;
HtmlToPdf.Options.OutputArea = new System.Drawing.RectangleF(0.25f, 0.25f, 8f, 10.5f);

MVCToPDF.SendToClient = true;
MVCToPDF.ResultAsDownload = true;
MVCToPDF.AutoFormsAuthentication = true;
MVCToPDF.ResultFileName = id + ".pdf";
MVCToPDF.RenderAsPDF();
}

return View("~/Views/Invoice/Print.cshtml", model);
}

}


If I need to set SendToClient = false and override OnResultExecuted, how do I return the result to the client once I've set the options? Thank you!
Cypress North
Posted: Thursday, April 2, 2015 5:44:27 PM
Rank: Newbie
Groups: Member

Joined: 5/28/2014
Posts: 9
Never mind, that's working. It's been a long day :( thanks for your help
eo_support
Posted: Thursday, April 2, 2015 10:24:25 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,196
Great. Glad to hear that it's working!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.