ASP.NET MVC 3 - Making View selection generic in controller - asp.net-mvc-3

I have two actions in my controller which are sharing part of logic responsible for selecting the view. How Can I make this part common accross actions. Example:
Controller Document
Action Open
if there is one document found and is type X, display it using OpenX View
if there is one document found and is type Y, display it using OpenY View
if there are more than documents found, display list using List View
if there are no documents found, display error using Error View
Action OpenMetaData
if there is one document found, display it using OpenMetaData View
if there are more than documents found, display list using List View
if there are no documents found, display error using Error View
As you can see, points 3,4 are the same as 2,3
I would like to create something like
public DocumentController
{
public ActionResult Open( ... )
{
var dataFromWebService = service.GetData( ... );
return ViewSelector.GetLaunchView(dataFromWebService);
}
public ActionResult Open( ... )
{
var dataFromWebService = service.GetData( ... );
return ViewSelector.GetOpenMetaData(dataFromWebService);
}
}
public class ViewSelector
{
public static ActionResult GetLaunchView(DataFromWebService dataFromWebService)
{
if( dataFromWebService contains document type X)
return new ViewResult("OpenX",data);
if( dataFromWebService contains document type Y)
return new ViewResult("OpenY",data);
return CommonLogic(dataFromWebService);
}
public static ActionResult GetOpenMetaData(DataFromWebService dataFromWebService)
{
......
}
private static ActionResult CommonLogic(DataFromWebService dataFromWebService)
{
.... Common logic
}
}
I would like to do this to make my Controller as clean as possible.
Can I create ViewResults outside controller, attach data to them are return them in the action ?
Is this good or bad design ?
Maybe someone have better idea how to handle this

If you don't need to access any of the contexts of the controller you can create the results outside the controller. In your case I would consider making the GetOpenMetaData() and GetLaunchView methods private methods of the controller.
If you need to share it accross multiple contollers you could also consider putting it into an abstract BaseController and let your controllers inherit from it.

Related

use RenderMvcController to filter a list in Umbraco

