Render and display a view from another controller - asp.net-mvc

How can I call and render a view of controller from action of another controller.
I have this, an action of Product Controller :
public ActionResult SortedLists(List<string> items, string ShopID)
{
//Do sth...
db.SaveChanges();
return RedirectToAction("Index", "ControlPanel", new { ID = ShopID });
}
And Index is the action(view) of ControlPanel Controller :
public ActionResult Index(int ID)
{
ViewBag.theRelatedShopID = ID;
return View();
}
How can I render Index and display it in browser???

public ActionResult SortedLists(List<string> items, string ShopID)
{
//Do sth...
db.SaveChanges();
return View("~/ControlPanel/Index.cshtml", (object)ShopID);
}
Here we are passing the ShopId as model to the Index view. If this view is strongly typed to some model you should pass this model:
MyViewModel model = ...
return View("~/ControlPanel/Index.cshtml", model);

Related

Model Binding Object properties gets NULL on passing while Redirecting to another Action Method [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));
}
}

How to print the string array on view page in Asp.net Mvc?

public ActionResult About()
{
var roles = System.Web.Security.Roles.GetAllRoles();
return View();
}
I don't know how to take this string on view page. Please help me.
You should have your view accept a string[] Model and pass this model from your controller to your view like this:
public ActionResult About()
{
var model = System.Web.Security.Roles.GetAllRoles();
return View(model);
}
In your view you'd have something like this (assuming you are using the Razor ViewEngine):
#model string[]
<ul>
#foreach(var role in model)
{
<li>#role</li>
}
</ul>
The View method takes a model which can be your string[].
public ActionResult About()
{
var roles = System.Web.Security.Roles.GetAllRoles();
return View(roles);
}
Then your view would look something like this
#model System.Array
#foreach (var role in Model)
{
...
}
You can set a ViewBag
public ActionResult About()
{
ViewBag.roles = System.Web.Security.Roles.GetAllRoles();
return View();
}
and u can access this ViewBag object on the page by #ViewBag.roles
To display the list
foreach(var customrole in ViewBag.roles)
{
#customrole.Roles // This might be some property you need to display
}

How to pass model to partial view

I have two view models:
public class ParentViewModel
{
public Id { get; set; }
.....
public ChildViewModel Child{ get; set; }
}
public class ChildViewModel
{
public ChildId { get; set; }
.....
}
Controllers:
public ActionResult Index()
{
.... <some code>
return View("NewIndex", ParentViewModel);
}
[HttpPost]
public ActionResult PartialAction(ChildViewModel childView)
{
return RedirectToAction("Index");
}
And views:
Index
#model ParentViewModel
....
#Html.Partial("_Partial", Model.Child)
and _Partial
#model ChildViewModel
... do some stuff with child model
When I'm trying to open Index page I've got an error:
The model item passed into the dictionary is of type 'ParentViewModel', but this dictionary requires a model item of type 'ChildViewModel'.
Why it tries to pass ParentViewModel instead of ChildViewModel. What I'm doing wrong?
I had the same issue as the OP. From one of the comments, I realized that the second parameter shouldn't be null, i.e from
#model ParentViewModel
#Html.Partial("_Partial", Model.Child)
If Model.Child is null, then Model is passed instead of Model.Child. If there will be cases when the second parameter is null, then you will have to check first in your code and maybe pass an initialized Child as the second parameter. Something like this
#Html.Partial("_Partial", new Child())
The answer is that needs to pass an empty object to Partial, like
#Html.Partial("_Partial", new ChildViewModel ())
You could return PartialView("...") from a Controller instead, and call the action from the Index view.
Controllers:
public ActionResult Index()
{
.... <some code>
return View("NewIndex", ParentViewModel);
}
public ActionResult Partial(ChildViewModel cvm)
{
var vm = cvm ?? new ChildViewModel(); //if cvm from the parent view is null, return new cvm
return PartialView("_Partial", vm) //return partial view
}
[HttpPost]
public ActionResult PartialAction(ChildViewModel childView)
{
return RedirectToAction("Index");
}
And Index
#model ParentViewModel
....
#Html.Action("Partial", Model.Child)
Alternatively, you could initialize ParentViewModel in the Index()
public ActionResult Index()
{
.... <some code>
return View("NewIndex", new ParentViewModel{Child = new ChildViewModel});
}

Display the same page after saving

I'd like show a form with some field (one in the example), submit it, save and display the same page with a reset of all fields. The probelm when I submit, I go the "Save" action but when I display the view the form is still filled in.
The model :
public class TestingModel
{
public string FirstName { get; set; }
}
The controller :
public class ChildController : Controller
{
public ActionResult Index()
{
TestingModel model = new TestingModel();
return View(model);
}
public ActionResult Save(TestingModel model)
{
Console.WriteLine(model.FirstName); //OK
//Save data to DB here ...
TestingModel testingModel = new TestingModel() { FirstName = string.Empty };
return View("Index", testingModel);
}
}
The view :
#using (Html.BeginForm("Save", "Child",FormMethod.Post))
{
#Html.TextBoxFor( m => m.FirstName)
<input type="submit" id="btSave" />
}
When Id debug to the view, in "Immediat window" Model.FirstName = "" but when the page is show I still have the value posted. I tried a ReditrectionToAction("Index") at the end of the Save method but same result.
Do you have an idea ?
Thanks,
If you want to do this you need to clear everything that's in the ModelState. Otherwise HTML helpers will completely ignore your model and use data from ModelState when binding their values.
Like this:
[HttpPost]
public ActionResult Save(TestingModel model)
{
//Save data to DB here ...
ModelState.Clear();
TestingModel testingModel = new TestingModel() { FirstName = string.Empty };
return View("Index", testingModel);
}
or simply redirect to the Index GET action in case of success:
[HttpPost]
public ActionResult Save(TestingModel model)
{
//Save data to DB here ...
return RedirectToAction("Index");
}
Try to return Index view without any model
return View("Index");
You should be posting your form back to the same ActionResult
public ActionResult Index()
{
TestingModel model = new TestingModel();
return View(model);
}
[HttpPost]
public ActionResult Index(TestingModel model)
{
Console.WriteLine(model.FirstName); //OK
//Save data to DB here ...
return RedirectToAction("Index");
}
You would be able to use the parameterless overload for BeginForm too
#using(Html.BeginForm())
{
//form
}

How to use an actionresult to return both a view and a partial view

How can I use use an actionResult to return both a view and a partial view. Actually in case of an ajax request it should send a partial view else it should send a view.
public ActionResult Test(string Name ="", DateTime? Date= null, string sex="" )
{
myModel model = new myModel(Name, Date, Sex);
if(IsAjaxRequest)
return PartialView("partialView", model)
else
return View(model);
}
if (Request.IsAjaxRequest())
return PartialView("_Article", model);
return View(model);

Resources