Using PartialView to create dynamic MainMenu in _Layout Page - Asp.net core razorpage - asp.net-core

i want to using PartialView in My _Layout Page
and this is my PartialView code:
#model List<WebApplication4.Models.MainMenuTable>
#foreach (var item in Model)
{
<li class="nav-item">
<a class="nav-link text-dark" asp-page="#item.Link">#item.Title</a>
</li>
}
and this is my _Layout Page code:
#{
var partialModel = new List<MainMenuTable>()
{
};
}
and:
<partial name="_MainMenu" model="partialModel"/>
but i saw nothing in result why?

Your code is OK, But you need to pass some data into Partial View when you use it in _Layout.cshtml, Refer to this simple demo:
#{
var partialModel = new List<MainMenuTable>()
{
new MainMenuTable
{
Title = "HomePage",
Link = "index"
},
new MainMenuTable
{
Title = "PrivacyPage",
Link = "Privacy"
}
};
}
<partial name="_MainMenu" model="partialModel"/>
When you don't pass any data into Partival View, It will not show in your _Layout.

Related

ASP.NET Core How to open PDF in a new tab?

In my controller I have the following action to create a PDF
public async Task<IActionResult> ExportMailingLabel(int CustomerID, int ProductID)
{
var mailingLabel = await NoticeService.CreateMailingLabel(CustomerID, ProductID);
return File(mailingLabel.NoticeContents, "application/pdf", "MailingLabel.pdf");
}
And In my view i have the following link,
<a asp-action="ExportMailingLabel" asp-controller="Product" asp-area="Product" asp-route-CustomerID="#Model.CustomerID" asp-route-ProductID="#Model.ProductID" class="btn btn-primary"><i class="fa fa-receipt"></i> View Mailing Label</a>
I need help when on click to open the PDF in a new Tab instead of displaying Open Dialog box.
I tried target="_blank" but i seems like it open a new tab but still shows open dialog box
_target="blank" is a simple HTML tag once for all and I think that it works in all browsers as expected. You can use it with a static or dynamic file name as follows.
STATIC FILE NAME USAGE
Controller.cs
public async Task<IActionResult> ExportMailingLabel(int CustomerID, int ProductID) {
var mailingLabel = await NoticeService.CreateMailingLabel(CustomerID, ProductID);
return File(mailingLabel.NoticeContents, "application/pdf");//we don't send 3.parameter yet
}
View.cshtml
<a asp-action="ExportMailingLabel"
asp-controller="Product"
asp-route-CustomerID="#Model.CustomerID"
asp-route-ProductID="#Model.ProductID"
asp-route-FileName="MailingLabel.pdf" class="btn btn-primary" id="btnOpenDocument">
<i class="fa fa-receipt"></i> View Mailing Label
</a>
#section Scripts
{
<script>
//We are opening the file with js instead of action when click to the button
$('#btnOpenDocument').click(function (e) {
e.preventDefault();
window.open('#Url.Action("ExportMailingLabel"
,"Product"
,new {customerId=selectedCustomerId
,productId=selectedProductId
,fileName="MailingLabel.pdf" })'
,"_blank");
});
</script>
}
DYNAMIC FILE NAME USAGE
Controller.cs
//We are adding a new route to action for file name
[HttpGet("[controller]/[action]/{customerId}/{productId}/{fileName}")]
public async Task<IActionResult> ExportMailingLabel(int CustomerID, int ProductID) {
var mailingLabel = await NoticeService.CreateMailingLabel(CustomerID, ProductID);
return File(mailingLabel.NoticeContents, "application/pdf", $"{CustomerID}_{ProductID}.pdf");
}
View.cshtml
<a asp-action="ExportMailingLabel"
asp-controller="Product"
asp-route-CustomerID="#Model.CustomerID"
asp-route-ProductID="#Model.ProductID"
asp-route-FileName="#(Model.CustomerID)_#(Model.ProductID).pdf" class="btn btn-primary" id="btnOpenDocument">
<i class="fa fa-receipt"></i> View Mailing Label
</a>
#section Scripts
{
<script>
//We are opening the file with js instead of action when click to the button
$('#btnOpenDocument').click(function (e) {
e.preventDefault();
window.open('#Url.Action("ExportMailingLabel"
,"Product"
,new {customerId=selectedCustomerId
,productId=selectedProductId
,fileName=selectedCustomerId+"_"+selectedProductId+".pdf" })'
,"_blank");
});
</script>
}
FileContentResult Class

mvc - How to assign a value to a partial view property from withing its parent view

