Reusable Code in MVC3 C#.Net - asp.net-mvc-3

I have an MVC3 C#.Net web app. I have two views that display the same HTML table. However, each View represents a different Model. View 1 = "ProposalEdit", View 2 = "DocEdit". Both the Proposal model and the Doc model have a property:
ICollection<Deliverable> Deliverables.
In each of the Edit Views, I display the Deliverables belonging to the Model of that View. It's identical code in each of the Edit Views, only the Model behind the Edit Views is different. So, there's a lot of duplicate code.
How can I modularize this in order to reduce the duplicate code?

#Mike, that is exactly what I would do. The main point though is having the DisplayTemplates for each model. Even a DateTime object could have a DisplayTemplate if you wanted to.
Edit:
Here's an example of using the DisplayTemplate for just the Deliverables model
#model ICollection<Deliverables>
#foreach (var deliverable in this.Model)
{
#this.Html.DisplayFor(d => deliverable)
}
You would also, of course, have a template under ~\Shared\DisplayTemplates\Deliverables.cshtml or for editing under ~\Shared\EditorTemplates\Deliverables.cshtml

Related

Many models with one dynamic mvc view

I am planning a new mvc 3 application.
I am trying to make things as simple as possible.
Here's my question.
I'm planning on having many different models with different params. I am going to have crud operations for all these models but I don't want to have a view for each one. I would like to have one list view and one edit view.
I know this goes agains the lose coupled style of mvc architecture but It would be very handy just for me to send the view a model and the view would work out what fields to add etc.
Has anyone heard o a way to do this?
MVC has an Html.EditorFor() helper into which you can give a whole model and MVC will generate a form from it. I have not tried whether this works dynamicly when your view's model is type of object and you give concrete objects into it, but it might work.
But for all those headaches you will have in the future with your approach I would strongly suggest for you to try to make your different models into an object hierachy (so you will have inherintance) and compose your views with different partial views based on the model's type.
I have used the last way of doing things sucessfully on many occasions. Something in the lines of (code in your topmost view):
#model Animal
//Show Animal fields
#if(Model is Cat)
{
//show cat specific fields
Html.Partial("_cat", Model);
}
else if(Model is Dog)
{
//show dog specific fields
Html.Partial("_dog", Model);
}
So in your controller you could pass either a Dog, Cat or Animal to this view and what would be rendered is dependent on the Model's type.

MVC 3 Combinging multiple controls in one sort control template

I'm working on some forms, and often I can reuse the same amount and combination of fields together, is it possible to group them all as a template and then call it from the page?
For example:
2 radio buttons with labels and 2 texboxes under.
How is it called so i can do a proper research?
You can use Partial View, its like a reusable component.
These links will elaborate more:
http://www.devcurry.com/2012/04/partial-views-in-aspnet-mvc-3.html
http://www.dotnet-tricks.com/Tutorial/mvc/2IKW160912-Partial-View-in-Asp.net-MVC3-Razor.html
MVC3 Partial Views
Create a Partial View and keep your markup which you want to reuse in that. You can use these Partial views in other views as needed then.
You can use the Html.Partial helper method to call the partial views in other views.
#Html.Partial("RecentItems")
You can also pass some model to your partial view as well
#Html.Partial("RecentItems", Model.RecentItems)
Assuming Your partial view is strongly typed to a class which is of the same type as the type of Model.RecentItems, of the caller view.

Finding, loading and adding partial views dynamically

