how build dynamic layout mvc 4? - asp.net-mvc

how return razor code for layout of view instead of master page name
for example instead of
return View("Index", "_Layout");
use this code
return View("Index", #"
#using System.Diagnostics
#using iaumahallat.Helper
<!DOCTYPE html>
<html lang="en">
<head>
<title>#ViewBag.SiteTitle - #ViewBag.Title</title>
<meta name="description" content="#ViewBag.MetaDescription">
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
");

One way is to use RazorEngine and parse the razor source code, then get the corresponding Html String to display it on the view or layout-
Razor.SetTemplateBase(typeof(HtmlTemplateBase<>));
string template =
#"<html>
<head>
<title>Hello #Model.Name</title>
</head>
<body>
Email: #Html.TextBoxFor(m => m.Email)
</body>
</html>";
var model = new PageModel { Name = "World", Email = "someone#somewhere.com" };
string result = Razor.Parse(template, model);
Then use result in the page of your interest.

Related

Open Rotativa print dialog automatically

I am using Rotativa to generate a PDF of a view with the intention of printing it.
I have the following code
public ActionResult PrintTicket(string tempTickID)
{
//var tick = ctx.vw_printTicket.Where(e => e.noTicket == tempTickID).FirstOrDefault();
// return View(tick);
var report = new ActionAsPdf("PrepareTicket", new { tempTickID = tempTickID });
return report;
}
ActionAsPdf allows me to open the "PrepareTicket" view as a pdf and then I can print.
Problem
The problem for me is this, The pdf takes over my entire page and while I can print I don't have access to my program's menus anymore cause it's now a PDF view.
Questions
Is it possible that I call the print dialog automatically instead of showing the pdf?
I think will work for my situation.
Regards
Hi I have tried to create a sample which will solve your issue.
Model
public class Ticketinfo
{
public string name { get; set; }
public int quantity { get; set; }
}
Created a Controller which has 3 Action Method
public class GenerateController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult PrintTicket(string tempTickID)
{
return new ActionAsPdf("RotativaPartialViewAsPdf", new { tempTickID = tempTickID });
}
public ActionResult RotativaPartialViewAsPdf(string tempTickID)
{
Ticketinfo Ticketinfo = new Ticketinfo()
{
name = "Demo",
quantity = 5
};
return PartialView("_RotativaPartialViewAsPdfl", Ticketinfo);
}
}
Partial View
#model WebApplication6.Models.Ticketinfo
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="~/Content/bootstrap.css" rel="stylesheet" />
</head>
<body>
<div class="container">
<table class="table">
<tr class="info">
<td>Lot</td>
<td>Name</td>
<td>Quantity</td>
</tr>
<tr class="success">
<td>#Model.name</td>
<td>#Model.quantity</td>
</tr>
</table>
</div>
</body>
</html>
Index View
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<iframe src="#Url.Action("PrintTicket", "Generate", new {tempTickID = "1"})"
width="800px" height="600px">
</iframe>
</div>
</body>
</html>
Output

cant pass current Date & Time using Viewdata in mvc

i am new in MVC.I try to pass Current Date & Time by using Viewdata.But it does not get my code is here
namespace FirstHelloWorldProjct.Controllers
{
public class HelloWorldController : Controller
{
//
// GET: /HelloWorld/
public ActionResult Index()
{
ViewData["CurrentTime"] = DateTime.Now.ToString();
return View();
}
}
}
And my View Code here
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
This is Hello World...<br/>
The Current Date and time is <%= ViewData["CurrentTime"]%>
</div>
</body>
</html>
And output is here
This is Hello World...
The Current Date and time is <%= ViewData["CurrentTime"]%>
I think In Asp.net MVC we use Razor syntax as metion below.
you need to use #ViewData["CurrentTime"] instead of <%= ViewData["CurrentTime"]%>

Error of populating menu items permenantly and unwantedly in each postback in MVC

I have a problem. In order to make it understandable, I want to denote my layout. layout is as follows:
Menu side is implemented by NavController. Here is the content of the NavController:
public class NavController : Controller
{
private IProductRepository repository;
public NavController(IProductRepository repo) {
repository = repo;
}
[ChildActionOnly]
public PartialViewResult Menu(string category = null)
{
ViewBag.SelectedCategory = category;
//IEnumerable<string> categories = repository.Products
//.Select(x => x.ProductCategory)
//.Distinct()
//.OrderBy(x => x);
IEnumerable<string> categories = Actions.GetirTumAksiyonları();
return PartialView(categories);
}
}
At the Menu action method, some strings populated and become visible at the Menu side.
There are many controllers defined in my project that manipulates the Content of the project, and they have buttons that post back to server. Whenever I click at one of these buttons, menu strings permenantly populated. Here is my _Layout.cs:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title</title>
<link href="~/Content/Site.css" type="text/css" rel="stylesheet" />
<link href="~/Content/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-ui-1.8.24.min.js"></script>
</head>
<body>
<div id="header">
<div class="title">Lojman Bilgi Sistemi</div>
</div>
<div id="categories">
#{ Html.RenderAction("Menu", "Nav"); }
</div>
<div id="content">
#RenderBody()
</div>
How can I overcome the issue? thanks in advance.
You can write your Menu method this way. Cheers :)
[ChildActionOnly]
public PartialViewResult Menu(string category = null)
{
// Logic
}

