Sharing methods between multiple controllers C# MVC4 - c#

I have the same method I call in six controllers. Right now I copy and paste between each of the controllers. All the controllers are in the same namespace. The method returns a bool based on the passed id. For example:
public bool CheckSubmission(int id =0)
{
Get Records from DB with criteria
If Record available return true
else return false
}
I have been away from C++ C# for awhile and can't find how to write these once. I know in Rails I can put the shared functions in ApplicationController. I have seen several Questions on SO about this but not a clear example, they are more along the lines read up on OOP. Any help would be appreciated as I get back into this.

Create a ControllerBase class that inherits from Controller, place this method in it.
Have your controllers inherit from your base controller - they will get this implementation to use.
public class ControllerBase : Controller
{
public bool CheckSubmission(int id = 0)
{
Get Records from DB with criteria
If Record available return true
else return false
}
}
public class SomethingController : ControllerBase
{
// Can use CheckSubmission in here
}

Related

Making a generic query / getbyspecification in web api controller?

I have a typical API with some CRUD operations. I typically need to get certain objects, based on different parameters.
One way to do it would be to have methods like:
GetProjectsByCustomerId(int customerId);
GetProjectsBySigneeId(int signeeId);
However, in my service layer (ProjectService in this case) I usually use a method such as the following where ProjectSpecification typically has quite a lot of fields and even lists:
public IEnumerable<Project> GetBySpecification(ProjectSpecification projectSpecification)
That means, in my dream world I would like to have endpoints such as:
/api/projects (empty specification, return full list)
/api/projects?customerid=2 (gets projects for customer with id 2)
/api/projects?signeeid=2,3 (get projects with signee id 2 and 3)
My question is - how is this done
My first attempt was adding this in my ProjectController (calling my ProjectService):
public class ProjectsController : ApiController
{
public IEnumerable<Project> GetProjects(ProjectSpecification projectSpecification)
{
var projects = _projectService.GetBySpecification(projectSpecification);
return projects;
}
}
But lets say I open this URL:
/api/Projects?CustomerId=2
This is not parsed into a ProjectSpecification viewmodel. However, if I change my controller signature to:
public IEnumerable<Project> GetProjects(int customerid) { }
It would work, because it's a simple type.
I could of course build some parameter-hell, but I guess there is something super obvious MVC magic I am missing - probably in the routing? :-)
Referencing documentation
Parameter Binding in ASP.NET Web API : [FromUri]
To force Web API to read a complex type from the URI, add the
[FromUri] attribute to the parameter.
For example assuming
public class ProjectSpecification {
public int CustomerId { get; set; }
//...other properties
}
public class ProjectsController : ApiController {
[HttpGet]
public IHttpActinoResult GetProjects([FromUri]ProjectSpecification projectSpecification) {
return Ok(projectSpecification);
}
}
The client can put the CustomerId value in the query string.
For example:
/api/Projects?CustomerId=2
and Web API will use them to construct a ProjectSpecification with the CustomerId set to 2 .

C# Web API Help Documentation IHttpActionResult

I have a C# Web API and I am trying to get the auto created help documentation to work with IHttpActionResult. I stripped down the example below so its a little easier to read.
For the object, below is a simple example. BusinessObject is just a wrapper. The CollectionBase is CollectionBase : ObservableCollection<T>, ILoadable where T : BusinessObject. Its an older code base that is auto generated but reusing it for this.
public class Value : BusinessObject
{
public int Id { get; set; }
}
public class Values : CollectionBase<Value>
{
public override Value LoadObject(System.Data.IDataRecord record)
{
return new Value();
}
}
For the API side of things. The following works.
public class Values : ApiController
{
public IEnumerable<Value> GetThis()
{
Values values = new Values();
return values;
}
}
The issue comes when I try to do
public IHttpActionResult GetThis()
{
Values values = new Values();
return Ok(values);
}
It doesn't recognize that it should use a different return type. The 'Resource Description' ends up being IHttpActionResult with no sample output. Now I can add
config.SetActualResponseType(typeof(IEnumerable<Value>), "Values", "GetThis");
and it will show a sample output but the 'Resource Description' will still be IHttpActionResult. That is the main issue I am having. I would like to use IHttpActionResult because its very easy to use and can return error codes if needed very easily. I would just like to be able to auto construct the documentation.
UPDATE: Upon some further research, I did fine this post.
Resource Description on Web API Help page is showing "None."
Bascially, you add the response type attribute to the method.
[ResponseType(typeof(IEnumerable<Value>))]
public IHttpActionResult GetThis()
{
Values values = new Values();
return Ok(values);
}
Although this technically works and I have modified my existing code to use this. It would still be nice if there was a way to have it automatically figure it out somehow. Not sure if this is possible or not.
This works for what I am doing. Its a little tedious to have to include every time but it allows me to return error codes if necessary and retain the help documentation functionality.
[ResponseType(typeof(IEnumerable<Value>))]
public IHttpActionResult GetThis()
{
Values values = new Values();
return Ok(values);
}
Resource Description on Web API Help page is showing "None."

