MVC3 pass the parameter to others in same controller - asp.net-mvc-3

I am trying to pass the parameter, which is 'priceValue'. How can I pass this value through using RedirectToAction? or do you have any idea for that?
I am trying to make shopping cart now. 'priceValue' is radioButton value. Could you give me some help? After passing the priceValue, and I want to use if statement what I have written in AddToCart. Is it possible to use it?
Please help me..
Thanks.
public class ShoppingCartController : Controller
{
rentalDB db = new rentalDB();
//
// GET: /ShoppingCart/
public ActionResult Index()
{
var cart = ShoppingCart.GetCart(this.HttpContext);
// Set up our ViewModel
var viewModel = new ShoppingCartViewModel
{
CartItems = cart.GetCartItems(),
CartTotal = cart.GetTotal()
};
// Return the view
return View(viewModel);
}
// GET: /Store/AddToCart/5
[HttpPost]
public ActionResult AddToCart(int id, FormCollection col)
{
var addedProduct = db.Product
.Single(product => product.productId == id);
decimal priceValue = Convert.ToDecimal(col["price"]);
//how to pass priceValue to index
if (Convert.ToDecimal(col["price"]) == addedProduct.threeDayPrice)
{
ViewBag.price = new SelectList(db.Product, "productId", "threeDayPrice");
//How to put this value into cart.AddtoCart(addedProduct) with date and price
}
else if (Convert.ToDecimal(col["price"]) == addedProduct.aWeekPrice)
{
ViewBag.price = new SelectList(db.Product, "productId", "aWeekPrice");
//How to put this value into cart.AddtoCart(addedProduct) with date and price
}
// Retrieve the product from the database
// Add it to the shopping cart
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.AddToCart(addedProduct);
// Go back to the main store page for more shopping
//I don't know how to pass the 'priceValue' by using RedirectToAction.
return RedirectToAction("Index", new {id = priceValue});
}

You have to add a parameter to your Index method in order to be able to get the value passed in to the Index method:
public ActionResult Index(int priceValue = 0).
Instead of 0, you can then use whatever default value you wish. Then calling
return RedirectToAction("Index", new {#priceValue = priceValue});
will allow you to get the value inside the method.

return RedirectToAction("Index", new {#id = priceValue.toString()});
will redirect it to an Action method called Index with a id parameter

Related

How to pass data from one actionmethod to another in ASP.NET Core 6.0 MVC

I'm wondering how I should do this: I get the ID of an item by using the asp-route-id="#item.ID" method.
<a asp-controller="Outfit" asp-action="OutfitRatingOpslaan"
asp-route-id="#item.ID" class="btn btn-primary">Beoordelen</a>
This ID needs to be remembered for the view:
public IActionResult OutfitRatingOpslaan(item.ID)
{
Object obj = Container.GetObject(item.ID)
}
So the ID of that object, needs to be combined with the value i get after pressing on a submit button in the OutfitRatingOpslaan(Item.ID) view.
I have added a picture on how the view looks like and where the user can enter a value.
This new value + the ID of the object need to be combined and stored inside database.
So the end result should look something like this:
public IActionResult OutfitRatingSave()
{
Rating rating = ratingContainer.AddRating(item.ID, Value);
}
Does anyone have any ideas ? ;p
There are two methods can achieve it.
First method, You can use:
return RedirectToAction("action", "controller", new { id = item.ID});
Then in target action, Just use :
public IActionResult OutfitRatingSave(int id)
{
Rating rating = ratingContainer.AddRating(id, Value);
}
Second method, You can use TempData["xx"] to pass data between actions, refer to below code:
public IActionResult OutfitRatingOpslaan(item.ID)
{
TempData["id"] = item.ID
Object obj = Container.GetObject(item.ID)
}
public IActionResult OutfitRatingSave()
{
int id = (int)TempData["id"];
Rating rating = ratingContainer.AddRating(id, Value);
}

MVC 3 How to tell what view a controller action is being called from-

Is there a way to tell what view a controller action is being called from?
For example, I would like to use "ControllerContext.HttpContext.Request.PhysicalPath" but it returns the path in which the controller action itself is located:
public ActionResult HandleCreateCustomer()
{
// Set up the customer
//..code here to setup the customer
//Check to see of the calling view is the BillingShipping view
if(ControllerContext.HttpContext.Request.PhysicalPath.Equals("~/Order/BillingShipping"))
{
//
return RedirectToAction("OrderReview", "Order", new { id = customerId });
}
else
{
return RedirectToAction("Index", "Home", new { id = customerId });
}
}
If you have a fixed number of locations that it could possibly be called from, you could create an enum where each of the values would correspond to a place where it could have been called from. You'd then just need to pass this enum value into HandleCreateCustomer, and do your condition statement(s) based on that.
At the moment I am using something of the sort:
In the View I am populating a TempData variable using:
#{TempData["ViewPath"] = #Html.ViewVirtualPath()}
The HtmlHelper method ViewVirtualPath() is found in the System.Web.Mvc.Html namespace (as usual) and is as follows and returns a string representing the View's virtual path:
public static string ViewVirtualPath(this HtmlHelper htmlHelper)
{
try{
return ((System.Web.WebPages.WebPageBase)(htmlHelper.ViewDataContainer)).VirtualPath;
}catch(Exception){
return "";
}
}
I will then obviously read the TempData variable in the controller.
I found another way.
In the controller you want to know what page it was called from.
I added the following in my controller
ViewBag.ReturnUrl = Request.UrlReferrer.AbsolutePath;
Then in the View I have a 'Back' button
#(Html.Kendo().Button().Name("ReturnButton")
.Content("Back to List").Events(e => e.Click("onReturn"))
.HtmlAttributes(new { type = "k-button" })
)
Then the javascript for the onReturn handler
function onReturn(e) {
var url = '#(ViewBag.ReturnUrl)';
window.location.href = url;
}

Return to current url in asp.net mvc

I have a method:
public ActionResult AddProductToCart(int productId)
{
var product = _productService.GetProductById(productId);
if (product == null)
return RedirectToAction("Index", "Home");
int productVariantId = 0;
if (_shoppingCartService.DirectAddToCartAllowed(productId, out productVariantId))
{
var productVariant = _productService.GetProductVariantById(productVariantId);
var addToCartWarnings = _shoppingCartService.AddToCart(_workContext.CurrentCustomer,
productVariant, ShoppingCartType.ShoppingCart,
string.Empty, decimal.Zero, 1, true);
if (addToCartWarnings.Count == 0)
//return RedirectToRoute("ShoppingCart");
else
return RedirectToRoute("Product", new { productId = product.Id, SeName = product.GetSeName() });
}
else
return RedirectToRoute("Product", new { productId = product.Id, SeName = product.GetSeName() });
}
You see the line which is commented out: I want there to not trigger any redirect but just stay on the same page from where this request was made.
If I put return View() it's not fine because it will search for View with this name while this method is a simple action to add to cart..
Can you please give me a solution of how to Redirect to current url or to stay on the same page?
You could pass an additional returnUrl query string parameter to this method indicating the url to get back to once the product has been added to the cart:
public ActionResult AddProductToCart(int productId, string returnUrl)
so that you can redirect back to wherever you were:
if (addToCartWarnings.Count == 0)
{
// TODO: the usual checks that returnUrl belongs to your domain
// to avoid hackers spoofing your users with fake domains
if (!Url.IsLocalUrl(returnUrl))
{
// oops, someone tried to pwn your site => take respective actions
}
return Redirect(returnUrl);
}
and when generating the link to this action:
#Html.ActionLink(
"Add product 254 to the cart",
"AddProductToCart",
new { productId = 254, returnUrl = Request.RawUrl }
)
or if you are POSTing to this action (which by the way you should probably be because it is modifying state on the server - it adds a product to a cart or something):
#using (Html.BeginForm("AddProductToCart", "Products"))
{
#Html.Hidden("returnurl", Request.RawUrl)
#Html.HiddenFor(x => x.ProductId)
<button type="submit">Add product to cart</button>
}
Another possibility is to use AJAX to invoke this method. This way the user will stay on the page wherever he was before calling it.
Assuming you mean return to where you were before visiting that controller:
return Redirect(Request.UrlReferrer.ToString());
Keep in mind that if you POSTed to get to that [previous] page, you're going to be at a loss since you're not mimicking the same request.

Pass a value from one controller to another in asp.net mvc

I've been new to ASP.NET MVC. This is what I'm doing. I've 2 Controllers:Home and Customerservice.
Now I have a Customer list where when I click details gets redirected to the products he acquired.
So, I need to pass in the id so that the products of that customer can be displayed. So, my home consists of customer details. Now i need to pass that id to CustomerService controller ,Index action. This is what I've done in Home:
public ActionResult Customers()
{
var dc = new ServicesDataContext();
var query = (from m in dc.Customers
select m);
return View(query);
}
public ActionResult Details(int id)
{
var datacontext = new ServicesDataContext();
var serviceToUpdate = datacontext.Customers.First(m => m.CustomerId == id);
ViewData.Model = serviceToUpdate;
// return View();
return Redirect("/CustomerService");
}
[HttpPost]
public ActionResult Details(FormCollection form)
{
var id = Int32.Parse(form["CustomerID"]);
var datacontext = new ServicesDataContext();
var service = datacontext.Customers.First(m => m.CustomerId == id);
return Redirect("Customers");
}
}
Now I'm not sure whether I need to pass an id as parameter for index in CustomerService. SO can you please guide me in finishing this?
If you are using any Redirect (such as RedirectToAction) you can use TempData to store any parameters. The semantics have slightly changed in MVC 3 but TempData is designed to pass data between actions in a POST-Redirect-GET scenario.
Passing it as a parameter is probably your best option. Try using something like return RedirectToAction(ActionName, ControllerName, RouteValues);.

ViewBag property value in DropDownListFor instead of Model property value

We found strange behaviour in DropDownListFor (ASP.NET MVC3 release). It selects ViewBag property value instead of Model property value in dropdown.
Model:
public class Country {
public string Name { get; set; }
}
public class User {
public Country Country { get; set; }
}
Controller Index action:
ViewBag.CountryList = new List<Country> { /* Dropdown collection */
new Country() { Name = "Danmark" },
new Country() { Name = "Russia" } };
var user = new User();
user.Country = new Country(){Name = "Russia"}; /* User value */
ViewBag.Country = new Country() { Name = "Danmark" }; /* It affects user */
return View(user);
View:
#Html.EditorFor(user => user.Country.Name)
#Html.DropDownListFor(user => user.Country.Name,
new SelectList(ViewBag.CountryList, "Name", "Name", Model.Country), "...")
It will show text box with "Russia" value and dropdown with "Danmark" value selected instead of "Russia".
I didn't find any documentation about this behaviour. Is this behaviour normal? And why is it normal? Because it is very hard to control ViewBag and Model properties names.
This sample MVC3 project sources
I'm not so sure why this decision was made, but it was happened because MVC framework tried to use the ViewData-supplied value before using the parameter-supplied value. That's why ViewBag.Country override parameter-supplied value Model.Country.
That was how it was written in MVC framework in the private method SelectInternal.
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
if (!usedViewData) {
if (defaultValue == null) {
defaultValue = htmlHelper.ViewData.Eval(fullName);
}
}
if (defaultValue != null) {
IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue };
IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
List<SelectListItem> newSelectList = new List<SelectListItem>();
foreach (SelectListItem item in selectList) {
item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
newSelectList.Add(item);
}
selectList = newSelectList;
}
This code defaultValue = htmlHelper.ViewData.Eval(fullName); tried to get the value from ViewData and if it can get the value, it will override the supplied parameter selectList with new list.
Hope it can help. Thanks.
side-node: ViewBag is just a dynamic wrapper class of ViewData.
The following line from your action method is what is confusing the code:
ViewBag.Country = new Country() { Name = "Danmark" }; /* It affects user */
That's because the html helpers look into a few different places to pick up values for the generated controls. In this case ViewData["Country"] is clashing with ModelState["Country"] Rename that property to something else and everything should work.

Resources