ASP.NET MVC: Reuse of View by two controller actions - asp.net-mvc

'Add' and 'Edit' views are typically more or less identical. How can I reuse a View so that Foos/Add and Foos/Edit/[Id] both use it? What would the actions look like?
Thanks

Simply specify the view name when calling the View() method like
public ViewResult Add() {
//...
return View("Foo");
}
public ViewResult Edit(int id) {
//...
var model = repository.get(id);
return View("Foo", model);
}
Your view will have to handle null/empty model values for the Add action or you could populate your model with default values.

You may want to consider using an Editor Template as opposed to reusing the same View. An Editor Template is a partial View that is used for editing and/or inserting data.
This would require separate views but the code would be minimal. The bulk of the code would be in the template which you would reuse for both the Add and Edit actions.
After you create your template, your Add View would look like (Razor):
#model Models.Foo
<h2>Add</h2>
<p>
#Html.EditorFor(model => model) // equivalent to EditorForModel()
</p>
And your Edit View would look like:
#model Models.Foo
<h2>Edit</h2>
<p>
#Html.EditorFor(model => model) // equivalent to EditorForModel()
</p>

I would use jQuery ajax. Clicking on Add or Edit would call serve action which will return the same PartialView (if you want to reuse it).
Then, in the success function of ajax call, you have just to put returned html (from that PartialView) into certain part of your page (or popup).
Nice and clean and no page reload...

Related

Call the Controller’s Action method of the Partial View

I have a partial view that fills a select option.
From another view, I need to call the previous partial view to display my <select> <option> /> component.
However, I need to call the partial view WITH the associated controller.
Note : I am using .NET Core 6.
Here is my Controller :
public async Task<IActionResult> getYearMonth()
{
var result = await _context.MonthlyConsumption.Select(t => new { t.Time.Year, t.Time.Month }).ToListAsync();
return PartialView(result);
}
And my PartialView :
#model IEnumerable<TestLogin.Models.MonthlyConsumption>
<select name="mois" id="mois">
#foreach(var item in Model){
<option value="#Html.DisplayFor(modelItem => item.Time)">#Html.DisplayFor(modelItem => item.Time)</option>
}
</select>
I want to call the Controller’s Action method of the Partial View
I tried using #Html.Action, #Html.RenderAction but I can't use it.
#Html.Action is not working because i am using .NET 6
And I don't know why #Html.RenderAction is not working : IHtmlHelper does not contain definition for RenderAction.
I looked up why I was getting this error message. Some people say you have to import System.Web.Mvc but I can't get it to import in .NET 6.
#Html.RenderAction and #Html.Action are not available in Asp.Net Core, There are two methods can achieve what you want.
The First method is to use View Component. It is a new feature in Asp.Net Core and is also the officially recommended method, More details you can refer to this link.
The Second method is to use ajax, you can use ajax to access action, Then in success method, you can use js to add this partial view to the main View.

MVC RenderAction return only renders partial part

I have this contact form which I want to use on two pages (two views) in MVC 5.x (razor viewengine) So I have put the form in an partialview called _Contact and I have read that RenderAction is the best approach if you do not have the required data for the partialview in your model and if it is more standalone (seperate from the rest of the view)
So I call it like this:
#{ Html.RenderAction("SendMail", "Uk");}
My Uk controller has these two methods:
[HttpGet]
public PartialViewResult SendMail()
{
return PartialView("_Contact");
}
[HttpPost]
public PartialViewResult SendMail(FormCollection fc)
{
// send mail using values out of the form (sorry did not feel like building a complete model for it
ViewBag.Succeed = true;
// if smtpclient could not reach server etc. it returns false
return PartialView("_Contact");
}
it all works, but the PartialView is only rendered, not on the placeholder where i call the RenderAction. It works all great, but after the post it just displays the partial view and not the "parent view" and the shared layout view etc. I hope that I made myself clear. Please let me know if I need to add more info.
This is the BeginForm from my shared view:
using (Html.BeginForm("SendMail", "Uk", FormMethod.Post))
It will not work as expected for your current code, because when you post the form, it returns Partial View not complete View. If you want to get only partial view then you have to submit your form via Ajax.
In ajax's success handler you will get HTML of your partial view and that you can put in a DIV tag of partial view container.
This link will give you a better idea about Posting Partial View via Ajax.
ASP.NET MVC Partial view ajax post?

ASP.Net MVC Partial View Model Binding

I'm very new to MVC and I am looking to put a list of links on the main layout(master page) based on database table. I'm sure I read before that you shouldn't try to load models on the master page but use Partial Views instead (correct me if I'm wrong).
I've looked on Google and on other questions here but they only seem to talk about passing data from a main view to a partial view via ViewBag but I think I just want to add a partial view that I can add to the master page.
Can someone please tell me how to create a partial view I can add to master page so its used on every page and be able to load the list of links required i.e. by binding IEnumerable model to Partial View?
Try using ChildActionExtensions.Action
In your layout:
#Html.Action("MyAction", "MyController")
Controller:
public ActionResult MyAction()
{
var list = // get your list values
return PartialView("MyViewName", list);
}
Then just create your partial view:
#model IEnumerable<WhateverType>
#* View goodness *#
You can use this to bind whatever model you need to your partial view and if you use the Action helper in your Layout.cshtml it'll be rendered on every page.