I have a View A, View B, and a View _C.
View _C is a partial view that is rendered inside of View A and B:
View A:
<div style="margin-top:20px;">
<div>
#Html.Partial("~/Views/_C.cshtml", null, new ViewDataDictionary { { "WithRedirect", "true" } });
</div>
</div>
View B
<div style="margin-top:20px;">
<div>
#Html.Partial("~/Views/_C.cshtml", null, new ViewDataDictionary { { "WithRedirect", "false" } });
</div>
</div>
View C(partial view) - code fragment:
.
.
<td style="padding-bottom: 8px;">
#Html.EditorFor(model => model.CurrentPassword, new { htmlAttributes = new { #class = "form-control k-textbox checkError", placeholder = "Enter current password" } })
</td>
.
.
When rendering partial view, I need to set a flag "WithRedirect" to refer to it later in the controller to decide if I need to redirect to another view or not:
string withRedirect = this.ViewData.ContainsKey("WithRedirect") ? this.ViewData["WithRedirect"].ToString() : string.Empty;
if(WithRedirect.Equals("true")
return Redirect(returnUrl ?? Url.Action("Index", "Page1"));
else
return Redirect(returnUrl ?? Url.Action("Index", "Page2"));
When debugging the controller, WithRedirect variable is an empty string.
What am I doing wrong and what is the solution?
Inside your partial view(_C.cshtml), you can read the value from ViewDataDictionary and set to an input field inside a form. When you submit the form, this value will be also submitted. You can have a parameter in your http post action method which will receive this input field value and using that you can conditionally redirect to page1 or page 2.
#model LoginViewModel
#using (Html.BeginForm("Login","Home"))
{
<input type="hidden" name="withRedirect" value="#ViewData["WithRedirect"]" />
#Html.LabelFor(f=>f.Password)
#Html.TextBoxFor(x=>x.Password )
<input type="submit" />
}
and now in your action method
[HttpPost]
public ActionResult Login (LoginViewModel model,bool withRedirect)
{
//to do : Do something
if(withRedirect)
{
return RedirectToAction("Index","Page1");
}
return RedirectToAction("Index","Page2");
}

How to render (image) data from the model in the view?

That's my controller action
public ActionResult ViewImage(int? productId){
var image = (from x in db.Images
where (x.ProductId == productId)
select x).ToList();
return View(image);
}
And that's my view
#model
#{
ViewBag.Title = "ViewImage";
}
<h2>Uploaded pictures</h2>
<div>
<br>
<img height="300" width="350 " src="#Model" />
</div>
<div>
<br>
#Html.ActionLink("Back to Index","Index","Products")
</div>
I don't know what I have to put after #model . I tried to put the type of image but not work!
you need to send the type of model
#model List<Images>
Add following property to the model class and add images to it.
public IEnumerable<HttpPostedFileBase> AttachImages { get; set; }
try to use ViewBag.Image instead of var image:
public ActionResult ViewImage(int? productId){
Viewbag.Image image = (from x in db.Images
where (x.ProductId == productId)
select x).ToList();
return View(image);
}
Now in your view:
#{
ViewBag.Title = "ViewImage";
}
<h2>Uploaded pictures</h2>
<div>
<br>
#foreach(var image in Viewbag.Image)
{
<img height="300" width="350 " src="#image" />
}
</div>
<div>
<br>
#Html.ActionLink("Back to Index","Index","Products")
</div>
Hope this helps
You should have a controller action that is streaming the image to the response:
public ActionResult Image(int imageId)
{
var image = db.Images.SingleOrDefault(x => x.Id == imageId);
if (image == null)
{
return HttpNotFound();
}
byte[] imageData = image.Data; // or whatever byte[] property you have
string contentType = "image/jpg"; // or if you have stored the content type in your DB simply assign it to image.ContentType
return File(imageData, contentType);
}
OK, with this handy method in place you could update your view:
#model IList<WebApplication1.Image>
<h2>Uploaded pictures</h2>
<div>
#foreach(var image in Model)
{
<img height="300" width="350 " src="#Url.Action("Image", "SomeController", new { imageId = image.Id })" />
}
</div>
Notice how the src property of the image is pointing to the controller action we have implemented previously and which will get the image and stream it to the response.

MVC4 Web Grid Sorting and Pagination Issue

