I want to redirect to a different view depending on the result of a dataset, but I keep getting returned to the page I am currently on, and can't work out why. I drop into the if statement the action gets called but once i return the view to the new page, it returns me back to the current page.
CSHTML page
#{
ViewBag.Title = "Search Results";
EnumerableRowCollection<DataRow> custs = ViewBag.Customers;
bool anyRows = custs.Any();
if(anyRows == false)
{
Html.Action("NoResults","Home");
}
// redirect to no search results view
}
Controller
public ActionResult NoResults()
{
return View("NoResults");
}
View I cant get too..
#{
ViewBag.Title = "NoResults";
}
<h2>NoResults</h2>
Change to this:
#{ Response.Redirect("~/HOME/NoResults");}
Would be safer to do this.
#{ Response.Redirect("~/Account/LogIn?returnUrl=Products");}
So the controller for that action runs as well, to populate any model the view needs.
Source
Redirect from a view to another view
Although as #Satpal mentioned, I do recommend you do the redirecting on your controller.
This clearly is a bad case of controller logic in a view. It would be better to do this in a controller and return the desired view.
[ChildActionOnly]
public ActionResult Results()
{
EnumerableRowCollection<DataRow> custs = ViewBag.Customers;
bool anyRows = custs.Any();
if(anyRows == false)
{
return View("NoResults");
}
else
{
return View("OtherView");
}
}
Modify NoResults.cshtml to a Partial.
And call this as a Partial view in the parent view
#Html.Partial("Results")
You might have to pass the Customer collection as a model to the Result action or in a ViewDataDictionary due to reasons explained here: Can't access ViewBag in a partial view in ASP.NET MVC3
The ChildActionOnly attribute will make sure you cannot go to this page by navigating and that this view must be rendered as a partial, thus by a parent view. cfr: Using ChildActionOnly in MVC
You can go to method of same controller..using this line , and if you want to pass some parameters to that action it can be done by writing inside ( new { } )..
Note:- you can add as many parameter as required.
#Html.ActionLink("MethodName", new { parameter = Model.parameter })
Related
new to MVC so here goes.
I am currently loading up HTML.Partial on my Index.cshtml page like so:
#Html.Partial("~/Views/Switchb/editPerson.cshtml")
However, I am in need of customizing that in the controller depending on the current users category number.
So as an example, if the user has a category of 3 then I would need to do this:
#Html.Partial("~/Views/Switchb/3.cshtml")
Is there any type of call in the "code behind" in the controller that I can use in order to do that? Or would I just need to place the code within the cshtml page and pass its category number via the controller over to the cshtml page?
You can render a partial view from a controller action. You can pass the view name as string.
public ActionResult Switchb(string categoryNumber) {
var viewModel = new MyViewModel { CategoryNubmer = categoryNumber };
// additional processing, backend calls, formatting ....
return PartialView(categoryNumber, viewModel);
}
To call this action from View:
#{
var routeValues = new RouteValueDictionary(new {
categoryNumber= "3",
});
Html.RenderAction("Switchb", "MyController", routeValues);
}
Determine the category in the controller (via url parameter, from a database, or whatever) and then set that value as a property on your view's Model. Then in your line of code you can do this
#Html.Partial("~/Views/Switchb/" + Model.Category + ".cshtml");
I have a PartialView called GetSimilarPosts in my Post Views folder and in my main details page I have this link:
#Html.Action("GetSimilarPosts", "Post", new { id = Model.CurrentPost.Category.Id })
This is the Partial View:
#model IEnumerable<MyBlogger.Models.Post>
#foreach (var item in Model)
{
<p class="text-left">Similar Article: #Html.DisplayFor(modelItem => item.Title)</p>
}
But something strange is happening... the partial view does not reference my layout page but somehow its duplicating my entire page when I load maindetails:
In your controller, are you returning using View or PartialView
View will render with the Master Page, PartialView will render just the view
public ActionResult GetSimilarPosts(int id) {
var model = _repository.GetSimilarPosts(id); // data retrieval
return PartialView("_viewName", model);
}
This is because you're using the incorrect method... instead of #Html.Action use #Html.Partial.
#Html.Action() will execute an Action on your Controller, and then return the result, Html.Partial won't execute any actions, instead returning only the PartialView specified.
Both my home controller and my "StatusController" create a new instance of a DBEntities. The Home Controller returns a _db.VMs ViewData.Model to the _Layout.cshtml view and the Status Controller returns a _db.Jobs ViewDataModel to the _GetForStatus.cshtml view as a partial view. I call the VMs ViewData model to the _Layout view like so:
#foreach (var m in ViewData.Model)
{
<li>#m.Name</li>
}
This works fine, populating the dropdown list with names of the VMs from the DB.
The _GetforStatus.
The Home Controller piece for this is written like so:
public ActionResult index()
{
_db = new IntegrationDBEntitires();
ViewData.Model = _db.VMs.ToList();
return View();
}
The StatusController is written like so:
public PartialViewResult _GetforStatus()
{
_db = new OntegrationDBEntities();
ViewData.Model = _db.Jobs.ToList();
return PartialView();
}
The _GetforStatus view is written like so:
#model IntegrationWeb.Models.Job
<div class="progress progress-striped active">
<div class="progress-bar" style="width: #((Model.IS_Progress / Model.IS_Total)*100)%"></div>
</div>
#Html.Action("_GetforStatus", "StatusController")
This is called in the _Layout view like so:\
#Html.Partial("~/Views/_GetforStatus.cshtml")
I am getting an error here. "The model item passed into the dictionary is of type 'System.Collections.Generic.List' 1[IntegrationWeb.models.VM]', but the dictionary requires model item type 'IntegrationWeb.Models.Job'.
It seems as though there is a conflict with pulling two different DBEntities into the Layout view.
How do I return a View and a Partial View to the Index Layout in ASP.NET MVC 4?
Update: I just put the Action in the Home Controller, since I can't figure out why it won't find my Controller "StatusController". Now I am getting a different error using #{Html.RenderAction("_GetforStatus");} "The Model Item passed into the dictionary is type 'System.Collections.Generic.List '1[IntegrationWeb.models.Job]', but this dictionary requires a model item of type 'IntegrationWeb.models.Job'." Anyone know what is going on here?
A partial view inherits the Model from the parent view, unless you specifically pass a property, or create another object to pass to it. They are also processed of the same request. So in your example, the controller action for the partial view isn't even being executed. What you need to do instead is use RenderAction.
#{ Html.RenderAction("_GetforStatus","ControllerName"); }
This will then allow you to to execute a view with its own model and separate request.
Instead of
#Html.Partial("~/Views/_GetforStatus.cshtml")
simply do
#Html.Action("_GetForStatus", "MyController")
Html.Partial doesn't actually hit the action, it just renders the cshtml file.
I'm working on a MVC production project.
In my Production details view I have some buttons to get some more data from the database, but for this I need the id of the Product. I can see it exist but can I catch it?
Here's my controller that return data:
public ActionResult Details(long AProductionOrderId)
{
ProductionOrderList item = new ProductionOrderList();
item = ProductionOrderReg.GetProductionOrders(conn, AProductionOrderId);
ViewData["item"] = item;
return View();
}
Here's my details page when it load, I can see the id, but how to catch and use it in the buttons in the left to bring more date ?
You could use a hidden input on your view page to submit the ID.
your View:
<form method="post">
<button type="submit">Button Text</button>
<input type="hidden" name="AProductionOrderId" value="#ViewData['item']">
</form>
i wrote this im my controller
ViewData["id"] = AProductionOrderId;
and catched it in my view
long id = Convert.ToInt64( ViewData["id"]);
If you controller is:
public ActionResult Details(long AProductionOrderId)
{
var item = ProductionOrderReg.GetProductionOrders(conn, AProductionOrderId);
ViewBag.ProductionOrderId = AProductionOrderId;
return View(item);
}
then your AProductionOrderId will be in the ViewBag although I don't see the reason why you need it since whatever the type of item is (single object instance or list of objects) it contains your ID as a property because you're fetching the item by this ID. Anyway in your model you then need to declare your model like this:
#model YourModelNamespace.ProductionOrderList
and now you can access any property of your model in your view. But if you really want you can access it via ViewBag like this:
#{
long AProductionOrderId = Viewbag.AProductionOrderId;
}
Okay so, i am totally new to MVC and I'm trying to wrap my head around a few of the concepts. I've created a small application...
This application has a view for creating a new Individual record. The view is bound to a model ViewPage... And I have a associated IndividualController which has a New method...
The New method of the IndividualController looks like this...
public ActionResult New()
{
var i = new Individual();
this.Title = "Create new individual...";
i.Id = Guid.NewGuid();
this.ViewData.Model = new Individual();
return View();
}
Now, the above all seems to be working. When the view loads I am able to retrieve the data from the Individual object. The issue comes into play when I try and save the data back through the controller...
In my IndividualController I also have a Save method which accepts an incoming parameter of type Individual. The method looks like...
public ActionResult Save(IndividualService.Individual Individual)
{
return RedirectToAction("New");
}
Now, on my view I wanted to use a standard html link/href to be used as the "Save" button so I defined an ActionLink like so...
<%=Html.ActionLink("Save", "Save") %>
Also, defined in my view I have created a single textbox to hold the first name as a test like so...
<% using (Html.BeginForm()) { %>
<%=Html.TextBox("FirstName", ViewData.Model.FirstName)%>
<% } %>
So, if I put a break point in the Save method and click the "Save" link in my view the break point is hit within my controller. The issue is that the input parameter of the Save method is null; even if I type a value into the first name textbox...
Obviously I am doing something completely wrong. Can someone set me straight...
Thanks in advance...
Your New controller method doesn't need to create an individual, you probably just want it to set the title and return the view, although you may need to do some authorization processing. Here's an example from one of my projects:
[AcceptVerbs( HttpVerbs.Get )]
[Authorization( Roles = "SuperUser, EditEvent, EditMasterEvent")]
public ActionResult New()
{
ViewData["Title"] = "New Event";
if (this.IsMasterEditAllowed())
{
ViewData["ShowNewMaster"] = "true";
}
return View();
}
Your Save action should take the inputs from the form and create a new model instance and persist it. My example is a little more complex than what I'd like to post here so I'll try and simplify it. Note that I'm using a FormCollection rather than using model binding, but you should be able to get that to work, too.
[AcceptVerbs( HttpVerbs.Post )]
[Authorization( Roles = "SuperUser, EditEvent, EditMasterEvent")]
public ActionResult Save( FormCollection form )
{
using (DataContext context = ...)
{
Event evt = new Event();
if (!TryUpdateModel( evt, new [] { "EventName", "CategoryID", ... }))
{
this.ModelState.AddModelError( "Could not update model..." );
return View("New"); // back to display errors...
}
context.InsertOnSubmit( evt );
context.SubmitChanges();
return RedirectToAction( "Show", "Event", new { id = evt.EventID } );
}
}
If I don't create a new Indvidual object in the New method then when my view tries to bind the textbox to the associated model I get a NullReferenceException on the below line in my view...
`<%=Html.TextBox("FirstName", ViewData.Model.FirstName)%>`
With regards to the Save method. From what I understand since my view is strongly typed shouldn't I be able to have a method signature like...
`public ActionResult New(IndividualService.Individual ind)
{
return View();
}`
I thought that was the purpose behind model binding..?
I would strongly recommend that you take a step back from what you are doing and run through some of the Tutorials/Videos here http://www.asp.net/learn/
If you have a strongly typed View it means that when the Controller picks that view to generate the output the view has better access to the Model.
However the View is not responsible for what comes back from the client subsequently such as when a form is posted or a URL is otherwise navigated to.
ASP.NET-MVC uses information in the URL to determine which Controller to hand the request off to. After that it's the controller's responsibility to resolve the various other elements in the request into instance(s) of Model classes.
The relationship between the incoming request and the controller is clouded by the significant assistance the ASP.NET-MVC routing gives the controller. For example a route can be defined to supply parameters to the controller method and thats all the controller needs and hence you don't see any code in the method relating to the http request. However it should be understood that the contoller method is simply processing a http request.
I hope you can see from the above that it would be too early in a requests life-cycle for an instance of a class from the model to passed to a public method on a controller. Its up to the controller to determine which model classes if any need instancing.