Reputation: 199
I'm trying to make my controller actions more efficient. Let's say I have two actions, one a ViewResult and the other a PartialViewResult. Both perform the same action at a certain point which is returned in the same viewModel by both actions, let's say my two actions are:
public ViewResult datastream(string dataID)
{
var data = db.data.FirstOrDefault(i -> i.ID == dataID);
var viewModel = new DataViewModel();
viewModel.Data = data.Data;
return view(viewModel)
}
public PartialViewResult datastreampartial(string dataID)
{
var data = db.data.FirstOrDefault(i -> i.ID == dataID);
var viewModel = new DataViewModel();
viewModel.Data = data.Data;
return PartialView("_datapartial", viewModel)
}
I can put the following:
var data = db.data.FirstOrDefault(i -> i.ID == ID)
var viewModel = new DataViewModel();
viewModel.Data = data.Data;
code into another action and then RedirectToAction back to the original actions carrying the viewModel, I could then make those original two actions act in the appropriate way given whether the viewModel was null or not. This seems a bit of a farce though. Presumably there is some way I can easily reference this single chunk of code so it can be used in both actions easily and the viewModel returned by both actions.
What is the best way to do this?
Upvotes: 0
Views: 72
Reputation: 3185
You can create a private method that returns the object being used by both your public methods:
public ViewResult datastream(string dataID)
{
return view(this.GetDataViewModel(dataID));
}
public PartialViewResult datastreampartial(string dataID)
{
return PartialView("_datapartial", this.GetDataViewModel(dataID))
}
private DataViewModel GetDataViewModel(string dataId)
{
var data = db.data.FirstOrDefault(i => i.ID == dataID);
var viewModel = new DataViewModel()
{
Data = data?.Data;
}
return viewModel;
}
Keep in mind that your code might throw an exception as you are trying to access data.Data
without checking if it is a null
value; not a problem in my private method.
Upvotes: 1
Reputation: 6530
Just create a private method on your controller and call that from your actions. There's not reason to call RedirectToAction
private WhateverYouTypeIs GetData(int Id)
{
var data = db.data.FirstOrDefault(i -> i.ID == ID)
var viewModel = new DataViewModel { Data = data.Data);
return viewModel;
}
Then change your methods
public ViewResult datastream(string dataID)
{
return view(GetData(dataID));
}
public PartialViewResult datastreampartial(string dataID)
{
return PartialView("_datapartial", GetData(dataID));
}
Upvotes: 1
Reputation: 727067
Efficiency in terms of CPU cycles does not make much difference here, so you should go for the most readable approach that shares as much code as you can share.
Making a helper method that obtains DataViewModel
based on ID
is a classic approach, available in imperative languages:
private static DataViewModel GetViewModel(string dataID) {
// You can flatten your three lines into one with {} initialization syntax
return new DataViewModel {
Data = db.data.FirstOrDefault(i -> i.ID == dataID)
};
}
Now you can use your method in all your actions with a single line:
return view(GetViewModel(dataID))
...
return PartialView("_datapartial", GetViewModel(dataID))
Upvotes: 1