I am coding a MVC5 internet application and I am trying to pass an object from a View to a ActionResult.
The parameter of the ActionResult is an AssetItem called assetItem.
Here is the function definition:
public ActionResult DeleteAssetFile(AssetItem assetItem)
Here is my View code:
<ul style="list-style-type: none; padding:0;">
#foreach (var item in Model.assetItems)
{
<li>
<img src="#item.blobItem.Uri.ToString()" alt="item" width="100" height="100" />
#Html.ActionLink("Delete", "DeleteAssetFile", new { assetItem = item })
</li>
}
</ul>
The assetItem in the DeleteAssetFile ActionResult is null.
Can I please have some help with this?
Thanks in advance
Related
I'm new to mvc and am trying to figure out how to create an approve button on an index view. Some clarification is needed.
There is a question here already about creating an Approve/Unapprove button in an mvc view. But after reviewing it, it appears to be missing information. The controller is expecting the SubmitButton and the ID to be passed to it. This I understand. But the view's submit buttons only sends the SubmitButton with no ID. Can someone please clear the fog? Thank you.
Controller
[ActionName("Index")]
[HttpPost]
public ActionResult IndexPost(string SubmitButton, int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
string buttonClicked = SubmitButton;
if(buttonClicked == "Approve")
{
CurrentApplication currentApplication = db.CurrentApplications.Find(id);
currentApplication.AppStatus = "APPROVED";
db.SaveChanges();
}
else if(buttonClicked == "Unapprove")
{
CurrentApplication currentApplication = db.CurrentApplications.Find(id);
currentApplication.AppStatus = "UNAPPROVED";
db.SaveChanges();
}
//Save Record and Redirect
return RedirectToAction("Index");
}
View
<button type="submit" name="SubmitButton" value="Approve" class="btn btn-sm btn-success">Approve</button>
<button type="submit" name="SubmitButton" value="Unapprove" class="btn btn-sm btn-danger">Unapprove</button>
The controller will them update the database with the status change and return the Index to reflect the changes.
According to your newest example, here is the best answer I can think. At first, your code example has a few syntax errors and I needed to create own macaddress -class. I hope its similar than yours.
I used the same example than in my earlier answer. I only modified view and created maccaddress -class. The controller is same as earlier.
Modified View
This is the important part. I think you just have formatted Html form and tables in weird way. Here is a screenshot of how the view is rendered.
Now when user click Approve or Unapprove the form will send maccaddress id and button value to the controller IndexPost -action.
In a view example:
table is made just for example, modify it if needed.
I changed foreach location, now it is before Html.BeginForm. In your example, BeginForm was outside foreach and that caused a few problems when submitting your code. In a way how your form was rendered, it was impossible to know which Id is submitted.
Look #Html.Hidden("id", item.idMACAddress). It should be inside BeginForm.
I have only print id and status into a table for example purposes.
Action buttons are in the third column.
So why it works now is the way Form is rendered. In the example, there is now one html form for every maccaddress row. When a button is clicked, we know exactly what values we want to send into the controller.
#model IEnumerable<MySQL_MACAddress.Models.macaddress>
#{ ViewBag.Title = "Index"; }
<table class="table">
<tr>
<th> MAC Address </th>
<th> Status </th>
<th> Actions </th>
</tr>
#foreach (var item in Model)
{
using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.Hidden("id", item.idMACAddress)
<tr>
<td> #item.idMACAddress </td>
<td> #item.Status </td>
<td>
<button type="submit" name="SubmitButton" value="Approve" class="btn btn-sm btn-success">Approve</button>
<button type="submit" name="SubmitButton" value="Unapprove" class="btn btn-sm btn-danger">Unapprove</button>
</td>
</tr>
}
}
</table>
maccaddress.cs example
Check this example. Don't just copy it because probably it won't work with your code. The view is a more important part here so look it.
using System;
namespace MySQL_MACAddress.Models
{
public class macaddress
{
public macaddress()
{
}
public string Status { get; set; }
public int idMACAddress { get; set; }
}
}
Controller
Check earlier answer.
I suppose you have an HTML form in View made with Html-helpers. In your case, the following example code is probably the simplest one.
View - Home/Index.cshtml
<h2>Welcome to ASP.NET MVC!</h2>
<!--
If needed, check BeginForm parameters to send POST
into right controller and action.
-->
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<!-- second parameter is the value for id field. -->
#Html.Hidden("id", 2001)
<button type="submit" name="SubmitButton" value="Approve" class="btn btn-sm btn-success">Approve</button>
<button type="submit" name="SubmitButton" value="Unapprove" class="btn btn-sm btn-danger">Unapprove</button>
}
Controller - HomeController.cs
using System.Net;
using System.Web.Mvc;
namespace FormTest.Controllers
{
public class HomeController : Controller
{
// GET action for index
public ActionResult Index()
{
// Do something here ...
return View();
}
// POST action for index.
// Will use same path as GET
[HttpPost]
[ActionName("Index")]
public ActionResult IndexPost(string SubmitButton, int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (SubmitButton == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//Redirect to GET Index
return RedirectToAction("Index");
}
}
}
The important part is the Hidden helper that will generate a hidden input field. If you need more modifications in your use case, read more here about parameters and examples.
#T.Nylund , Your thoughts? Thank you.
View
#model Enumerable<MySQL_MACAddress.Models.macaddress>
#{ ViewBag.Title = "Index"; }
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Status)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#HtmlHidden("id", item.idMACAddress)
</td>
<td>
#Html.DisplayFor(modelitem => item.Status)
</td>
<button type="submit" name="SubmitButton" value="Approve" class="btn btn-sm btn-success">Approve</button>
<button type="submit" name="SubmitButton" value="Unapprove" class="btn btn-sm btn-danger">Unapprove</button>
}
We use different controller methods for the different actions when approving (button to approve, button to reject)
Our view:
if (!Model.IsApproved)
{
<td>
#using (Html.BeginForm("Approve", "BudgetItem", new { id = Model.BudgetItemSid, role = Model.ActiveRole }, FormMethod.Post))
{<button type="submit" id="btnApprove" style="display: none;">Approve</button>}
</td>
}
if (!Model.IsRejected)
{
<td>
#using (Html.BeginForm("Reject", "BudgetItem", new { id = Model.BudgetItemSid, role = Model.ActiveRole }, FormMethod.Post))
{<button type="submit" id="btnReject" style="display: none;">Reject</button>}
</td>
}
Our Controller:
[HttpPost]
public ActionResult Approve(int id, EnumRole role)
{
}
[HttpPost]
public ActionResult Reject(int id, EnumRole role)
{
}
I am trying to get some more information about Razor Pages with core 2.0 and I am having some issues with the post. Please note, this is not production worthy, its just code to try and getting a better understanding of what you can do in razor pages.
The issue is, if my button is in the form, it does not send any data back to the view. So, computedURL in OnPostConcatURL() is never getting to the view.
If the button is outside the form, the form data does not get to the post controller OnPostEdit23 but I can send back ComputedURL to the view. Clearly I am missing something or a lot. And I cannot find an example to fix this.
#page
#model VisibilityTest
#{ ViewData["Title"] = "Visibility Test Site"; }
<form id="frmVisibility" method="post">
<div class="container">
<div class="row form-group">
<div class="col-md-1"> Select Portal: </div>
<div class="col-md-1"><select id="ddlEnvironment" asp-for="selectedEnvironment" asp-items="Model.Environments"></select></div>
<div class="col-md-2"><select id="ddlPortalName" asp-for="selectedPortalName" asp-items="Model.portalNames"></select></div>
<div class="col-md-3"><input asp-for="#Model.ComputedURL" /></div>
</div>
<div class="row form-group">
<div class="col-md-1"><button id="btnConcatURL" asp-page-handler="ConcatURL" type="submit" class="btn btn-primary">Submit23</button></div>
</div>
</div>
</form>
<form method="post">
<button asp-page-handler="edit23" class="btn btn-default">Edit2</button>
</form>
[BindProperty]
public string ComputedURL { get; set; }
public void OnGet()
{
config = GetConfigFile();
PopulatedEnvironmentSelectList();
PopulatePortalNameSelectList(config);
}
public IActionResult OnPost()
{
ComputedURL = selectedEnvironment + selectedPortalName;
return RedirectToPage("./VisibilityTest");
}
public void OnPostConcatURL()
{
ComputedURL = "this is a test";
}
public void OnPostEdit23()
{
ComputedURL = "this is a test";
}
I'm still figuring out Razorpages as well but I noticed a couple of points about your example:
The Model should be the code behind page class not some other object.
The BindProperty should probably be to an object and not just a string (or you can bind to multiple properties on the code-behind object)
If you want to pass back just a message (string) you can use temp data.'
You definitely want the button inside the form as it will populate the model properties with form values (but as with #2 the binding property should be more than a simple string).
So your example modified example below seems to do what you are looking for (I simplified the dropdowns to text fields for easy testing).
.cshtml page
#page
#model VisibilityTestModel
#{
ViewData["Title"] = "Visibility Test Site";
}
<hr />
<form id="frmVisibility" method="post">
<div class="container">
<div class="row form-group">
<div class="col-md-1"> Select Portal: </div>
<div class="col-md-3"><input asp-for="#Model.Portal.Environment" /></div>
<div class="col-md-3"><input asp-for="#Model.Portal.Name" /></div>
<div class="col-md-3">#Model.Portal.ComputedURL</div>
</div>
<div class="row form-group">
<div class="col-md-1"><button id="btnConcatURL" asp-page-handler="ConcatURL" type="submit" class="btn btn-primary">Submit23</button></div>
</div>
</div>
</form>
<h3>Msg: #Model.Message</h3>
.cshtml.cs page:
public class VisibilityTestModel : PageModel {
[BindProperty]
public PortalInfo Portal { get; set; }
[TempData]
public string Message { get; set; }
public void OnGet() {
Portal = new PortalInfo {
Environment = "www.example.com",
Name = "test"
};
}
public void OnPostConcatURL() {
Portal.ComputedURL = Portal.Environment + " " + Portal.Name;
Message = "URL concat";
}
}
public class PortalInfo {
public string Environment { get; set; }
public string Name { get; set; }
public string ComputedURL { get; set; }
}
Can i display reference products with gallery images in hybris?
I am trying to retrieve images from controller but value in jsp page is always empty
#RequestMapping(value = PRODUCT_CODE_PATH_VARIABLE_PATTERN, method = RequestMethod.GET)
public String productDetail(#PathVariable("productCode") final String productCode, final Model model,
final HttpServletRequest request, final HttpServletResponse response) throws CMSItemNotFoundException,
UnsupportedEncodingException
{
final ProductModel productModel = productService.getProductForCode(productCode);
final String redirection = checkRequestUrl(request, response, productModelUrlResolver.resolve(productModel));
if (StringUtils.isNotEmpty(redirection))
{
return redirection;
}
updatePageTitle(productModel, model);
populateProductDetailForDisplay(productModel, model, request);
model.addAttribute(new ReviewForm());
final List<ProductReferenceData> productReferences = productFacade.getProductReferencesForCode(productCode,
Arrays.asList(ProductReferenceTypeEnum.SIMILAR, ProductReferenceTypeEnum.ACCESSORIES),
Arrays.asList(ProductOption.BASIC, ProductOption.PRICE, ProductOption.GALLERY), null);
try
{
for (int i = 0; i < productReferences.size(); i++)
{
final List<Map<String, ImageData>> imageDataList = getGalleryImages(productReferences.get(i).getTarget());
final List<ImageData> imdData = new ArrayList<ImageData>();
for (int j = 0; j < imageDataList.size(); j++)
{
final ImageData sgImage = imageDataList.get(j).get("product");
if (sgImage != null)
{
imdData.add(sgImage);
}
}
productReferences.get(i).setPreviewImages(imdData);
}
}
catch (final Exception e)
{
e.printStackTrace();
}
//model.addAttribute("imageDataList", imageDataList);
model.addAttribute("productReferences", productReferences);
model.addAttribute("pageType", PageType.PRODUCT.name());
final String metaKeywords = MetaSanitizerUtil.sanitizeKeywords(productModel.getKeywords());
final String metaDescription = MetaSanitizerUtil.sanitizeDescription(productModel.getDescription());
setUpMetaData(model, metaKeywords, metaDescription);
return getViewForPage(model);
}
I have extended the product reference data class and added a new property
<bean
class="de.hybris.platform.commercefacades.product.data.ProductReferenceData">
<property name="previewImages"
type="java.util.List<de.hybris.platform.commercefacades.product.data.ImageData>" />
</bean>
Finally in the jsp page i am trying to display it
<section class="featured-products">
<h4>${component.title}</h4>
<div class="features-product-block">
<div class="features-product carousel jcarousel-skin">
<c:forEach end="${component.maximumNumberProducts}"
items="${productReferences}" var="productReference">
<c:url value="${productReference.target.url}/quickView"
var="productQuickViewUrl" />
<div class="items">
<div class="each-product">
<div id="featuredprimaryPhoto" class="detailsPhotoWrap">
<a href="${productQuickViewUrl}" class="popup scrollerProduct">
<div class="thumb">
<product:productPrimaryImage
product="${productReference.target}" format="product" />
</div>
<h5>
<c:if test="${component.displayProductTitles}">
<span>${productReference.target.name}</span>
</c:if>
</h5> <c:if test="${component.displayProductPrices}">
<p>
<format:fromPrice
priceData="${productReference.target.price}" />
</p>
</c:if>
</a>
</div>
</div>
</div>
<div id="FeaturedShowcase">
<ul class="wtf">
<c:forEach items="${productReferences.previewImages}" var="previewImages"
varStatus="varStatus">
<li>Hello</li>
</c:forEach>
</ul>
</div>
</c:forEach>
</div>
</div>
</section>
I am always getting this exception
WARN [hybrisHTTP12] [DefaultCMSComponentRendererRegistry] Error processing component tag. currentComponent [ProductReferencesComponentModel (8796119335996)] exception: An exception occurred processing JSP page /WEB-INF/views/desktop/cms/productreferencescomponent.jsp at line 76
73: <ul class="wtf">
74:
75: <%-- <product:similarProductImagePanel similarProductImageList="${productReferences.previewImages}"/> --%>
76: <c:forEach items="${productReferences.previewImages}" var="previewImages"
77: varStatus="varStatus">
78: <li>Hello</li>
79: </c:forEach>
Stacktrace:
Any help on this issue or any suggestion
You are getting this error because you are using productReferences (List) instead of productReference for getting previewImages.
Please change this
<c:forEach items="${productReferences.previewImages}" var="previewImages" varStatus="varStatus">
<li>Hello</li>
</c:forEach>
to
<c:forEach items="${productReference.previewImages}" var="previewImages" varStatus="varStatus">
<li>Hello</li>
</c:forEach>
I just replace productReferences to productReference. Hope this will fix the issue.
I know I've asked a lot of questions lately and for that I apologize, I'm in the process of learning the ins and outs of MVC. Anyways, when I select a quantity and hit add to cart it doesn't add the quantity I select, almost like it just grabs a random number and adds it. Here's the code for the view:
#model IEnumerable<AccessorizeForLess.ViewModels.DisplayProductsViewModel>
#{
ViewBag.Title = "Products > Necklaces";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="~/Content/Site.css" rel="stylesheet" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/jquery.fancybox.css?v=2.1.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-buttons.css?v=1.0.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-thumbs.css?v=1.0.7" rel="stylesheet" />
<h2>Products > Necklaces</h2>
<div id="update-message"></div>
<p class="button">
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm("AddToCart", "Orders", FormMethod.Post))
{
<div id="container">
<div class="scroll">
#foreach (var item in Model)
{
<div class="scroll">
<div class="itemcontainer">
<table>
<tr>
<td id="#item.Id">
<div class="DetailsLink"> #Html.ActionLink(#item.Name, "Details", new { id = item.Id })</div>
<br />
<div id="#item.Id"></div>
<div class="divPrice" id="#item.Price">#Html.DisplayFor(modelItem => item.Price)</div>
<div class="divImg"><a class="fancybox-thumbs" href="#item.Image.ImagePath" title="#item.Image.AltText" data-fancybox-group="thumb"><img src="#item.Image.ImagePath" alt="#item.Image.AltText" title="#item.Image.AltText" /></a></div>
<div> </div>
<div class="divQuantity"> Quantity: #Html.TextBoxFor(modelItem => item.Quantity, new { #id = "quantity", #style = "width:50px;", #class = "formTextBox" })</div>
<div class="divAddToCart">
<p class="button">
#Html.ActionLink("Add to cart", "AddToCart", "Orders", new { id = item.Id }, new { #class = "AddToCart" })
</p>
</div>
<div style="height:15px;"></div>
</td>
</tr>
</table>
</div>
</div>
}
<div class="button">#Html.ActionLink("Back To Categories","Categories")</div>
<br />
</div>
</div>
}
#section scripts {
<script src="~/Scripts/jQuery-jScroll.js"></script>
<script src="~/Scripts/jquery.fancybox.js?v=2.1.5"></script>
<script src="~/Scripts/jquery.fancybox-thumbs.js?v=1.0.7"></script>
<script src="~/Scripts/jquery.fancybox-buttons.js?v=1.0.5"></script>
<script type="text/javascript">
//$(function () {
// $('.scroll').jscroll({
// autoTrigger: true
// });
$('.fancybox-thumbs').fancybox({
prevEffect: 'none',
nextEffect: 'none',
closeBtn: true,
arrows: false,
nextClick: false
});
});
</script>
}
Here's the code for AddToCart in my controller:
// GET: /Orders/AddToCart/5
public ActionResult AddToCart(int id)
{
// Retrieve the product from the database
var productAdded = db.Products
.Single(p => p.ProductId == id);
// Add it to the shopping cart
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.AddToCart(productAdded);
// Go back to the main store page for more shopping
return RedirectToAction("Index");
}
And finally the code for AddToCart in my ShoppingCart model:
public void AddToCart(Product item)
{
// Get the matching cart and product instances
var order = entities.Orders.FirstOrDefault(
c => c.OrderGUID == ShoppingCartId
&& c.OrderItems.Where(p=>p.ProductId == item.ProductId).FirstOrDefault().ProductId == item.ProductId);
if (order == null)
{
// Create a new order since one doesn't already exist
order = new Order
{
InvoiceNumber = Guid.NewGuid().ToString(),
OrderDate=DateTime.Now,
OrderGUID = ShoppingCartId,
IsShipped = false
};
entities.Orders.Add(order);
// Save changes
entities.SaveChanges();
//add the OrderItem for the new order
OrderItem oi = new OrderItem()
{
OrderId = order.OrderId,
OrderGUID = ShoppingCartId,
ProductId = item.ProductId,
ProductQuantity = item.Quantity,
ProductPrice = item.ProductPrice
};
entities.OrderItems.Add(oi);
entities.SaveChanges();
}
else
{
// If the item does exist in the cart,
// then add one to the quantity
order.OrderItems.Where(p => p.ProductId == item.ProductId).FirstOrDefault().ProductQuantity++;
entities.SaveChanges();
}
}
Code for DisplayProductsViewModel:
using AccessorizeForLess.Data;
using System.ComponentModel.DataAnnotations;
namespace AccessorizeForLess.ViewModels
{
public class DisplayProductsViewModel
{
public int Id { get; set; }
public string Name { get; set; }
[DisplayFormat(DataFormatString = "{0:C}")]
public decimal? Price { get; set; }
public ProductImage Image { get; set; }
public int ProductQuantity { get; set; }
}
}
Can anyone possibly see what I'm doing wrong
EDIT
This is what I see when I use the debugging tools
EDIT
'Here is the new view with the submit button added
#model IEnumerable<AccessorizeForLess.ViewModels.DisplayProductsViewModel>
#{
ViewBag.Title = "Products > Necklaces";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="~/Content/Site.css" rel="stylesheet" />
<link href="~/Content/jquery.fancybox.css?v=2.1.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-buttons.css?v=1.0.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-thumbs.css?v=1.0.7" rel="stylesheet" />
<h2>Products > Necklaces</h2>
<div id="update-message"></div>
<p class="button">
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm("AddToCart", "Orders", FormMethod.Post))
{
<div id="container">
<div class="scroll">
#foreach (var item in Model)
{
<div class="scroll2">
<div class="itemcontainer">
<table>
<tr>
<td id="#item.Id">
<div class="DetailsLink"> #Html.ActionLink(#item.Name, "Details", new { id = item.Id })</div>
<br />
<div id="#item.Id"></div>
<div class="divPrice" id="#item.Price">#Html.DisplayFor(modelItem => item.Price)</div>
<div class="divImg"><a class="fancybox-thumbs" href="#item.Image.ImagePath" title="#item.Image.AltText" data-fancybox-group="thumb"><img src="#item.Image.ImagePath" alt="#item.Image.AltText" title="#item.Image.AltText" /></a></div>
<div> </div>
<div class="divQuantity"> Quantity: #Html.TextBoxFor(modelItem => item.Quantity, new { #id = "quantity", #style = "width:50px;", #class = "formTextBox" })</div>
<div class="divAddToCart">
<input type="submit" value="Add To Cart" class="btn btn-default" /> #*#Html.ActionLink("Add to cart", "AddToCart", "Orders", new { id = item.Id }, new { #class = "AddToCart" })*#
</div>
<div style="height:15px;"></div>
</td>
</tr>
</table>
</div>
</div>
}
<div class="button">#Html.ActionLink("Back To Categories","Categories")</div>
<br />
</div>
</div>
}
#section scripts {
<script src="~/Scripts/jQuery-jScroll.js"></script>
<script src="~/Scripts/jquery.fancybox.js?v=2.1.5"></script>
<script src="~/Scripts/jquery.fancybox-thumbs.js?v=1.0.7"></script>
<script src="~/Scripts/jquery.fancybox-buttons.js?v=1.0.5"></script>
<script type="text/javascript">
//$(function () {
// $('.scroll').jscroll({
// autoTrigger: true
// });
$('.fancybox-thumbs').fancybox({
prevEffect: 'none',
nextEffect: 'none',
closeBtn: true,
arrows: false,
nextClick: false
});
// Document.ready -> link up remove event handler
//$(".AddToCart").click(function () {
// alert('Clicked!');
//});
//s});
</script>
}
And AddToCart
[HttpPost]
public ActionResult AddToCart(DisplayProductDetailsViewModel model)
{
// Retrieve the product from the database
var productAdded = db.Products
.Single(p => p.ProductId == model.Id);
// Add it to the shopping cart
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.AddToCart(productAdded);
// Go back to the main store page for more shopping
return RedirectToAction("Index");
}
When I set a breakpoint in AddToCart model is always null, what am I missing here?
You are always sending the same quantity because you always trigger the ActionLink's GET request that only passes the query string parameter id. The quantity field in your form is never sent as that's part of the POST form body submission.
// you are not triggering this submission: POST AddToCart
#using(Html.BeginForm("AddToCart", "Orders", FormMethod.Post))
{
// quantity is passed on the request's body
#Html.TextBoxFor(modelItem => item.Quantity)
// but GET AddToCart/id is send instead
#Html.ActionLink("Add to cart", "AddToCart", "Orders", new { id = item.Id }, new { #class = "AddToCart" })
}
As indicated by your screenshot
Request URL: http://localhost:24177/Orders/AddToCart/21
Request Method: GET
Status Code: 302 Found
Notice "Form Data" or "Request Body" is missing from your request.
Each time you call GET AddToCart you query the same product from the data store and set the quantity property to the same value.
You ought to send this GET request as POST instead because:
It can be cached by the browser and it won't make subsequent requests to the
server
Web crawlers can trigger the ActionLink request
So add a submit button to your form and make a POST action. Then be sure the assign a new quantity from the form.
[HttpPost]
public ActionResult AddToCart(FormModel model)
{
var product = db.Products.Where(... && p => p.Id == model.ProductId);
var quantity = model.ProductQuantity;
cart.AddToCart(product, quantity);
return RedirectToAction("Index");
}
I am implementing a role based menu. I have to generate the menu from the database dynamically. I have a role-feature mapping table from where I can get the features that are mapped to the role. Once I get that I have to generate the HTML menus with <ul> and <li>. Can I get suggestion as to how that be done. I mean generating the HTML script in controller and rendering it on to the respective view. Please help. Any suggestion is welcomed.
<ul id="menu">
<li>
#Html.ActionLink("Home", "Dashboard", "User")
</li>
<li>
<span>User</span>
<ul>
<li>#Html.ActionLink("Create User", "CreateUser", "User")</li>
</ul>
</li>
<li>
<span>Report</span>
<ul>
<li>#Html.ActionLink("ABC Report", "ABC", "Report")</li>
<li>#Html.ActionLink("User Report", "UserReport", "Report")</li>
</ul>
</li>
<li>
<span>XYZ</span>
<ul>
<li>#Html.ActionLink("XYZ1", "XYZ1", "XYZ")</li>
<li>#Html.ActionLink("XYZ2", "XYZ2", "XYZ")</li>
<li>#Html.ActionLink("XYZ3", "XYZ3", "XYZ")</li>
<li>#Html.ActionLink("XYZ4", "XYZ4", "XYZ")</li>
</ul>
</li>
</ul>
Above HTML I have to build in controller and render to the view.
I suggest to create a Menu class as below
public class Menu
{
public string Text {get;set;}
public string Controller {get;set;}
public string Action {get;set;}
}
then in your viewModel add a property MenuList of type List<Menu> then fill that collection in your controller dynamically from your database
then change your view as below
<span>XYZ</span>
<ul>
#for(var menu in Model.MenuList)
{
<li>#Html.ActionLink(menu.Text, menu.Action, menu.Controller)</li>
}
</ul>