How do i display the response(html) from webclient in my asp.net mvc view

I'm faking a form post using webclient like this:
public static string SendHttpRequest(string url, string method, List<WebParameter> paramaters)
{
using(WebClient client = new WebClient())
{
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
System.Collections.Specialized.NameValueCollection reqparm = new System.Collections.Specialized.NameValueCollection();
foreach (var param in paramaters)
{
reqparm.Add(param.name, param.value);
//reqparm.Add("param2", "escaping is already handled");
}
byte[] responsebytes = client.UploadValues(url, method, reqparm);
string responsebody = Encoding.UTF8.GetString(responsebytes);
return responsebody;
}
}
Its working well so far but the response is an html page. i want to embed this page inside my view.
My controller action looks like this
string response = SendHttpRequest(purl,"POST",param);
ViewBag.Response = response;
return View();
In my view when i called ViewBag.Response its showing me the raw html. This is not what i want. i want to display the page.
I'm thinking i can do this with an iframe but dont have idea how.
EDIT:
the expected response looks like this:
<!DOCTYPE html> <html> <head> <link rel='shortcut icon' type='image/x-icon' href='/test_paydirect/favicon.ico' /> <meta name="viewport" content="width=device-width, initial-scale = 1, maximum-scale=1, user-scalable=no" /> <title>WebPAY</title> <link href="/test_paydirect/Content/webpay?v=CSrAVoCR_RCkIRW_2W4qWDLY74gqncHw6gTHkYQDqPI1" rel="stylesheet"/> <script src="/test_paydirect/scripts/jquery?v=YDYC4uCmpbLIjqOyVNC_2sd9YbHnRonWjUni8iH6_Xo1"></script> </head> <body> <div id="outer-frame"> <div id="page-header"> <div id="account-header"> </div> </div> <!--page logo header starts--> <div id="page-logo-header" class=""> <div id="page
Have you tried this in your view?:
#Html.Raw(ViewBag.Response)
By default the string will be HTML encoded to prevent script injection.

Registering Javascript / CSS files within Partial Views with Output Caching only once

I would like to create partial views which would require the inclusion of Javascript/CSS files in order to function properly. The same partial view can be included multiple times within a page and hence if I put the embedding of the Javascript/CSS files within the Partial View HTML content, such files will be embedded N amount of times. I would want such files to be embedded only once.
Also, such Partial Views are being rendered using the Html.Action method so as to make use of output caching so the Action method will not execute all the time.
My idea was to register the javascript/css files within the Partial View with with some controller which manages such embedding and then outputs them at the scripts section of the page, at the bottom before the end </body> tag but since the Actions will be cached, such code is not guaranteed to be executed but can be loaded from Cache.
Any suggestions for best practices for such scenario?
You could define 2 custom helpers:
public static class HtmlExtensions
{
public static IHtmlString RenderRegisteredScripts(this HtmlHelper htmlHelper)
{
var ctx = htmlHelper.ViewContext.HttpContext;
var registeredScripts = ctx.Items["_scripts_"] as Stack<string>;
if (registeredScripts == null || registeredScripts.Count < 1)
{
return null;
}
var sb = new StringBuilder();
foreach (var script in registeredScripts)
{
var scriptBuilder = new TagBuilder("script");
scriptBuilder.Attributes["type"] = "text/javascript";
scriptBuilder.Attributes["src"] = script;
sb.AppendLine(scriptBuilder.ToString(TagRenderMode.Normal));
}
return new HtmlString(sb.ToString());
}
public static void RegisterScript(this HtmlHelper htmlHelper, string script)
{
var ctx = htmlHelper.ViewContext.HttpContext;
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var registeredScripts = ctx.Items["_scripts_"] as Stack<string>;
if (registeredScripts == null)
{
registeredScripts = new Stack<string>();
ctx.Items["_scripts_"] = registeredScripts;
}
var src = urlHelper.Content(script);
if (!registeredScripts.Contains(src))
{
registeredScripts.Push(src);
}
}
}
and then have a _Layout.cshtml in which you are calling the RenderRegisteredScripts helper at the end:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>
<body>
#RenderBody()
<script src="#Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
#RenderSection("Scripts", required: false)
#Html.RenderRegisteredScripts()
</body>
</html>
Now you could have a view which renders some partial as many times as you like:
#for (int i = 0; i < 10; i++)
{
#Html.Partial("_Foo")
}
#Html.Action("Bar")
and inside this partial (_Foo.cshtml) use the RegisterScript helper to register dependent scripts for this partial:
#{Html.RegisterScript("~/scripts/foo.js");}
Now when you look at the generated HTML markup the script is included only once:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<script src="/Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="/scripts/foo.js" type="text/javascript"></script>
</body>
</html>

Resources