I've been tasked with converting an existing webforms application to mvc 3 razor.
The application currently has an aspx page which has a static header user control and "n" amount of other user controls which are dynamically created. In the code behind for the file, it is executing the below code in various specific sections to dynamically process user controls with information provided from the database.
I know how to statically create partial views, but being somewhat new to MVC, how would I go about defining this new "aspx" page and also to dynamically find, load and add the partial views (each equivalent to the below webforms code)?
btw, the code will be in C# as well.
Dim parent As Control = Page.FindControl(_moduleSettings.PaneName)
Dim portalModule As PortalModuleControl = CType(Page.LoadControl(_moduleSettings.DesktopSrc), PortalModuleControl)
parent.Controls.Add(portalModule)
I think I can do something like this when the page is rendering. I want to make it as simple as possible.
The "PaneName" will be set in the parent variable which determines where in the page it will be shown (Left, Right, or Main)
The "DeskTopSrc" is the name of the partial view to display.
So, take the code out of the code behind and place it in the main View. Perform the above processing logic in the View (boy, switching from aspx code behind to a View throws me a loop. I gotta get use to doing the processing in the View. Reminds me of Classic ASP, but the Razor syntax will help).
Display the partial view via the #Html.PartialView('partial view name'). This view might have a grid in it associated with a specific model.
Below is the part I am unsure about.
I've done database processing for a main View associated with a Controller, but not with a partial view that needs to do some database processing.
Perform any database processing logic (if any) for this partial view in the Controller associated with the main View (which contains this partial View).
In the Action Index method while looping over these "partial views", I can get the data and display the views....
Ahhh, I think I got it.....
After carefully thinking it through, if someone could help me out with the last statement here, I would greatly appreciate it.
1.Have partial views already statically created with the specific HTML markup that I need in the Views/Shared folder.
2.In the main View, I will already have
#Html.Partial(ViewData["partial_view_left"])
#Html.Partial(ViewData["partial_view_right"])
#Html.Partial(ViewData ["partial_view_main"])
statements in specific locations of the HTML which will render the partial views as I retrieve their names from the database.
3.In the Controller's Index method, I need to do the following:
a) Loop through the converted logic (from the CodeBehind of the existing WebForms page in the PageLoad event) in the Index action method of the new Controller which will load the partial views dynamically.
1) Find out where the partial view will be displayed (left, right, main) from the database via the "parent" variable.
2) Find out the name of the partial view that will be displayed from the database via the “DesktopSrc” variable.
eg: ViewData["partial_view_left"] = "left_view"; OR
ViewData["partial_view_right"] = "right_view"; OR
ViewData["partial_view_main"] = "main_view";
3) Right here is where I am unsure of how to properly display the partial view.
I need to have the equivalent of a webforms "Controls.Add" method to render each partial view from the Controller that I retrieve from
the database from step 3.a.2
What statement can I use in this Index method of the Controller that will accomplish this?
In other words, if I dynamically need to display several partial views inside of a parent view, how is this accomplished in MVC?
I know for each partial view, I can send over the model associated with it, but I just don't know how I can place several partial views inside the main view page at run time from one Action method.
If your partial views need to do some processing, like database retrieval, then you should use
#{Html.RenderAction("ActionName");}
This will call an action method (which doesn't have to be on the same controller) that can dynamically choose a view based on logic, and populate the ViewModel with data from the database.
public ActionResult ActionName()
{
var modelData = GetData();
return View(settings.DesktopSrc, modelData);
}

MVC3 : How to call A view from another controller from a different controller

I have to make a form consisting of several sub forms which may or may not contain grids.
For simplicity lets say i am using 2 models
1. Applicant Detail : where the applicants basic information (Name, DOB, Gender) is placed.
2. Applicant Experience : where the applicants prev work experience details are being placed.
Now for organizing purpose i am thinking of making two different controllers Namely ApplicantDetail and ApplicantExperience and both will contain their respective functionalities. But as soon as the user enters his basic information i want the same view to call in the index view of ApplicantDetail which will have a grid and the user can enter his/her prev working details in the form of rows.
My basic question is, is there anyway that can i create single razor view which will contain the razor view of my ApplicantDetail as well??
I believe what you are looking for is RenderAction.
Using RenderAction you can invoke controller/view within any view.
So if you had some razor view and second Controller and View combination, you could invoke it like so within the first view:
#{ Html.RenderAction("Action", "Controller2"); }
This can be useful when trying to modularize functionality.
See this blog post from Phil Haack for more details:
Html.RenderAction and Html.Action

What kind of data belongs in a view model?

The name "view model" suggests that it models the data for the view. That much is obvious. What else can or should go in the view model?
As an example, a view might display a list of items in a shopping cart, fields for customer's credit card info, and fields for customer's billing information. The view model might contain properties for all that OR it might only contain properties for the shopping cart items.
The view model is a class that represents the fields that your view shows/modifies. So for example if you are going to show a shopping cart and customer's credit card all on the same page these properties should all belong to the view model.
You could even put properties like this in your view model if the view is going to show a drop down list of day names:
public IEnumerable<SelectListItem> DayNames
{
get
{
return CultureInfo
.CurrentCulture
.DateTimeFormat
.DayNames
.Select((dayName, index) => new SelectListItem
{
Value = index.ToString(),
Text = dayName
});
}
}
How exactly you use your view models is a judgement call. One developer might have fewer typed ViewModels so they can be reused. Another developer might have more ViewModels, each smaller and more specific to particular actions. And another developer might rely more on ViewData.
If possible, have your view models be well-organized, contain just what the view needs, and consist mostly of light entity objects. If you have a complicated view though, don't be afraid to make a highly customized view model class that will help simplify the view logic. It's okay to make reusable ViewModels that have a little unused data in them, but avoid using just a few one-size-fits-all ViewModels. ViewModels should have just the data needed for that view or very close.

Resources