I am using Web Grid in MVC4 web application. I have a search functionality in the page. Web grid works fine i.e Sorting and Paging works fine until there is no search performed. When a search is performed, then sorting the web grid does not sort those searched results alone but sorts the entire list of items.
I debugged and found that during click of Web grid header for sorting, it redirects to HttpGet method and not HttpPost.I am pretty sure that if HTTPPOST is hit, then this problem would vanish.
I tried searching in google but could not find any specific answers. Any help or pointers would be greatly appreciated. Hope I am clear on my problem.
Controller:
public ActionResult Index()
{
var item = GetAllActors();
return View(item);
}
[HttpPost]
public ActionResult Index(string SearchContion, FormCollection collection)
{
var item = GetAllActors();
List<ActorBE> listOfItems = new List<ActorBE>();
if (item != null && collection != null)
{
if (!string.IsNullOrEmpty(SearchContion))
{
List<string> searchResults = item.FindAll(s => s.ActorName.IndexOf(SearchContion, StringComparison.OrdinalIgnoreCase) >= 0).Select(p => p. ActorName).ToList();
foreach (var data in searchResults)
{
ActorBE actor = new ActorBE ();
actor = item.Where(l => l.ActorName == data).FirstOrDefault();
listOfItems.Add(actor);
}
return View(listOfItems);
}
else
{
return View(item);
}
}
else
{
return View();
}
}
View:
#model IEnumerable<Tool.DataService.ActorBE>
#{
ViewBag.Title = "Actor";
Layout = "~/Views/Shared/_Layout.cshtml";
WebGrid grid = new WebGrid(rowsPerPage: 50, canPage: true, canSort: true);
grid.Pager(WebGridPagerModes.All);
grid.Bind(Model, rowCount: Model.ToList().Count());
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<div style="padding: 2px 2px 2px 2px;">
<fieldset>
<legend>Search</legend>
<header>
<div class="content-wrapper">
<div class="float-left">
<label style="display:inline;margin-right:5px">Actor Name</label>
#Html.TextBox("SearchContion")
<input type="submit" value="Search" name="Search" style="border-radius:5px;margin-left:5px;"/>
</div>
</div>
</header>
</fieldset>
</div>
#grid.GetHtml(htmlAttributes: new
{ id = "grid" },
tableStyle: "webgrid",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
firstText:"First",
lastText:"Last",
nextText:"Next",
mode: WebGridPagerModes.All,
previousText:"Previous",
rowStyle: "webgrid-row-style", columns: grid.Columns
(
grid.Column("ActorID",header:"Actor ID, style:"column", canSort:true),
grid.Column("ActorName",header:"Actor Name", style:"width:200px", canSort:true),
grid.Column
("",
header:"Actions",
format:#<text>
#Html.ActionLink("Edit", "Edit", new { id = item.ActorID })
#if (item.IsActive)
{
#Html.ActionLink("Deactivate", "Delete", new { id = item. ActorID })
}
</text>
)
)
)
}
When user searches some actor name, the search results are happening properly. Once search is over, when the user clicks on web grid headers, then search results are not retained properly but the control again goes to HttpGET Method and not to the HTTPPOST Method. This s the main problem.
Guide me on how to solve this problem
As a work around what you can do is when search is performed save the state of the Grid on server so that you can check for it while rendering the grid again, a similar question was answered here https://stackoverflow.com/a/15528219/335105

Dynatree - 2 links per node?

Does anyone know if it's possible to make the DynaTree jquery plugin handle two HREF links per node?
I have one link working fine but I'm also looking at a request to display a "contacts" image on the right-hand side of each clickable node which, when clicked produces a popup (I know, not my design) of other users working on the same item.
I can display the image fairly easily using a SPAN tag but since the existing HREF is the one trapped by OnActivate, I'm having real trouble making it do anything.
All advice welcomed.
I discovered a better way.
<script type="text/javascript">
$(function () {
$("#tree").dynatree({
initAjax: {
type: "POST",
url: "TreeView/GetNodes"
// This gets data from an MVC3 controller
// in the form of a serialised list of nodes
// with custom attributes.
},
//here's the meat of it -
// elements are created and added
// according to the custom data values in the node
onRender: function (node, nodeSpan) {
if (node.data.hasPostImage) {
var postImg = document.createElement('img');
postImg.setAttribute('src', node.data.postImageUrl);
postImg.setAttribute('class', node.data.postImageClass);
postImg.setAttribute('alt', node.data.postImageAltText);
postImg.setAttribute('onClick', 'javascript:loadContacts(\'' + node.data.postImageScriptHref + '\');');
// the element is then appended to the Anchor tag (title)
// using jquery.after.
// it works really well, except for IE7. Working on that now.
$(nodeSpan).find('.dynatree-title').after(postImg);
}
},
onClick: function (node) {
node.toggleExpand();
}
});
});
</script>
I noticed that outputting the tree directly allowed me to embed an image tag in the structure as follows -
<div id="tree">
<ul id="treeData" style="display: none;">
#foreach (var provider in Model.Locations)
{
<li class="folder" data="icon: 'false', addClass: 'root-node'">#provider.Provider
<ul>
#foreach (var profession in provider.ChildLocations)
{
<li id="#profession.Id">#profession.Profession <img class="contactsImg" onclick="loadContacts();" src="../../Content/themes/default/images/icons/contacts.png" />
<ul>
#foreach (var formtype in profession.ChildLocations)
{
<li class="folder" id="#formtype.Id" data="addClass: 'progress-bar'">#formtype.Type
<ul>
#foreach (var form in formtype.ChildLocations)
{
<li id="#form.Id" data="addClass: 'progress-bar'">#Ajax.ActionLink(form.Form, "PartialIndex", "FormCover", new { Id = form.formId }, new AjaxOptions { UpdateTargetId = "contentpanel" })
<ul>
#foreach (var lo in form.ChildLocations)
{
<li id="#lo.Id" data="addClass: 'action-required'">#Ajax.ActionLink(lo.Name, "ActualFormTab", new {formid = form.formId, layoutid = lo.formId}, new AjaxOptions{ UpdateTargetId = "contentpanel"})</li>
}
</ul>
</li>
}
</ul>
</li>
}
</ul>
</li>
}
</ul>
</li>
}
</ul>
</div>
And that, as demonstrated, it was pretty straightforward to add an OnClick event to the image.