Create class to return Session User Information

Hello :) I am building an MVC5/EF6 system that has stores information about students with a number of user types . When the user logs in certain information about the user is stored in Session; UserID, UserTypeID etc. Different users have different privileges, and I often need to get the user information from Session within my ActionResult methods in each controller:
private Student GetCurrentStudentInfo()
{
var currentuser = (SessionModel)Session["LoggedInUser"];
var student = _db.Student.Find(currentuser.UserID);
return student;
}
I have this method at the bottom of my controllers, which I call from each method depending on when I need this information. It gets the userID from the current logged in user and returns the profile information. I would like to be able to either:
Make this method available to all my controllers
Or create a class variable that I can use at the top of my controller, which would return this info:
public class RegistrationWizardController : Controller
{
private readonly DefaultContext _db = new DefaultContext();
private UserInfo _userInfo = new UserInfo();
}
I am very new to MVC and coding in general, so any help/opinions/other suggestions are welcome. Thanks!
You have a couple of options.
The first (and easier) of the two is to make all of your controllers inherit from a common base controller. To do this, make a base controller that extends from the default controller:
public class BaseController : Controller
{
protected Student GetCurrentStudentInfo() //protected so we can access this method from derived classes
{
var currentuser = (SessionModel)Session["LoggedInUser"];
var student = _db.Student.Find(currentuser.UserID);
return student;
}
}
Now, change your controllers to inherit the base controller you just created:
public class RegistrationWizardController : BaseController
{
public ActionResult AnAction()
{
var student = this.GetCurrentStudentInfo(); //calls the method inherited from BaseController
}
}
The other option you have is to use Dependency Injection. This is a bit more complicated, and much more abstract than the previous method. There are a bunch of Dependency Injection frameworks, my favorite is Ninject (http://www.ninject.org/). This would probably be closer to the "Industry Standard" of doing something like this, and I would encourage you to at least look into it, but I think a sample would be a little out of scope for this question (do some side reading first). If you do decide to implement it and get stuck, post another question.

.Net MVC binding dynamic Type to a Model at runtime

I have a slightly long conceptual question I'm wondering if somebody could help me out with.
In MVC I've built a website which builds grids using kendoui's framework.
All the grids on my website are constructed exactly the same except for the model they use and the CRUD methods that need to be implemented for each model. I set things up where each Model implement an interface for CRUD methods like below to get the logic all in one place.
//Actual interface has variables getting passed
public interface IKendoModelInterface
{
void Save();
void Read();
void Delete();
}
public class Model1: IKendoModelInterface
{
[Key]
public int IdProperty1 { get; set; }
public int SomeProperty2 { get; set; }
public string SomeProperty3 { get; set; }
public void Save(){
//Implement Save
}
public void Read(){
//Implement Read
}
public void Delete(){
//Implement Delete
}
}
Then to speed up the writing of all the scaffolding Action methods needed to get the grids to work I created an abstract Controller that can call the interface methods of the Model that gets passed into it.
//Implement the AJAX methods called by the grid
public abstract class KendoGridImplController<T> : Controller where T : class, IKendoModelInterface
{
// Method called from kendo grid
public virtual ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<T> createdRecords)
{
//Invoke Create Method for Model and return results
}
public virtual ActionResult Read([DataSourceRequest]DataSourceRequest request, int Id)
{
//Invoke read method for model and return results
}
//Update and Delete also implemented..
}
Then I just need a Controller per model that implements the abstract controller above passing in the type of Model being used.
public class ResponsibilityMatrixController : KendoGridImplController<Model1>
{
//Set up the page the grid will be on
public ActionResult Index(int id)
{
return View("SharedGridView", id);
}
//Can override abstract methods if needed but usually won't need to
}
I'm wondering if I can take this one step further or if I've reached the end of the road. To me it just seems like more repeated code if I have to create a controller per Model that does nothing but pass in the type to the abstract controller and calls the same View.
I attempted for quite a while yesterday to figure out if I could dynamically assign the type to the abstract controller. I setup something where I was sending back the type of model via strings and I could still invoke the methods needed. Where it failed, was that the mapping could no longer be done on any of the controller actions by default since the type isn't known at compile time. eg
public virtual ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<T> createdRecords)
createdRecords can't be bound like this if T that's passed in is an interface and not the Model itself and I've found no real way to map the form data to an instance of a type that isn't known at compile time.
I'm wondering if there's an easy way to do this mapping between an instance of the type of object getting passed in that I can figure out at runtime, if there's some other way to set this up that I'm overlooking or if both those things are going to be way too much work and I should just not attempt something like this and build a controller per model like I do now?
In case anybody else finds this in the future here's what I've done so far to solve my issue. First I downloaded the impromptu-interface code lib which is incredibly helpful when dealing with dynamic types.
Then for the abstract controller's save methods where it was important that I could bind back to the original object type I did this.
// Method called from kendo grid
public virtual ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<ExpandoObject> createdRecords)
{
Type originalGridType = GetTypeOfModelUsingCustomCodeIDevelopedEarlier();
foreach (ExpandoObject record in createdRecords)
{
var convertedType = Impromptu.InvokeConvert(record, originalGridType);
T objectInstance = Impromptu.ActLike(convertedType);
objectInstance.Save();
}
}
Then I just needed to add a cast in my model that could convert from the ExpandoObject to my model. An extra method that I still wish didn't have to be there but with some helper methods that I wrote it's not a lot more code to make happen.
public static implicit operator Model1(ExpandoObject expando)
{
Model1 model = new Model1();
//Set fields of model...
//....
return model;
}
From here everything works front to back. Maybe there's a better way but this is the best I could come up with so far.

