Get NancyResponse content body before returning the view
Question
is it possible to get the NancyResponse body before returning the View?
I mean this:
Get["/"] = x => {
var x = _repo.X();
var view = View["my_view", x];
**//here I want to send the response body by mail**
return view;
};
Solution
Watch out! this answer is based on nancy version 0.11, a lot has changed since then. The version within the route should still work. The one in the after pipeline not if you use content negotiation.
You could write the contents to a memorystream in the route or you could add a delegate to the After Pipeline:
public class MyModule: NancyModule
{
public MyModule()
{
Get["/"] = x => {
var x = _repo.X();
var response = View["my_view", x];
using (var ms = new MemoryStream())
{
response.Contents(ms);
ms.Flush();
ms.Position = 0;
//now ms is a stream with the contents of the response.
}
return view;
};
After += ctx => {
if (ctx.Request.Path == "/"){
using (var ms = new MemoryStream())
{
ctx.Response.Contents(ms);
ms.Flush();
ms.Position = 0;
//now ms is a stream with the contents of the response.
}
}
};
}
}
OTHER TIPS
View[]
returns a Response
object and that has a Content
property of the type Action<Stream>
so you could pass in a MemoryStream
into the delegate and it would render the view in that stream
I use Nancy version 0.17 and @albertjan solution is based on 0.11.
Thanks to @TheCodeJunkie he introduced me to the IViewRenderer
public class TheModule : NancyModule
{
private readonly IViewRenderer _renderer;
public TheModule(IViewRenderer renderer)
{
_renderer = renderer;
Post["/sendmail"] = _ => {
string emailBody;
var model = this.Bind<MyEmailModel>();
var res = _renderer.RenderView(this.Context, "email-template-view", model);
using ( var ms = new MemoryStream() ) {
res.Contents(ms);
ms.Flush();
ms.Position = 0;
emailBody = Encoding.UTF8.GetString( ms.ToArray() );
}
//send the email...
};
}
}