MVC - ViewModel - model-view-controller

I need to create a linq statement that combines 2 tables and send that to the view.
Do I need to create a ViewModel for this.
Say the output will be the following
Table1.Vendor Table1.VendorName Table2.Address

It depends what your result type is.
If you return a dynamic object an anonymous type then you can't put that into the ViewBag directly (see: Stuffing an anonymous type in ViewBag causing model binder issues). But if you're returning something that's strongly typed, you can just put that straight into the ViewBag and bypass having a model.
That said, I'd always lean towards having a strongly typed model!

Yes You Should use View-model because if u want to send more than one table you may
use ViewBag or something equivalent viewdata[] that's wrong etc..
Because ViewBag for example is dynamic type it can't be sent to view with 2 table
For example if you do something like this
ViewBag.Workers=db.Workers.Join(idb.AspNetUsers, e => e.UserID, i => i.Id, (e, i) => new { UserName = i.UserName, SBIN = e.SBIN, }).ToList();
You will Get error 500 when you use this viewbag in your View
<span>#ViewBag.Workers.Anything</span>
Even in this example you should use for-each you still get error becausethe ViewBag is internal
So You could use something like that in the controller for this issue
var Workers=db.Workers.Join(idb.AspNetUsers, e => e.UserID, i => i.Id, (e, i) => new WorkerViewCardModelcs{ UserName = i.UserName, SBIN = e.SBIN, }).ToList();
return PartialView("_WorkerCard", Workers);
and Don't for get to use #model in the View or Partial View
#model IEnumerable<FinalProject.ViewModels.WorkerViewCardModelcs>
#foreach (var item in Model)
{
What ever logic you wish
}

Related

how to show data in view from Viewbag mvc4?

this is my controller
public ActionResult Index()
{
var data = (from o in db.aspnet_Users
from q in db.aspnet_Profile
where
o.UserId == q .UserId
select new{
o.UserId,
o.UserName,
q.Address,
q.Email,
q.Phone,
q.Mobile,
q.SocialID,
}
).ToList();
ViewData["Allprofile"] = data;
return View();
}
and i want to show the data in the view in table, there was a problem to show 2 db Models in one view because the model generated from Database not Code First so i'm trying show the data using ViewData any help ?
why are you not using a ViewModel here? you are somewhat defeating the purpose of MVC.
the view model will encapsulate the data you need to show on the View. you pass the view model to the View - the view will accept the strongly typed view.
the ViewData should never really be used for heavy/complex objects for a number of reasons - performance for one, but also no type safety/strongly typed support either.
change your code so you return a ViewModel with the data you need to show to the user.

How to show custom query result to view mvc3 Razor

I have Custom query Result as
public ActionResult Index()
{
var Query = (from E in db.SITE_MASTER.AsEnumerable()
where E.IS_PAGE == true
select new
{
E.POST_TITLE,
E.POST_TEXT
}).ToList();
return View(Query);
}
Now,
How can I make view for this result or How can I create View for this Result Query.
Thanks...
You can pass an anonymous type as a model, but please don't. It's ugly and will lead to maintenance problems.
As an alternative either use the ViewBag or create concrete type and pass that.

MVC 3 controller GroupBy View error