In ASP.NET Mvc, what's the best way to fork to multiple action methods, and back to the same view?

So far:
I have a page with multiple submits on it, where each submit depends on the previous one.
The same page is rendered each time a submit is clicked.
I found myself writing spaghetti code in the controller method (branching based on the ViewModel), and wanted to factor out the behaviour for each submit into a separate method.
I implemented the solution found here - specifically the solution posted by mkozicki based on the article by Maartin Balliauw.
This worked well for forking to different controller methods. But I encountered two problems:
Returning to the same view each time.
Hard-wiring the action method names in the View.cshtml
Here's the code:
Controller:
public class PlayerStatController : Controller
{
public class PlayerStatViewModel . . . //quite complex ViewModel
// HTTP GET
public ActionResult SelectPlayer()
{
List<string> idx_list = getSeasonIndex();
return View(new PlayerStatViewModel(idx_list));
}
// One of three forked action methods
[HttpPost]
[MultipleButton(Name = "action", Argument = "ChosenSeason")]
public ActionResult ChosenSeason(PlayerStatViewModel viewModel)
{
List<string> team_idx = getTeamNameIndex(viewModel.selected_seasonIndex);
return View("SelectPlayer",new PlayerStatViewModel(new List<string>(), team_idx, new List<string>(), 0));
}
Here an excerpt from the view (SelectPlayer.cshtml)
<form action="/PlayerStat/ChosenSeason" method="post">
<fieldset>
<legend>Select Season</legend>
<div class="editor-field">
#Html.LabelFor(m => m.selected_seasonIndex)
#Html.DropDownListFor(m => m.selected_seasonIndex, Model.seasonIndex_select_list)
#Html.ValidationMessageFor(m => m.selected_seasonIndex)
</div>
<p>
<input type="submit" value="Choose Season" name="action:ChosenSeason" />
</p>
</fieldset>
</form>
Hence:
Is returning from the forked action method with return View("SelectPlayer",new PlayerStatViewModel(...); the best solution to forcing the same view (SelectPlayer.cshtml) to be rendered every time?
Is there a way to avoid hard-coding the action method name in the View (i.e., <form action="/PlayerStat/ChosenSeason" method="post">) I would like to keep using #using (Html.BeginForm()) if possible.
Specifying the view name in the return statement is the best and most practical way to return a view that is named something different than the current action method being executed. I believe this is by design in order to decouple action methods from a single view.
Again, for the view if you want the form to post to an action other than the one specified in the current URL you have to specify it explicitly. Using an empty BeginForm() will cause the form to post to the same URL that was returned on the previous request.
I believe what you have is the best way to tackle the problem and is the way I have my MVC application implemented as well. There is nothing wrong with being explicit, especially when it comes to views and view logic because they are by their very nature explicit. Separating the different submit buttons into different action methods is a solid approach and one that will inherently require you to specify which action to target for each submit button. You can think of this approach as analogous to Web Forms Server Side Event Handlers for button clicks (minus all the nasty page life cycle). This approach is elegant and clean, only the server side code corresponding to the submit is executed.

using update panel in ASP.NET MVC 4

Please explain me how to create update panel in ASP.NET MVC4 application. I looked for many blogs... but can not find any useful way.
This is my view
How I can separate these actions in same view?
Your two panels don't allow the user to switch between one or the other so I assume that you have an "intro" view with the option to either Sign in or Register. Right? In that case there is no real need for client side panel switching using Javascript/Ajax. Your "intro" view can pass a parameter to the controller action defining whether it needs a Sign In or Register view back.
For instance:
// RouteConfig.cs
routes.MapRoute(
name: null,
url: "login-register/{action}",
defaults: new { controller = "Authentication"},
constraints: new { action = #"(SignIn|Register)" }
);
// AuthenticationController.cs
public ActionResult SignIn()
{
...
return View(); // Will return the Authentication\SignIn.cshtml view
}
public ActionResult Register()
{
...
return View(); // Will return the Authentication\Register.cshtml view
}
Update panel does not really exist in ASP.NET MVC. It used to be there in ASP.NET Web form develeopment world before people actually realized it is better to use hand written jQuery ajax for doing the partial page update.
You may use jQuery ajax methods to post your form data to an action method and do partial page update to the page as needed. You may also consider using Partial view (to return a part of a page) as required.
In your case you can create 2 partial views for Sign in and Register and include those in your main view, to make your code more reusable.
<h1>Login or Register</h1>
<div>
#Html.Partial("Login")
</div>
<div>
#Html.Partial("Register")
</div>

Resources