my goal is to create a list of contents (of specific docType) . in this list I have a filter button and two ddlist dynamically filled with children data. when user click the "filter" , the list should be updated by selected ddlist values.
Is it possible to use RenderMVCController for this ? I couldnt used surfaceController because I cant have access to Index action before rendering the page.
Is it possible to use Ajax when user submit the form instead of refreshing all page?
View
using (Html.BeginUmbracoForm("FilterPage", "inTheFieldController", FormMethod.Post, htmlAttributes: new { #id = "PageInTheField" }))
{
//....
}
Controller
public class inTheFieldController : RenderMvcController
{
private readonly UmbracoContext umbracoContext;
public inTheFieldController()
{
umbracoContext = UmbracoContext.Current;
}
// GET: inTheField
public ActionResult Index()//RenderModel model)
{
}
and I want to have something like this:
[HttpPost]
public ActionResult FilterPage(inTheFieldModel model)
{
return null
}
But it never reached to this point,it asks for surfaceController.
Yes, if you use the BeginUmbracoForm it will always expect a SurfaceController. Ideally you should be using SurfaceController for forms. I dont clearly understand what you are trying to do here but you can use #Ajax.BeginForm and couple it with a SurfaceController action

call Model function from View

I have an HTML select in View, for the select options i have to retrieve value from database. I have a function in model that returns LIST of options. How can I call the model's function from view.
Something like this:
public class XXXXViewModel {
//properties...
public List<Option> Options {get;set;}
}
and in your controller:
public class XXXXController : Controller {
public ActionResult SomeAction(){
var model = GetModelFromRepository();
var viewModel = new XXXXViewModel{
//Properties...
Options = model.GetOptions();
};
return View(viewModel);
}
}
So, you controller takes care of providing the options to the view using a ViewModel class containing everything your view needs.
Hope it helps.
create an event which is going to call that function and by the help of json and Ajax javascript you can easily do it
its a small concept that model canot be call from html after rendering on client side you have to take care of it by controller action and ajax is a good practice for it in maximum of mvc application

.NET MVC3/Holding temp model

I have a situation where i have to take input(form) from user. After continue button is pressed next view page is displayed. But after continue is pressed i don't want to store the model in the DB. I have to display some details(combining some tables) according to input given by the user earlier and again get some data from user. Only then i want to store the model in the respective tables.
How can i perform this? I tried getting Model from user and passing to the function that generates next page. Is this is way to do it? or there is other way around?
Store the model submitted by the first form in session.
[HttpPost]
public ActionResult ContinueForm1(Model1 model1)
{
if(ModelState.IsValid)
{
Session["Model1"] = model1;
return View("Form2");
}
return View();
}
[HttpPost]
public ActionResult ContinueForm2(Model2 model2)
{
if(ModelState.IsValid)
{
... model2 is already here, get the model1 from session
... and save to datatbase finally return a different view or redirect to some
... other action
}
return View();
}
You are heading down the right track.
You need to grab the model that is passed back from the first view - preferably you are using ViewModels here rather than binding directly to your db models. Have a look at http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ and Why should I use view models? as to why these are good things.
The easiest way to do this is to pass the model in as an argument to your method e.g.
Assuming that your views are using the same ViewModel ( which may or may not be true) then you can send the viewmodel straight to your new view - else you can copy the elements into a new viewModel and send that.
e.g.
[HttpPost]
public ViewResult Step1(MyViewModel viewModel)
{
//Do some validation here perhaps
MySecondViewModel secondViewModel = new MySecondViewModel{
Id = viewModel.Id,
// etc. etc.
};
return View("Step2", secondViewModel);
}
Then you can carry on as you need until you have to persist the entity to the database.
NB as you do not need to do anything special in the form to make it post the model as an argument as long as the view is strongly typed to that ViewModel.

how to fill a viewmodel EF 4.1

I am working on asp.net MVC 3 project. I am using EF 4.1 code first approach. I have entity class called disputes. It maps to a table in database name tblDisptes. It has three properties names Lastviewedby, Lastupdatedby, LastRespondedBy ... all three integers. I have created a viewmodel 'disputeviewmodel' with three more properties Lastviewedbyname, Lastupdatedbyname, LastRespondedByname and a property named dispute. Now my repository function returns list of disputes. how to convert this list to List of disputeviewmodel so that these three properties are filled with the names ?
Please suggest.
Your view model doesn't really need a property named dispute. A view model should not reference your domain models.
As far as the mapping is concerned one possibility is to manually do it but that could quickly become cumbersome with more complex models:
public ActionResult Foo()
{
IEnumerable<disputes> disputes = ... fetch from repo
IEnumerable<disputeviewmodel> disputeViewModels = disputes.Select(x => new disputeviewmodel
{
Lastviewedbyname = x.Lastviewedby,
Lastupdatedbyname = x.Lastupdatedby,
LastRespondedByname = x.LastRespondedBy
});
return View(disputeViewModels);
}
So a better approach would be to use AutoMapper:
public ActionResult Foo()
{
IEnumerable<disputes> disputes = ... fetch from repo
IEnumerable<disputeviewmodel> disputeViewModels = Mapper.Map<IEnumerable<disputes>, IEnumerable<disputeviewmodel>>(disputes);
return View(disputeViewModels);
}
Why your Dispute doesn't look like that?
class Dispute
{
public User LastViewedBy;
public User Lastupdatedbyname
public User LastRespondedByname
}
That's how it should look. Then problem solved. When you query for Disputes you already have Users (with there usernames) ready.

Spring MVC Controller

I have a controller class that makes a search on the Student Database and displays its
information. Right now no matter if a particular student is found or not, it displays the same screen.
I am planning to show a different view if backend search doesnt return any data. For this
I coded my controller with if else block (data found: show view, else show different view) but
it doesnt seem to be working. In any case I am seeing the same view returned back. In this sample
student/homePage. What am I doing wrong here?
#Controller
public class StudentController extends BaseClassController
{
#RequestMapping( value = "/student/studentSearch.html", method = RequestMethod.POST )
public String searchStudent( Arguments )
{
if( bundleStudentBean.getRollNum() != null)
{
try
{
//Call Service layer and get the data
//Set into a model
}
catch( ServiceException e )
{
// Some exception occured
}
catch( Exception e )
{
//print error trace
}
//Student Found: Show student homepage
return "student/homePage";
}
//No Student Found: Show splash page
return "student/noDataPage";
}
}
Instead of checking whether the rollNum to null,better check whether it's value is zero. Chances are more that the function returns zero even when youi give no value into it.Most probably in the database you would have set the column to be not null and int
Good practice: Controller methods should be as lightweight as possible.
Bad practice: using Exceptions as control flow.
Spring MVC has a nice way of mapping business exceptions to custom views using ExceptionHandlers. I assume this is only one of the cases where a Controller is looking for a student and finds none - using ExceptionHandlers should help you write readable, lightweight Controllers.

Resources