ASP.NET MVC Single View for CRUD operation - asp.net-mvc

I am working on a ASP.NET MVC project. I have a question about the View in a CRUD operation.
In most of the examples I have seen, separate views for each CRUD operation (e.g. Add, Edit, Delete) are used. Now imagine if I have 100 tables in my database, and each of them requires CRUD operations via a View. Is it best to create these separate Views for each table or create a function that would create these Views for me, such as below?
public ActionResult CreateSubject()
{
return View(Model.toList());
}
public ActionResult EditSubject()
{
return View();
}
public ActionResult DeleteSubject()
{
return View();
}

I use separate actions for each operation on my controller and create a simple PartialView that handles all the fields and then I use a shared View from my Shared folder that loads my partial view.
public class CRUDController : Controller {
public ActionResult Create() {
return View(new CreateModel());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(CreateModel model) {
if(ModelState.IsValid) {
//save to db return view or redirect
}
return View(model);
}
public ActionResult Edit(it id) {
var model = new EditModel();
model = //load and map from db
return View(model);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(EditModel model) {
if(ModelState.IsValid) {
//save to db return view or redirect
}
return View(model);
}
}
Supporting interfaces:
public interface ICreateModel {
}
public interface IEditModel {
int Id {get;set;}
}
CreateModel.cs:
public class CreateModel : ICreateModel {
public string SomeProp {get;set;}
}
EditModel.cs:
public class EditModel : CreateModel, IEditModel {
public int Id {get;set;}
}
_create.cshtml:
#model CreateModel
#Html.TextBoxFor(x=>x.SomeProp)
Create.cshtml:
#model ICreateModel
#using(Html.BeginForm) {
#Html.Partial("_create")
<input type="submit" value="Submit"/>
}
Edit.cshtml
#model EditModel
#using(Html.BeginForm) {
#Html.Partial("_create")
#Html.HiddenFor(x=>x.Id)
<input type="submit" value="Submit"/>
}
This is an example of how I handle my multiple CRUD operations (at least in terms of showing forms for them). There would obviously be more content in your Create/Edit views
By placing the Edit.cshtml and Create.cshtml in the Shared folder, it'll be used by default when you return a view from an action with those names. By default the view engine checks the appropriate view folder for the controller for the file and then looks to Shared. Each of your _create.cshtml partial should be in the appropriately named View folders and they will be delivered correctly.

Related

How To call An Action In Umbraco Controller?

I created an Umbraco DocumentType with the alias Personal and created a controller that inherits
Umbraco.Web.Mvc.RenderMvcController
I added two Actions, one is the default action and the other is called Test.
How can I fire the Test Action from the Personal controller?
public class PersonalController : Umbraco.Web.Mvc.RenderMvcController
{
// GET: Personal
public override ActionResult Index(RenderModel model)
{
return base.Index(model);
}
public String Test(RenderModel model)
{
return "fff";
}
}
When I put the url like this: localHost/personal/test it shows:
No umbraco document matches the url '/test'.
Which is right, so how can I call it?
I would do it like this
[HttpPost]
public ActionResult SubmitSearchForm(SearchViewModel model)
{
if (ModelState.IsValid)
{
if (!string.IsNullOrEmpty(model.SearchTerm))
{
model.SearchTerm = model.SearchTerm;
model.SearchGroups = GetSearchGroups(model);
model.SearchResults = _searchHelper.GetSearchResults(model, Request.Form.AllKeys);
}
return RenderSearchResults(model.SearchResults);
}
return null;
}
public ActionResult RenderSearchResults(SearchResultsModel model)
{
return PartialView(PartialViewPath("_SearchResults"), model);
}
See this blog post for the full context behind where this code snippet came from.
http://www.codeshare.co.uk/blog/how-to-search-by-document-type-and-property-in-umbraco/

What's the best regarded way to organize multiple ASP .Net MVC View models within a single view?

