MVC passing variables within a controller - c#

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.

Related

Using model to save a list, works first time but second time it saves 62 count item list as 1 list item [duplicate]

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));
}
}

MVC 5 asp.net, viewbag from controller to view is not working

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

ViewModel Not Working

[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

Role based controller access

I'm to new asp.net and asp.net MVC. I'm trying to show a user a page depending on the role his in.
public class HomeController : Controller
{
[Authorize(Roles = "Reviewer")]
public ActionResult Index()
{
ViewBag.Title = "Reviwer";
return View();
}
[Authorize(Roles="User")]
public ActionResult Index()
{
return View();
}
}
My code is the one above, it makes perfect sense that it won't compile like this i can't cave two idendical methods with the same name. But can someone please point me in the right direction. How am i supposed to show the user o different page based on his role.
If they must be two separate actions, then it makes more sense to name them according to role, like so:
public class HomeController : Controller
{
[Authorize(Roles = "Reviewer")]
public ActionResult Reviewer()
{
ViewBag.Title = "Reviewer";
return View();
}
[Authorize(Roles="User")]
public ActionResult User()
{
return View();
}
}
If you can have them as one, you could do:
public class HomeController : Controller
{
[Authorize(Roles = "Reviewer", "User")]
public ActionResult Index()
{
if (User.IsInRole("Reviewer"))
{
return View("Reviewer");
}
else
{
return View("User");
}
}
}
Are there different views for each role or is it just that you want to have a different title depending on their role?
What you could do is combine the roles into a single Controller method and then inside the method have conditional logic, as a naive example:
public class HomeController : Controller
{
[Authorize(Roles = "Reviewer, User")]
public ActionResult Index()
{
if (Roles.IsUserInRole("Reviewer"))
{
ViewBag.Title = "Reviwer";
}
return View();
}
}
If all you were doing was changing the title. If you wanted to display a different view or redirect them somewhere else you could do:
[Authorize(Roles = "Reviewer, User")]
public ActionResult Index()
{
if (Roles.IsUserInRole("Reviewer"))
{
return View("ReviewerView");
}
else if (Roles.IsUserInRole("User"))
{
//Or do a RedirectToAction("SomeAction")
return View("UserView");
}
}
Do a test in the action whether the user is in a role and return a different view or redirect to a different action.
You could try something like:
public class HomeController : Controller
{
[Authorize(Roles = "Reviewer,User")]
public ActionResult Index()
{
if (User.IsInRole("Reviewer")){
ViewBag.Title = "Reviwer";
return View("IndexReviwer");
}
return View();
}
}
Need to create a View called IndexReviwer

HTTPPost does not work asp mvc 3

I am really confused,
here is the code :
[HttpPost]
public ActionResult Settings(string SubmitButton)
{
if (SubmitButton == "Sign In") {
ServiceLocator.Current.GetInstance<IAppContext>().LoggedUser = null;
Response.Cookies["loginuser"].Expires = DateTime.Now;
return RedirectToAction("Logon", "Account");
}
if (SubmitButton == "Sign Up") { return RedirectToAction("register", "Account"); }
if (SubmitButton == "Change Default Ride Settings") { return RedirectToAction("changeSettings", "Home"); }
return View();
}
The view contain
<% using (Html.BeginForm()) { %>
Three input ,
<% } %>
the controller is not fired with httppost but fired with httpget
You probably need to pass in the controller and action names in Html.BeginForm() in your view. Since the [HttpPost] Settings() action is being invoked for HTTP get requests, that implies that there isn't another Settings() action for get requests, so I'm guessing that your view is being served from a different action. In such a case, you need to explicitly set the controller and action in your Html.BeginForm(). Try this:
<% using (Html.BeginForm("Settings", "YourControllerName")) { %>
You have to generate a html form with the method attribute set to post if you want a post to happen:
Html.BeginForm("action","controller", FormMethod.Post) { ... }
There should be action with name Index() and should not containg any parameters in it. This is the problem I have faced.
I have used ActionName() to solve the same problem,
Not working code:
[HttpGet]
public ViewResult RsvpForm()
{
[HttpPost]
public ViewResult RsvpFrom()
{
}
Working code:
[HttpGet]
public ViewResult RsvpForm()
{
}
[HttpPost, ActionName("RsvpForm")]
public ViewResult RsvpFromPost()
{
}
The proper way using razor
#using (Html.BeginForm("LogOn", "Account", FormMethod.Post, new { id = "form1" }))
{
//form content
}

Categories

Resources