Im creating an MVC 3 view from a controller. My model "MyList", contains a large number of records. When I create my model using the following linq statement:
var model = _db.MyList.GroupBy(r => r.myKey);
I'm getting the error: "The model item passed into the dictionary is of type 'System.Collections.GenericlList' 1... but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable' ...
In the view I have the following code in the first line:
#model IEnumerable<MyApp.Models.MyList>
I tried returning
return View(model.ToList());
from the controller, but no joy. What am I missing?
model.ToList() will return a List<T> where T is MyList. Your model type is straight MyList. If the var declaration you have above already returns MyList, just do return View(model).
This one was dogging me all morning. I found the answer to my question in the following post:
Linq Distinct() by name for populate a dropdown list with name and value
I basically return the following:
public static IEnumberable<MyModel> FindTheKeys(this IQueryable<MyModel> myList)
{
return myList.OrderBy(r => r.AreaKey);
}
and then performed the select as indicated in the above post.
var model = _db.MyModel.FindTheKeys().GroupBy(r => r.AreaKey).Select(g => g.First());
GroupBy returns a collection of IGrouping<TKey, TSource>, not MyList (which is strange anyways, you wouldn't have a list of a list.
It doesn't even make much sense to convert a GroupBy into a list anyways. Did you actuall mean OrderBy?

How to access objects inside a List, saved in a Session. ASP.NET MVC 3

So I have this code:
var list = new List<Carrito> {
new Carrito { ProductId = producto.ID , Cantidad = 1, PrecioUnitario = producto.Precio }
};
Session["list"] = list;
return View();
Then I load the view but I don't know how to print the the content that is inside the session. Any ideas?
This is the code I use inside the view but doesn't work:
#foreach(var item in (IEnumerable<object>)Session["list"] )
{
<p>#item.ProductId</p>
}
it's as simple as reading back the value from your session varable and cast it to the original type, then do whatever you want
example:
#{
if(Session["list"]!= null)
{
var listBackFromSession = (List<Carrito>)Session["list"];
// do what you want
}
}
My recommendation is to use the more elegant way of ViewBag.
a quote from official asp.net mvc website about Viewbag:
New "ViewBag" Property
MVC 2 controllers support a ViewData property that enables you to pass
data to a view template using a late-bound dictionary API. In MVC 3,
you can also use somewhat simpler syntax with the ViewBag property to
accomplish the same purpose. For example, instead of writing
ViewData["Message"]="text", you can write ViewBag.Message="text". You
do not need to define any strongly-typed classes to use the ViewBag
property. Because it is a dynamic property, you can instead just get
or set properties and it will resolve them dynamically at run time.
Internally, ViewBag properties are stored as name/value pairs in the
ViewData dictionary. (Note: in most pre-release versions of MVC 3, the
ViewBag property was named the ViewModel property.)
Further more, This is a good article to read about the different ways you have in MVC in order to preserve data: http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications
example:
var list = new List<Carrito> {
new Carrito { ProductId = producto.ID , Cantidad = 1, PrecioUnitario = producto.Precio }
};
// use ViewBag
ViewBag.myList = list;
then inside your view, read them back like this:
var myList = (List<Carrito>)ViewBag.myList;
// your code
You're doing MVC fundamentally wrong. In MVC, Views are there only to render a model. The logic of accessing that model should be implemented in controller, or in any other place, but not in the View itself.
Thus I recommend that you simply pass your list to the view, and make your view strongly-typed by including #model List<Carrito> at the top.

MVC 3 Details View

I am new to MVC frame work. And i am making one page where we can see details of department by clicking on details link button.
While User click link button it fetch the all the records of the particular department in List Collection and redirect to Details View.Data has been fetched in List but while going to Details view it Generates following error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List1[DocPageSys.Models.Interfaces.DepartmentInfo]', but this dictionary requires a model item of type 'DocPageSys.Models.Interfaces.DepartmentInfo`'.
I understood the error but confusion to solve it.And stuck with this problem...
Since your Details view is strongly typed to DepartmentInfo:
#model DocPageSys.Models.Interfaces.DepartmentInfo
you need to pass a single instance of it from the controller action instead of a list:
public ActionResult Details(int id)
{
DepartmentInfo depInfo = db.Departments.FirstOrDefault(x => x.Id == id);
return View(depInfo);
}
So make sure that when you are calling the return View() method from your controller action you are passing a single DepartmentInfo instance that you have fetched from your data store.
To make it run fine initially you could simply hardcode some value in it:
public ActionResult Details(int id)
{
var depInfo = new DepartmentInfo
{
Id = 1,
Name = "Sales",
Manager = "John Smith"
}
return View(depInfo);
}
Oh, and you will notice that I didn't use any ViewData/ViewBag. You don't need it. Due to their weakly typed nature it makes things look really ugly. I would recommend you to always use view models.
Passing a list instead of a single item
This error tells you, that you're passing a list to your view but should be passing a single entity object instance.
If you did fetch a single item but is in a list you can easily just do:
return View(result[0]);
or a more robust code:
if (result != null && result.Count == 1)
{
return View(result[0]);
}
return RedirectToAction("Error", "Home");
This error will typically occur when there is a mismatch between the data that the controller action passes to the view and the type of data the view is expecting.
In this instance it looks as if you're passing a list of DepartmentInfo items when your view is expecting a single item.

Resources