My app has a main dashboard which is comprised of 8 different partial views; each backed by their own view model and in my controller I'm just calling
public ActionResult mainDashboard(){
return View()
}
to return the dashboard. My question is would it be recommended to create a dashboard view model that also contains references to the view models of the partial views? What's considered a recommended best practice in this situation?
Ohkk here is a good idea as well to use html.Action instead of html.partial
This would look more like this:
public ActionResult Dashboard()
{
return View();
}
public PartialViewResult Clubs()
{
....
return PartialView(db.Clubs.ToList());//this assumes the partial view is named Clubs.cshtml, otherwise you'll need to use the overload where you pass the view name
}
public PartialViewResult Alerts()
{
....
return PartialView(db.Alerts.ToList());
}
Dashboard.cshtml
<div class="dashboard_alerts">
#Html.Action("Alerts")
<div class="dashboard_pending_clubs">
#Html.Action("Clubs")
</div>
<div class="dashboard_verified_members">
#Html.Action("Members")
</div>
OR
You would need to create a ViewModel specific for the Dashboard page precisely this would be more efficient way
public class DashboardViewModel
{
public IEnumerable<GMC.Models.Clubs> Clubs { get; set; }
public IEnumerable<GMC.Models.MemberUsers> Users { get; set; }
public IEnumerable<GMC.Models.Alerts> Alerts { get; set; }
}
Then, in the Dashboard action method, you would populate each list:
myModel.Users = db.MemberUsers.ToList();
...
You would then need to update the view to take in this new ViewModel
#model DashboardViewModel
Finally, from within the view, you would need to pass in the data to each partial:
#Html.Partial("DashboardAlerts", Model.Alerts)
#Html.Partial("DashboardClubs", Model.Clubs)

ASP.NET MVC - Routing Structure

I have an ASP.NET MVC 4.5 app. In this app, I have two controllers: Parent and Children. The look something like this:
[RoutePrefix("dashboard/parents")]
public partial class ParentsController : Controller
{
public ActionResult Index()
{
return View();
}
[Route("add")]
public ActionResult Add()
{
return View();
}
}
[RoutePrefix("dashboard/children")]
public partial class ChildrenController : Controller
{
public ActionResult Index()
{
return View();
}
[Route("add")]
public ActionResult Add()
{
return View();
}
}
At this time, these controllers work how I want. However, in my ChildrenController, I want to add something like an overload to the add route. In other words, I'd like for the user to be able to visit: /dashboard/parents/{parentId}/children/add. This URL would be used to add a child to a specific parent. My question is, how do I update my controllers to allow for this type of scenario?
thank you!
I think what you are looking for the is "~" to override your default routeprefix.. The following example is taken from the asp.net website which tells you how to accomplish the task.
[RoutePrefix("api/books")]
public class BooksController : ApiController
{
// GET /api/authors/1/books
[Route("~/api/authors/{authorId:int}/books")]
public IEnumerable<Book> GetByAuthor(int authorId) { ... }
// ...
}

Reusing Controller Action based on ViewModel

I will have a registration form on my website which will firstly show the boardrules / legal. Once accepted it will then show the main registration form. Using a ViewModel as below:
public class MyViewModel
{
public int Readrules { get; set; }
public int Coppa { get; set; }
}
public ActionResult Register(MyViewModel model)
{
... at this stage model.Readrules and model.Coppa will contain the values passed
as query string parameters tat you could use here
}
The idea is if I go to /register it will show the rules and then /register?readrules=1 it will then show the registration form. This is how it was done in PHP but now I am migrating to ASP.NET..
What is the best way of doing this? Can I redirect to the same action and just parse the value of model.ReadRules or must I use more than one action? I would prefer to keep this in one action and just check if model.ReadRules == 1 and either display the boardrules or registration form.
Thanks
Instead of re-using the Register action, you could have different controller actions for displaying the rules, registering and processing the registration, like so:
Controller Actions:
public ActionResult BoardRules()
{
return View();
}
public ActionResult Register(MyViewModel model)
{
if (model.ReadRules != 1)
return RedirectToAction("BoardRules");
return View();
}
public ActionResult Registration(MyViewModel model)
{
if (model.ReadRules != 1)
return RedirectToAction("BoardRules");
//Process the registration
return View();
}
Views:
BoardRules.cshtml:
#* HTML Displaying Rules *#
Accept Rules
Register.cshtml:
#using (Html.BeginForm("Registration", "[Controller Name]", new { ReadRules = 1 }))
{
#* Form Fields *#
<input type="submit" value="Process Registration" />
}
Registration.cshtml
<h2>Congratz on Registering!</h2>
public ActionResult Register()
{
return View("boardrules"); //Default
}
public ActionResult Register(MyViewModel model)
{
if (model.ReadRules == 1)
{
model.ReadRules++; //Next time it won't be 1 but step 2
return View("registration",model);
}
else
{
//Do IF or Case for other step
}
return View("boardrules"); //Default
}

Redirect to same view

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

Resources