[HttpPost]
public ActionResult AddToCart(int phoneListingID, string sellerSKU)
{
ShoppingBasket shoppingBasket = new ShoppingBasket();
BasketItem currentItem = new BasketItem
{
sellerID = 1,
Price = 100,
Quantity = 1,
sellerSKU = "testsku"
};
shoppingBasket.AddtoBasket(currentItem, this.HttpContext);
var viewModel = new BasketViewModel
{
basketItems = ShoppingBasket.GetBasketItems(this.HttpContext),
basketTotal = ShoppingBasket.GetBasketTotal(this.HttpContext)
};
return View(viewModel);
}
My form:
#using (Html.BeginForm("AddToCart","ShoppingBasket",new { phoneListingID = 12345, sellerSKU = "test"}, FormMethod.Post ))
{
<input type="submit" value="AddToCart" />
}
The expected result is that my BasketViewModel page is returned, however the view being returned is ShoppingBasket/AddToCart?PhoneID=xxxx&sellerSKU=xxxx
What am I doing wrong?
In MVC Suppose your action is like
public ActionResult MyAction()
{
return View();
}
In this scenerio it will point to the view named 'MyAction'. If you want to send it to another view make it like
public ActionResult MyAction()
{
return View("MyViewName");
}
If you want to pass some model to make it like
public ActionResult MyAction()
{
return View("MyViewName",model); // Here model is your object of model class
}
In you snippet your are returning default i.e. 'AddToCart' view because you are not describing explicitly. Make your code like
return View("BasketViewModel",viewModel); // where BasketViewModel is your view name
You're returning that controller's View, if you wish to transfer to another view try
return BasketViewActionResult(viewmodel)
Then access your 'BasketViewActionResult'
Function BasketViewActionResult(model as BasketViewModel) as ActionResult
return View(model)
End Function
Sorry if you don't get VB, I can translate it to C# for you if you wish.
Edit:
You can also simply change the form's action.
#using (Html.BeginForm("BasketView","ShoppingBasket",...
and make all your manipulations within that actionresult
Related
I have an ActionResult Method which i wanted to return some values to the view for using in a form to submit afterwards.
How can I access these data from view for submition in a form?!
Here is my ActionResult method:
[HttpPost]
public virtual async Task<IActionResult> ImportPhonenumbersFromExcel(IFormFile importexcelfile, int currentFestivalId)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageFestivals))
return AccessDeniedView();
try
{
if (importexcelfile != null && importexcelfile.Length > 0)
{
var result = await _importManager.ImportPhonenumbersFromXlsxAsync(importexcelfile.OpenReadStream());
}
else
{
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Common.UploadFile"));
return RedirectToAction("Edit", new { id = currentFestivalId });
}
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Festival.Phonenumbers.Imported"));
return RedirectToAction("Edit", new { id = currentFestivalId });
}
catch (Exception em)
{
await _notificationService.ErrorNotificationAsync(em);
return RedirectToAction("Edit", new { id = currentFestivalId });
}
}
For strongly typed data a view model is the best option. It is a class with properties that can be used to store your specific values which you want to pass to the view. To use a viewmodel:
Create the viewmodel class and add the properties you need.
Instantiate a new viewmodel object in your controller. The example shown below is from the Microsoft documentation where the viewmodel class is named Address.
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
var viewModel = new Address()
{
Name = "Microsoft",
Street = "One Microsoft Way",
City = "Redmond",
State = "WA",
PostalCode = "98052-6399"
};
return View(viewModel);
}
Once you have set the values of the properties of the viewmodel object in the controller you can then add the viewmodel to the view.
To send the viewmodel to the view, pass it as a parameter:
return View(viewModel);
Finally, add to the top of your view file:
#model yourViewModelsAddress
To refer to the properties of your viewmodel in your view, follow this example:
`#Model.Property`
You can create a view model that will contain the list and everything else you want to pass to the view.
Then in the view you can access it by using #model.
I want to know, there is any technique so we can pass Model as a parameter in RedirectToAction
For Example:
public class Student{
public int Id{get;set;}
public string Name{get;set;}
}
Controller
public class StudentController : Controller
{
public ActionResult FillStudent()
{
return View();
}
[HttpPost]
public ActionResult FillStudent(Student student1)
{
return RedirectToAction("GetStudent","Student",new{student=student1});
}
public ActionResult GetStudent(Student student)
{
return View();
}
}
My Question - Can I pass student model in RedirectToAction?
Using TempData
Represents a set of data that persists only from one request to the
next
[HttpPost]
public ActionResult FillStudent(Student student1)
{
TempData["student"]= new Student();
return RedirectToAction("GetStudent","Student");
}
[HttpGet]
public ActionResult GetStudent(Student passedStd)
{
Student std=(Student)TempData["student"];
return View();
}
Alternative way
Pass the data using Query string
return RedirectToAction("GetStudent","Student", new {Name="John", Class="clsz"});
This will generate a GET Request like Student/GetStudent?Name=John & Class=clsz
Ensure the method you want to redirect to is decorated with [HttpGet] as
the above RedirectToAction will issue GET Request with http status
code 302 Found (common way of performing url redirect)
Just call the action no need for redirect to action or the new keyword for model.
[HttpPost]
public ActionResult FillStudent(Student student1)
{
return GetStudent(student1); //this will also work
}
public ActionResult GetStudent(Student student)
{
return View(student);
}
Yes you can pass the model that you have shown using
return RedirectToAction("GetStudent", "Student", student1 );
assuming student1 is an instance of Student
which will generate the following url (assuming your using the default routes and the value of student1 are ID=4 and Name="Amit")
.../Student/GetStudent/4?Name=Amit
Internally the RedirectToAction() method builds a RouteValueDictionary by using the .ToString() value of each property in the model. However, binding will only work if all the properties in the model are simple properties and it fails if any properties are complex objects or collections because the method does not use recursion. If for example, Student contained a property List<string> Subjects, then that property would result in a query string value of
....&Subjects=System.Collections.Generic.List'1[System.String]
and binding would fail and that property would be null
[HttpPost]
public async Task<ActionResult> Capture(string imageData)
{
if (imageData.Length > 0)
{
var imageBytes = Convert.FromBase64String(imageData);
using (var stream = new MemoryStream(imageBytes))
{
var result = (JsonResult)await IdentifyFace(stream);
var serializer = new JavaScriptSerializer();
var faceRecon = serializer.Deserialize<FaceIdentity>(serializer.Serialize(result.Data));
if (faceRecon.Success) return RedirectToAction("Index", "Auth", new { param = serializer.Serialize(result.Data) });
}
}
return Json(new { success = false, responseText = "Der opstod en fejl - Intet billede, manglede data." }, JsonRequestBehavior.AllowGet);
}
// GET: Auth
[HttpGet]
public ActionResult Index(string param)
{
var serializer = new JavaScriptSerializer();
var faceRecon = serializer.Deserialize<FaceIdentity>(param);
return View(faceRecon);
}
[NonAction]
private ActionResult CRUD(someModel entity)
{
try
{
//you business logic here
return View(entity);
}
catch (Exception exp)
{
ModelState.AddModelError("", exp.InnerException.Message);
Response.StatusCode = 350;
return someerrohandilingactionresult(entity, actionType);
}
//Retrun appropriate message or redirect to proper action
return RedirectToAction("Index");
}
i did find something like this, helps get rid of hardcoded tempdata tags
public class AccountController : Controller
{
[HttpGet]
public ActionResult Index(IndexPresentationModel model)
{
return View(model);
}
[HttpPost]
public ActionResult Save(SaveUpdateModel model)
{
// save the information
var presentationModel = new IndexPresentationModel();
presentationModel.Message = model.Message;
return this.RedirectToAction(c => c.Index(presentationModel));
}
}
this is the controller
public ActionResult Test() {
#ViewBag.TheMessageIs = "this is the message";
return RedirectToAction("Details", new { id = theId});
}
on the view of Action Named Details I will check if it has the ViewBag to show and show it:
#{
if(ViewBag.TheMessageIs != null){
#ViewBag.TheMessageIs
}
}
but here the redirection is working fine to the page, it's not show the message I have stored in ViewBag.TheMessageIs
thanks
Basically what you're doing is invoking the method Details from your Index method and since you're already overloading your Details action with an id, pass it the message as well:
public ActionResult Index()
{
//ViewBag.TheMessageIs = "this is the message";
return RedirectToAction("Details", new { id = 1, TheMessageIs = "this is the message" });
}
public ActionResult Details(int id, string TheMessageIs)
{
ViewBag.TheMessageIs = TheMessageIs;
return View();
}
Then in the Details view you can access the property like this:
#ViewBag.TheMessageIs
public ActionResult Test() {
TempData["shortMessage"] = "MyMessage";
return RedirectToAction("Details", new { id = theId});
}
public ActionResult Details {
//now I can populate my ViewBag (if I want to) with the TempData["shortMessage"] content
ViewBag.TheMessageIs = TempData["shortMessage"].ToString();
return View();
}
You have to do it like this since the viewbag looses its value when you redirect to another active / view
Not sure if I am following MVC conventions but I have some variables passed from one Controller A to Controller B. My objective is to have another view named 'Publish' with an ActionLink to do some processing upon clicking on it.
The redirection from Controller A:
var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index", "Publish", new { accTok = facebookAccessTok, fullImgPath = fullpath });
return Json(new { Url = redirectUrl });
I now have the values for 'accTok' and 'fullImgPath' in my 'Publish' Index for Controller B which contains an ActionLink in its View to do the processing, but I am not sure how do I pass them to my 'Publish' ViewResult' method to do it:
namespace SF.Controllers
{
public class PublishController : Controller
{
public ViewResult Index(string accTok, string fullImgPath)
{
return View();
}
// This ViewResult requires the values 'accTok' and 'fullImgPath'
public ViewResult Publish()
{
// I need the values 'accTok' and 'fullImgPath'
SomeProcessing();
return View();
}
public SomeProcessing(string accessToken, string fullImagePath)
{
//Implementation
}
}
}
Index View:
#{
ViewBag.Title = "Index";
}
<h2>Publish</h2>
<br/><br/>
#Html.ActionLink("Save Image", "Publish")
I would suggest doing this
public ViewResult Publish(string accTok, string fullImgPath)
{
SomeProcessing(accTok,fullImgPath);
return View();
}
In your controller:
public ViewResult Index(string accTok, string fullImgPath)
{
ViewModel.Acctok = accTok;
ViewModel.FullImgPath = fullImgPath;
return View();
}
public ViewResult Publish(string accTok, string fullImgPath)
{
SomeProcessing(accTok,fullImgPath);
return View();
}
In the view:
#Html.ActionLink("Save Image", "Publish","Publish",new {accTok=ViewModel.Acctok, fullImgPath=ViewModel.FullImgPath},null )
Instead of the ActionLink you could also make it a form with hidden input fields (if this method changes thing in a database/on disk, it actually should be in a post).
But anyway use a viewmodel to pass the parameters from the index action to the view, so that in turn can send them to the publish action. This is generally the way to do it with the stateless web in MVC.
At the moment this is what I have in my HomeController:
[HttpPost]
public ActionResult Index(HomeFormViewModel model)
{
...
...
TempData["Suppliers"] = service.Suppliers(model.CategoryId, model.LocationId);
return View("Suppliers");
}
This is what I have in my SupplierController:
public ViewResult Index()
{
SupplierFormViewModel model = new SupplierFormViewModel();
model.Suppliers = TempData["Suppliers"] as IEnumerable<Supplier>;
return View(model);
}
This is my Supplier Index.cshtml:
#model MyProject.Web.FormViewModels.SupplierFormViewModel
#foreach (var item in Model.Suppliers) {
...
...
}
Instead of using TempData is there a different way to pass objects to a different controller and its view?
Why don't you just pass those two ID's in as parameters, then call the service class from the other controller? Something like:
Have your SupplierController method like so:
public ViewResult Index(int categoryId, int locationId)
{
SupplierFormViewModel model = new SupplierFormViewModel();
model.Suppliers = service.Suppliers(categoryId, locationId);
return View(model);
}
Then, I'm assuming you're calling your view from within the Supplier view via a link of some sort? You can do:
#foreach (var item in Model.Suppliers)
{
#Html.ActionLink(item.SupplierName, "Index", "Supplier", new { categoryId = item.CategoryId, locationId = item.LocationId})
//The above assumes item has a SupplierName of course, replace with the
//text you want to display in the link
}