Sending back collection of view models - asp.net-mvc

I have not used asp.net mvc 3 for a while (got side tracked). I can't remember is it good practice to send back a collection of view models?
Right now how I have my code is I have a view model that contains other view models. This way I only ever send back one view model.
The view models in this one view model could be a collection though. However I have a case where I need to send multiple view models back but that's all I need to send. I don't have any other properties or other view models getting sent back.
It seems kinda pointless to wrap it around another view model just to make it only return one view model.
So is it good practice or not?
Thanks

There's absolutely nothing wrong with that approach. Pass back whatever is necessary to render the View. You can certainly refactor later if you require additional data to be passed to your View.

I only pass one ViewModel to a View. BUT, that single ViewModel might have some properties which are OTHER ViewModels.
here's a sample view model for my homepage....
namespace RavenOverflow.Web.Models.ViewModels
{
public class IndexViewModel : _LayoutViewModel
{
public IndexViewModel(ICustomIdentity customIdentity) : base(customIdentity)
{
}
public IList<Question> Questions { get; set; }
public AuthenticationViewModel AuthenticationViewModel { get; set; }
public IDictionary<string, short> RecentPopularTags { get; set; }
public UserTagListViewModel UserFavoriteTagListViewModel { get; set; }
public UserTagListViewModel UserIgnoredTagList { get; set; }
}
}
The 2nd, 4th and 5th properties all contain individual ViewModels.
I grabbed this from some tutorial code I wrote up recently.

Related

Code reuse in multiple mvc views

I have read this link: https://www.future-processing.pl/blog/view-code-reuse-techniques-in-asp-net-mvc/
I can not use any of those helper ways...
I have to show on multiple mvc sites this string:
1612-1
That is an inquiry number: 16 is the day of month, 12 the month of year and 1 is the database id. I am sure that will not be the final impl but for now we take it as given.
public class MyViewModel
{
public string City { get; set; }
public string PostalCode { get; set; }
public List<string> ActionItemDescriptions { get; set; }
public string InquiryNumber { get; set; }
}
Where would you create the InquiryNumber?
If I put it inside the razor view I cant reuse it.
Seems business logic to me , so it belongs in the business layer.
Then, from within your controller you:
call the business component which returns the inquiry number
store the number in your view model
pass the view model to the view.
One way you could get an inquiry number, without using a helper, is this:
In a controller, have the following action method:
public ActionResult GetInquiryNumber()
{
// TODO : The code to get the inquiry number.
return Content("1612-1");
}
You can then call that method in any view you like, using the following:
#{ Html.RenderAction("GetInquiryNumber", "Home"); }
Obviously you will need to come up with your own method, and controller, names.
This isn't the ideal way of passing data to a view (using a viewmodel is preferable), but the above approach is an option to you.

Am I using viewModels correctly (MVC4)?

