3

(first time posting and fairly new to MVC) I currently have a MVC/C# application where the user selects a list of ID's and then chooses a Report Type (8 possible different reports calling 8 different database views). I am passing all of these parameters to the controller. Based on the report type chosen, I want to fetch the data, send it back to the view and then display the data in a grid/table format.

I tried sending the data via ViewBag and ViewData but had trouble parsing the actual columns/data using @foreach. This is when I decided to try ViewModels.

//My ViewModel....
//I know that I am missing the {get;set;} code which is where I also
// need help with.  I need to pass the selected ID's to each database view and 
// perform additional query requests (i.e. Distinct, Order By). 
// Sample query:
// var dd = (from p in _db.Report1 select new { sId = p.ReportID, UserName = p.Submitted_By, 
//      Balance = p.TotalDebt}).Distinct();
// dd = dd.Where(w => chosenUserIDs.Contains(w.sID));
// dd.OrderBy(p => p.sId).ThenBy(p => p.UserName).ThenBy(p => p.Balance);

public class UserReportsViewModel
{
    public List<namespace.report1> Report1 = new List<namespace.report1>();
    public List<namespace.report2> Report2 = new List<namespace.report2>();
    public List<namespace.report3> Report3 = new List<namespace.report3>();
    ...
}

//My Controller
UserReportsViewModel UserReportVM = new UserReportsViewModel();
switch (reportType)
{
    case "REPORT1":
        //Pass the selected ID's and get the data back from Report1 db view
        // not quite sure how to do this.
        break;
    case "REPORT2":
        break;
    case "REPORT3":
        break;
    default:
        break;
}
return View(UserReportsVM);

Am I even on the right track? I also came across something about partial Views and having the View call/referrence the correct partial View (?). Older languages were a lot simpler to accomplish this but I am really liking MVC/.Net/C#.

As for my database, I am using CodeFirst Entity framework.

5
  • Is the data different for each view? Or is the data the same just the view is different? Commented Jun 19, 2015 at 20:57
  • Is the fetch data different in each case? Create a single model that facilitate each case. Commented Jun 19, 2015 at 21:01
  • Each view will return unique data with unique set of columns. Commented Jun 19, 2015 at 21:04
  • Then put conditions in your view like @if(mode.Report1!=null){ // your logic for report2 goes here } else if(model.Report2!=null){ // your logic for report2 goes here } Hope this will help Commented Jun 19, 2015 at 21:07
  • I don't understand a "View" is how the data is layed out. View's don't return data, they are rendered and sent to the client. Commented Jun 19, 2015 at 21:31

3 Answers 3

1

I highly suggest you have view, viewmodel and action for each report. Just call the correct endpoint based on the requested report in the client.

Or, if you want to do this with one endpoint (action) specify the view you want to return. If you don't specify the view name, it returns a view based on the action name, but you can specify the view to render.

return View("ViewToRender", viewModel);

If you want to get fancy, you could do this with one view. Include a layout object in the viewmodel with the data... this way you can use one view model. The layout would be a list of "column info fields". Column1 would have This header, this width, etc. It would be bound to GenericReportViewModel.Column1.

From there, you just need to project your data into that generic view model.

Sign up to request clarification or add additional context in comments.

3 Comments

I like this idea as it will keep my code clean. Is it best to do partial views? I will need to keep the filtering section available on all reports (filtering section contains the list of ids, drop-down that loads the list of ids, and which report was selected). If more reports are request, then creating them will not (should not) affect the current code base.
Usually you would use a partial if you have a large portion of repeating code that you call from your view. It really depends on what you need. But yes, your filtering section could be a partial that you call from all your report specific views to keep your views DRY.
It also depends on if you are using AJAX or not. You many have one view with your Criteria at the top... then, make an ajax call to the correct endpoint/action. That action would do return PartialView("thereportview", model) and then you just load that into a DIV on the client.
1

Each model will return unique data with unique set of columns.comments by the user above

If this is the case write the logic in the view like this

@if(model.Report1!=null && model.Report1.Count!=0){
 // your logic for report1 goes here or you can also use partial view to render
 } 
else if(model.Report2!=null && model.Report2.Count!=0)

{ 
// your logic for report2 goes here or you can also use partial view to render
} 

Same for all the other reports. Hope this will help

5 Comments

Yuck. Better to have one view for each report, and render the correct view based on the report specified.
Yes, otherwise your view markup will be some how impossible to manage
This is what I was trying to avoid. It would work but a bit messy.
That's why i added in the comments add either the markup or partial view to render.
Ok, I understand now your "partial view to render" in your comments. So the controller would return the ONE master model with only one object with data and have the view render the partial view?
1

Thank you all for your help and guidance. I decided to to Partial Views. The solution to my question is as follows.

For each report, I get the data and immediately store the data into ViewData.

IQueryable<dbViewName> Report8 = _db.dbViewName;
ViewData["qryResults"] = Report8;
...
return View(ViewData["qryResults"]);

Then in the main view I call the partial view:

@Html.RenderPartial(rt, ViewData["qryResults"]);

In the partial view my model is strong type.

@model IQueryable<dbViewName>

This allowed me to list out the data in tables by using:

@foreach (var item in Model)

It is clean and easy to implement any additional reports that the client may request in the future.

Again, thank you all for your input.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.