Extending entity framework classes

Even many Q/A on the subject, I didn't find a clear answer for this question:
What's the best design practice for adding business rules (i.e, validations) to entity classes.
I simply want to check some validations before setting the underlying entity value:
public Property
{
get { return base.Property; }
set
{
// Do some validations or other business logic
base.Property = value;
}
}
It doesn't make sense to create a new class from scratch in BLL when all properties are already there in entity class. On the other hand, entity classes need to be extended with business logic rules.
Using interface need extra work, because a change in DAL (entity) would be reflected in both interface and BLL class.
I'm not sure if inheriting from entity class and overriding it's properties and adding extra properties and methods is a good idea or not.
A sample pseudo code in more helpful to me.
Thanks
I would like to elaborate on Stephen Cleary's answer. He is correct in using the partial class/methods to handle business rules in EF. However, he did not go into much detail about what to do within that partial class/method. I created a URL shortening service on my blog to use as an example for this. My ShortURL entity has only two columns/properties. Url and ID.
I wanted to validate that the URL being shortened is a valid URL before it actually stores it in the database through EF. So I created a partial class and method like so:
public partial class ShortURL
{
partial void OnUrlChanging(string url)
{
if (!Regex.IsMatch(url, #"(^((http|ftp|https):\/\/|www\.)[\w\-_]+(\.[\w\-_]+)+([\w\-\.,#?^=%&:/~\+#]*[\w\-\#?^=%&/~\+#])?)"))
throw new Exception("Not a valid URL.");
}
}
This stopped EF from changing the property, leaving it NULL. But that's all it did. It didn't give me an easy way to get at the error message and display it to the user (that I am aware of EDIT: According to http://www.sellsbrothers.com/posts/Details/12700 IDataErrorInfo is the only way to get the error message to display properly in ASP.NET MVC) so I followed another example I found in the dark recesses of the web somewhere and I made my partial class inherit from IDataErrorInfo. I then implemented the interface and included a private dictionary object to store error messages in.
public partial class ShortURL : IDataErrorInfo
{
private Dictionary<string, string> errors = new Dictionary<string, string>();
partial void OnUrlChanging(string url)
{
if (!Regex.IsMatch(url, #"(^((http|ftp|https):\/\/|www\.)[\w\-_]+(\.[\w\-_]+)+([\w\-\.,#?^=%&:/~\+#]*[\w\-\#?^=%&/~\+#])?)"))
errors.Add("Url", "Not a valid URL.");
}
public string Error
{
get { return string.Empty; } //I never use this so I just return empty.
}
public string this[string columnName]
{
get
{
if (errors.ContainsKey(columnName))
return errors[columnName];
return string.Empty; //Return empty if no error in dictionary.
}
}
}
Now, I have a fully-functioning way to store, retrieve, and display error messages. Now back in my controller (in MVC) I am able to do if (!ModelState.IsValid)
[HttpPost]
public ViewResult URLShortener(ShortURL shortURL)
{
if (!ModelState.IsValid)
return View();
shortURL.Url = shortURL.Url.ToLower().StartsWith("www.") ? "http://" + shortURL.Url : shortURL.Url;
shortURLRepository.AddShortURL(shortURL);
object model = "http://www.u413.com/" + ShortCodes.LongToShortCode(shortURL.UrlID);
//Not related to this answer but I had to cast my string as a generic object because the View() method has a (string, string) constructor that does something totally different. My view actually uses string as the model. I know I know, I could have just used ViewBag.
return View("ShowUrl", model);
}
There ya go. A working example of how to not only extend EF's partial methods, but also how to propagate the validation back to the UI. Let me know if anything needs improving or if there was something I missed.
Check out your EF designer-generated code.
Each property Property is actually implemented like this:
public global::System.String Property
{
get
{
return _Property;
}
set
{
OnPropertyChanging(value);
ReportPropertyChanging("Property");
_Property = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("Property");
OnPropertyChanged();
}
}
private global::System.String _Property;
partial void OnPropertyChanging(global::System.String value);
partial void OnPropertyChanged();
The partial method On-Property-Changing is where you can do single-property validation or business logic.
Xaqron, the best way I have found it to use Partial Classes, for example, if you have a class in your EF called PropertyListing you can use a partial class like this:
Partial Public Class PropertyListing
Inherits EntityObject
'Do something here
End Class
You can now extend the class as little or as much as you want without much fuss. The example is in VB but you get the jist of it

Categories