I have an object that I would like to display in a Details view. The object has a bunch of properties that the view needs.
The object also has parents and grandparents, which I need to display in the view.
What I have for my object viewModel is:
public class ObjectViewModel
{
// Used when creating a new object under a parent object
[HiddenInput(DisplayValue = false)]
public int? ParentObjectId { get; set; }
[Required]
public Object Object { get; set; }
// Info that only the view needs, which is defined in the Controller based on some logic
public string ActiveTitle { get; set; }
// A bre
public IList<Object> ParentObjects { get; set; }
}
I then use this in my Detail controller method:
public ActionResult Detail(int objectId)
{
// TODO: Make this a service call
var object = _db.Objects.FirstOrDefault(s => s.ObjectId == objectId);
if (object == null)
{
return View("Error");
}
var model = new SetViewModel() {
ActiveTitle = object.Name,
Object = object,
ParentObjectId = object.ParentObject.ObjectId,
ParentObjects = _objectService.GetParentObjects(set.ParentObject)
};
return View(model);
}
Does this look right? Or should I be pulling the required fields from the Object model into the viewModel, and not the objects themselves?
To have an object type in your view model is super vague and your code would be hard to support if you are not the original programmer. I would Add the class type to the actual model or use generics to specify the class type as shown below:
public class ObjectViewModel<T>
{
// Used when creating a new object under a parent object
[HiddenInput(DisplayValue = false)]
public int? ParentObjectId { get; set; }
[Required]
public T Object { get; set; }
// Info that only the view needs, which is defined in the Controller based on some logic
public string ActiveTitle { get; set; }
// A bre
public IList<T> ParentObjects { get; set; }
}
Either option will work, and you will often have a mixture of both techniques in a given application.
The key idea is that your view model should contain what the view needs in order to display the data to the user.
If your view merely displays the individual, primitive fields in simply controls, e.g. a series of labels or textbox controls, then your view model should probably specify only the fields, and not the parent object.
However, it's very possible for your view to include a templated or custom control that "knows how" to display a complex object in its entirety. In that case, your view model would need to include the entire object. (In practice I find myself doing this much more often in WPF than ASP-MVC but I've done both).
It looks like the answer will be contextual. Many teams using layered architectures might adopt architectural conventions whereby layers below X should not be referenced directly by your views, and a data access class might be a likely candidate for such a restriction. In your case, it does look like you will be binding your view's structure to the structure directly to your database schema (assuming, since you're using "_db"), which might be considered unreasonably tight coupling.
Also, I'm assuming you're using "object" to represent "any general thing" rather than literally a System.Object, since your objects appear to have an ObjectId property in your lambda expression.

Using the method in two model in one view of asp.net mvc 2.0

I have one view in my ASP.net MVC 2.0 project, I want to list the list of employee that I create method GetProfileCustomer() in CustomerModels and GetTransaction() in TransactionModels.
How can I import two different of models in a single view?
I'm fairly new to MVC as well, and I've struggled with the similar issues if I understand the question correctly.
I've found that you get much cleaner controller code if you design your ViewModels to be as close as possible to the data that the view is using. Your ViewModels can contain lists of other things including other model objects. Something like:
public class TransactionViewModel
{
public string dataelement1 { get; set; }
public int dataelement2 { get; set; }
//and so on...
//The Lists
public IList<Employee> EmpList { get; set; }
public IList<OtherModel> SomethingElse { get; set; }
//and so on...
}
In your controller, you construct and initialize your ViewModel
something like...
TransactionViewModel TVM = new TransactionViewModel();
//assign basic attributes here..
//make a list
TVM.Emplist = (from blah in context select blah).ToList();
//send it to the view
return View(TVM);
Hope this helps and happy to hear any feedback...

asp.net mvc2 - controller for master page and code organization

