i have two Html links
and
When i click First Link it goes to Sample controller and goes to advetisement Methode and returns View
public ActionResult advetisement{
// here iam reciveing data to variable
return view()
} now it retuns to view and data is binded and displays Page.Now when i click second link it should go to Same controller(advetisement) and return same Data but view should be diffrent since html styling is changed.
You can load two different views from the same controller action:
if (model.SomeCondition == true)
{
return View("ViewName1", model);
}
return View("ViewName2", model);
Then use your view model to store the condition which determines which view to display:
public class MyViewModel
{
public bool SomeCondition { get; set;}
public object Data { get; set; }
}
I think the easiest way is just having two actions with different names. Of course, code duplication should be extracted to the separate method. Something like this:
public ActionResult Advertisement()
{
return AdvertisementInternal("Advertisement");
}
public ActionResult Advertisement1()
{
return AdvertisementInternal("Advertisement1");
}
private ActionResult AdvertisementInternal(string viewName)
{
// filling ViewBag with your data or creating your view model
...
return View(viewName);
}
But if an appropriate way is the only action for both views then you should have a flag to distinguish the views. It can be added to URL. Something like this:
// on the view
#Html.ActionLink("Link1", "Advertisement", "Sample", new { Id = "View1" }, null)
#Html.ActionLink("Link2", "Advertisement", "Sample", new { Id = "View2" }, null)
// in the controller
public ActionResult Advertisement(string id)
{
if (id == "View1" || id == "View2")
{
// filling ViewBag with your data or creating your view model
...
return View(id);
}
return HttpNotFound();
}
Related
I want to pass more than one object in the view. I have two object. One name is "Caller" and one Name is "Receiver". I am new in MVC. This is my action method.
public ActionResult IsActiveCaller(int id)
{
var caller = new CallerService().getCallerById(id);
if(caller.active)
{
var reciver= new reciverService().getReviverTime(caller.dialNo);
return (caller ) // here i also want to send reciver to view
}
return View();
}
Is there any way to send more than object in view?
Yes you can do this. There are multiple ways to do this.
1) You can use viewBag to pass the data or object into view.
You can see here to see how to use viewBag in mvc
2) you can use ViewData but it is not a good approach.
3) you can make ViewModel like as below (recomended)
public class callerReciver
{
public Caller caller {set;get;}
pblic Reciver eciver {set;get;}
}
Now pass callerReciver to view.You can access both object.hope you will understand.
4) Another way is to use partial view.You can make partial view to use more than one object in same view.
You can use a View Model:
public class MyViewModel
{
public Caller Caller { get; set; }
public Receiver Receiver { get; set; }
}
Then you can populate the view model this way:
public ActionResult IsActiveCaller(int id)
{
var caller = new CallerService().getCallerById(id);
var vm = new MyViewModel {
Caller = caller
};
vm.Receiver = caller.active ? new reciverService().getReviverTime(caller.dialNo) : null;
return View(vm);
}
View:
#model MyViewModel
<h1>#Model.Caller.Title</h1>
#if(Model.Receiver != null) {
<h1>#Model.Receiver.Title</h1>
}
The cleanest way is to pass by a view model :
ViewModel
public class MyViewModel {
public Caller MyCaller { get;set; }
public Receiver MyReceiver { get;set; }
}
Controller
public ActionResult IsActiveCaller(int id)
{
var caller = new CallerService().getCallerById(id);
var viewModel = new MyViewModel();
viewModel.MyCaller = caller;
if(caller.active)
{
var reciver= new reciverService().getReviverTime(caller.dialNo);
viewModel.MyReceiver = reciver;
}
return View(viewModel);
}
View
#model MyViewModel
<h1>#Model.MyCaller.Id</h1>
<h1>#Model.MyReceiver.Id</h1>
I have a List with has three values.I want to display in view.Here is my approach
My Controller Function
public List<Movie> Index()
{
Movie obj = new Movie();
return obj.ShowData();
}
My model class & Function
Database db = DatabaseFactory.CreateDatabase("MyDBLINK");
public int ID { get; set; }
public string Title { get; set; }
public List<Movie> GetData()
{
try
{
DbCommand dbCommand = db.GetStoredProcCommand("SP");
DataSet dsResult = db.ExecuteDataSet(dbCommand);
List<Movie> Prop = new System.Collections.Generic.List<Movie>();
Prop = (from DataRow row in dsResult.Tables[0].Rows
select new Movie
{
ID = Convert.ToInt32(row["ID"].ToString()),
Title = row["Title"].ToString()
}).ToList();
return Prop;
}
catch (Exception ex)
{
return null;
}
}
Here is my view
#model System.Collections.Generic.List<MvcFirst.Controllers.MoviesController>
#foreach (var item in Model)
{
<ul>
<li>#item.ID</li>
<li>#item.Title</li>
</ul>
}
My Question is how to display this list in View?
Secondly Is this approach is Good for CPU?
Everything looks almost fine, your controller should be something like this:
public ActionResult Index()
{
var movie = new Movie();
var result = movie.GetData(); // instance object and read the method to get the list
return View(result);
}
An ActionResult could be any type of result, a View, a File to download, a Javascript, A StyleSheet, etc... but normaly is a View with the same name of action. If your action method is called Index, asp.net mvc will search for a View called Index on the Views folder. The part return View(result); means you are returning this View and passing the result object as a Model to your View.
Your View should be strogly typed with the entity (because you are returning it from the controller), not the controller:
#model System.Collections.Generic.List<Movie>
#foreach (var item in Model)
{
<ul>
<li>#item.ID</li>
<li>#item.Title</li>
</ul>
}
I think you've missunderstood how Controllers and Views work. Your Index() method need to return an ActionResult which will generate your view and return it to the user.
//My Controller Function
public ActionResult Index()
{
Movie obj = new Movie();
return View(obj.GetData()); //This will take the view with the same name as your method (Index in this case) and return it to the client/browser.
}
I hope I understood you question correctly.
Edit: I forgot to make the view stronly typed as Felipe Oriani has showned you
I am working on a ASP.NET MVC website and I am new to this.
I have a controller with few actions. I want to use these actions through out my website.
For example
[HttpPost]
public ActionResult MyAction(ViewModel model)
{
if (ModelState.IsValid)
{
//code is here
}
return RedirectToAction(); // redirect to same view
}
I want to redirect to same view from where request is generated. I am not sure if this is possible or not ?
Based on your comment, I would create a Controller that looks like:
public MyController : Controller
{
private ActionResult SharedMethod(SomeModel model)
{
if (ModelState.IsValid)
{
//code is here
}
// viewname is required, otherwise the view name used will be
// the original calling method (ie public1.cshtml, public2.cshtml)
return this.View("SharedViewName");
}
public ActionResult Public1(SomeModel model)
{
return this.SharedMethod(model);
}
public ActionResult Public1(SomeModel model)
{
return this.SharedMethod(model);
}
}
I have a question, can this be done using ASP.NET MVC (Razor, and MapRoute)?
Example
Category/ - calls controller Category and Index function
Category/{State_name} - calls controller Category and Cities(State_id) function, returns all cities inside that state.
So URL is displaying state name , but Cities function receive state id?
Yes u can, try
public class CategoryController : Controller {
// GET: /Category/
// OR
// GET: /Category/State_name
public ActionResult Index(string State_name) {
if (!string.IsNullOrWhiteSpace(State_name)) {
int? State_id = FindStateIdFromStateName(State_name); // retrive state_id from datastore where state_name == State_name
if (State_id.HasValue) { // means the currect state_name passed to action
var model = FindStateById(State_id.Value);
return View("Cities", model); // will renders Cities.cshtml with specified model
} else {
// means the specified state_name not found! u can do something else, or allow continue bellow lines
}
}
return View(); // will render normal Index.cshtml
}
}
Let me know if you have any questions or need clarifications on any part.
UPDATE
I have one issue with the way! You get the ID from db with State_name, then get the model from db by State_name! Why not retrieve
model from db by State_name at the first time?
look:
public class CategoryController : Controller {
// GET: /Category/
// OR
// GET: /Category/State_name
public ActionResult Index(string State_name) {
if (!string.IsNullOrWhiteSpace(State_name)) {
var model = FindStateByName(State_name);
if(model != null)
return View("Cities", model);
else
// means the specified state_name not found! u can do something else, or allow continue bellow lines
}
return View(); // will render normal Index.cshtml
}
}
and if you are on EF, then you can create this method:
public State FindStateByName(state_name){
using(var context = new YourEntityContext()){
return context.States.SingleOrDefault(s => s.Name.ToLower() == state_name.ToLower());
}
}
Why not using this way?
This should do it:
routes.MapRoute("Category_byState", "Category/{State_id}", new { controller = "Category", action = "Cities" });
I'm passing data between my controller and my view using a ViewModel class. When there are validation errors, I return the ViewModel back to the view so the user can see the errors.
I'm having trouble figuring out the best way to deal with the data that is only passed from the controller to the view, which isn't passed back to the controller, such as the contents of dropdown lists.
Here's a simplified example from the project I'm working on:
I have a Widget object in my domain model that has an Employee property. I have a view that allows the user to edit this employee property by selecting their name from a drop down list.
public class WidgetFormViewModel {
// Used for a drop down list in the view
public SelectList EmployeeList { get; set; }
// This will contain the employee the user selected from the list
public int EmployeeID { get; set; }
public Widget Widget { get; set; }
}
And the controller:
// GET: /Widget/Edit/1
public ActionResult Edit(int id) {
var widget = _widgetService.GetWidgetByID(id);
var employees = _widgetService.GetAllEmployees();
var viewModel = new WidgetFormViewModel()
{
EmployeeList =
new SelectList(employees, "ID", "Name", widget.Employee),
Widget = widget,
WidgetID = widget.ID
};
return View("Edit", viewModel);
}
// POST: /Widget/Edit
public ActionResult Edit(WidgetFormViewModel viewModel) {
var existingWidget = _widgetService.GetWidgetByWidgetID(viewModel.WidgetID);
existingWidget.Employee = _widgetService.GetEmployeeByID(viewModel.EmployeeID);
// try { /* Save widget to DB */ } catch { /* Validation errors */ }
return ModelState.IsValid
// Update was successful
? (ActionResult) RedirectToAction("List")
// Model state is invalid, send the viewModel back to the view
: View("Edit", viewModel)
}
Now, here's the problem: When the ModelState is invalid and viewModel gets passed back to the view, its EmployeeList property is blank. What is the best way to deal with this?
Should I just repopulate it before returning to the view? This method seems difficult to maintain. (What if I add PageTitle and HeaderText to the view model as well? Suddenly there are more things to keep track of.) Is there another approach?
Inside of the catch block of the controller action handling the post, extract your error messages and add it to this.ModelState, then have it return this.Edit(viewModel.widgetID);.
You already have all the logic you need built up to display the view appropriately, you just want to use ModelState to make sure that errors make it back to the view.