I've just finished my first ASP.NET MVC (2) CMS. Next step is to build website that will show data from CMS's database. This is website design:
http://img56.imageshack.us/img56/4676/portal.gif http://img56.imageshack.us/img56/4676/portal.gif
#1 (Red box) - displays article categories. ViewModel:
public class CategoriesDisplay
{
public CategoriesDisplay() { }
public int CategoryID { set; get; }
public string CategoryTitle { set; get; }
}
#2 (Brown box) - displays last x articles; skips those from green box #3. Viewmodel:
public class ArticleDisplay
{
public ArticleDisplay() { }
public int CategoryID { set; get; }
public string CategoryTitle { set; get; }
public int ArticleID { set; get; }
public string ArticleTitle { set; get; }
public string URLArticleTitle { set; get; }
public DateTime ArticleDate;
public string ArticleContent { set; get; }
}
#3 (green box) - Displays last x articles. Uses the same ViewModel as brown box #2
#4 (blue box) - Displays list of upcoming events. Uses dataContext.Model.Event as ViewModel
Boxes #1, #2 and #4 will repeat all over the site and they are part of Master Page. So, my question is: what is the best way to transfer this data from Model to Controller and finally to View pages?
Should I make a controller for
master page and ViewModel class that will wrap all this classes together OR
Should I create partial Views for
every of these boxes and make each
of them inherit appropriate class
(if it is even possible that it
works this way?) OR
Should I put this repeated code in
all controllers and all additional
data transfer via ViewData, which
would be probably the worse way :) OR
There is maybe a better and more
simple way but I don't know/see it?
Thanks in advance,
Ile
EDIT:
If your answer is #1, then please explain how to make a controller for master page!
EDIT 2:
In this tutorial is described how to pass data to master page using abstract class: http://www.asp.net/LEARN/mvc/tutorial-13-cs.aspx
In "Listing 5 – Controllers\MoviesController.cs", data is retrieved directly from database using LINQ, not from repository. So, I wonder if this is just in this tutorial, or there is some trick here and repository can't/shouldn't be used?
To get data to my Master Page:
I don't like using an abstract class to get data to the master page. I prefer composition over inheritance.
I don't like to use the ViewData dictionary because it's not strongly typed.
I would create Views, ViewModels and Actions for each section. Then call Html.RenderAction(...) For example:
I would create CategoriesDisplay.aspx with only the html for the redbox. I would pass that your CategoriesDisplay model. Then in my controller:
public class CategoryController : Controller
{
public ActionResult DisplayCategories()
{
var model = new CategoriesDisplay();
...
return View(model);
}
}
Then in my Master Page:
<% Html.RenderAction<CategoryController>(c => c.DisplayCategoreis()); %>
This will render the CategoriesDisplay view inline within the Master Page. Which in turn allows you have SOC (Seperation of Concerns), clean and manageable code.
I fought with this as well. Initially I did a lot of dumping of extra data into the ViewData, which ended up having to be casted back (made some extensions that eased this, but still not great).
I would go with your choice #1 and make a ViewModel that wraps all of the classes you would need.

Using Include and Exclude in asp.net mvc binding OR creat a new subset object?

Does it make sense create an object that contains only those properties that the user will input on the webpage, use that for binding in the controller, and then map to the full Entity Object? Or should you just use the entity object, and use Include and Exclude to make restrictions on what gets bound on input?
I have come to like the idea of using interfaces to segregate which properties should be included when the object is updated.
For example:
To create and update an person object:
interface ICreatePerson
{
string Name { get; set; }
string Sex { get; set; }
int Age { get; set; }
}
interface IUpdatePerson
{
string Name { get; set; }
}
class Person : ICreatePerson, IUpdatePerson
{
public int Id { get; }
public string Name { get; set; }
public string Sex { get; set; }
public int Age { get; set; }
}
Then, when binding model, just use the appropriate interface as the type and it will only update the name property.
Here is an example controller method:
public ActionResult Edit(int id, FormCollection collection)
{
// Get orig person from db
var person = this.personService.Get(id);
try
{
// Update person from web form
UpdateModel<IUpdatePerson>(person);
// Save person to db
this.personService.Update(person);
return RedirectToAction("Index");
}
catch
{
ModelState.AddModelErrors((person.GetRuleViolations());
return View(person);
}
}
See this article (and the comments) for a very good discussion of the options.
I recommend using a separate presentation model type in most cases. Aside from the issue of binding (which is important, but there are other ways around this issue), I think that there are other reasons why using presentation model types is a good idea:
Presentation Models allow "view-first" development. Create a view and a presentation model at the same time. Get your user representative to give you feedback on the view. Iterate until you're both happy. Finally, solve the problem of mapping this back to the "real" model.
Presentation Models remove dependencies that the "real" model might have, allowing easier unit testing of controllers.
Presentation Models will have the same "shape" as the view itself. So you don't have to write code in the view to deal with navigating into "detail objects" and the like.
Some models cannot be used in an action result. For example, an object graph which contains cycles cannot be serialized to JSON.

Resources