I am developing a MVC application.
I want to send a controller for validating purpose to Validation class.
That class will validate the controllers properties and send the result.
I am not gettting, how to get name and properties of the controller after
getting it in class.
Below code is the Controller class code and I send this controller to class named validation class.
[HttpPost]
public ActionResult Create(Location location)
{
if (ModelState.IsValid)
{
Validations v = new Validations();
Boolean ValidProperties = true;
//Sends the controller to Validation class
v.ValidProperty(this);
if (ValidProperties == true)
{
db.Locations.Add(location);
db.SaveChanges();
return RedirectToAction("Index");
}
}
}
And Below code is the class named Validations where I want to validate the controller .
Now I am not getting how to get the name of controller and its properties.
public class Validations
{
string PropertName;
public void ValidProperty(Controller ctr)
{
var name1 = ctr;
string s = ctr. ????????
//How to get Controller Name and its properties ?
}
}
use reflection to get name as:
var name = this.GetType().Name;
Or you can create a custom base controller of your choice, add properties, methods to it and deal with derived controllers as:
public abstract class BaseController : Controller
{
// add other properties as needed
public abstract string Name { get; protected set; }
public virtual void ValidProperty()
{
string s = Name;
//something esle
}
}
public class YourController : BaseController
{
private string _name;
public override string Name
{
get { return _name; }
protected set { _name = "Your_Name"; }
}
[HttpPost]
public ActionResult Create(Location location)
{
if (ModelState.IsValid)
{
bool validProperties = true;
// Deals with a base controller method
ValidProperty();
// or something like this, if you prefer
var controller = (BaseController) this;
Validations v = new Validations();
//Sends the controller to Validation class
v.ValidProperty(controller);
if (validProperties)
{
db.Locations.Add(location);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return Content(string.Empty);
}
}
Related
I have a block of code which is use in pretty much every controller, so I am wondering how, or what's the best practice for reusing code in multiple controllers
Simple example would be this
public String CoolCode(){
// Stuff
return MyStuff;
}
Then in another controller I just use
string something = CoolCode();
Where should I put it, and how to use it in every controller?
Personally I would inject the helper class into the controller:
public interface IHelper
{
string CoolCode();
}
public class Helper : IHelper
{
public string CoolCode()
{
return "Cool code";
}
}
public class SomeController
{
private IHelper _helper;
public SomeController(IHelper helper)
{
_helper = helper;
}
public ActionResult Index()
{
//call _helper.CoolCode();
}
}
Then you would need to inject this using some sort of IoC container, I recommend Castle Windsor
This is all quite abstract but I recommend you read up on it:
http://www.codeproject.com/Articles/560798/ASP-NET-MVC-Controller-Dependency-Injection-for-Be
What you should do is extend the Controller class that all your controllers inherit now and use this abstraction to wrap all of your controllers that use that code:
public class MyControllerBase : Controller
{
public string CoolCode() { ... }
}
now you simply inherit your abstraction rather than the default one:
public class AnyController : MyControllerBase
{
...
}
However depending on what you need precisely different approaches might be more appropriate.
public interface IBaseUserController
{
string SomePropety { get; set; }
ActionResult SignUp(string code, [Form] SomeViewModel model);
}
public class BaseUserController : Controller, IBaseUserController
{
private static string _somePropety = "";
public BaseUserController(){}
public string SomePropety
{
get
{
return _somePropety;
}
set { _somePropety = value; }
}
public virtual ActionResult SignUp(string code, [Form] SomeViewModel model)
{
// ... CoolCode maybe use SomePropety
return View(model);
}
}
public class TestUserController : BaseUserController
{
public TestUserController()
{
SomePropety = "Value";
}
public override ActionResult SignUp(string code, [Form] SomeViewModel model)
{
return base.SignUp(code, model);
}
public ActionResult SignUp2(string code, [Form] SomeViewModel model)
{
return base.SignUp(code, model);
}
}
MVC controller are same as normal class and controller have the same extension .cs
So use can use static method like following.
HomeController objHomeController = new HomeController();
string something= objHomeController.CoolCode();
I need to pass a View Model from one controller to another controller. I used the below statement.
return RedirectToAction("FillNewSession", "Account", new { LoginResult = loginResult });
LoginResult is an object of the model "UserLoginProperties". FillNewSession controller is below.
public ActionResult FillNewSession(UserLoginProperties LoginResult)
{
Session["UserID"] = LoginResult.UserID.ToString();
Session["LoginID"] = LoginResult.LoginID;
Session["UserFullName"] = LoginResult.UserFullName;
Session["UserTypeID"] = LoginResult.UserTypeID;
Session["UserRefNo"] = LoginResult.UserRefNo;
Session["UserNRIC"] = LoginResult.UserNRIC;
return Redirect("~/index.aspx");
}
Problem is when "FillNewSession" controller is executed the passed parameter "LoginResult" is null.
Please Help.
If you want to pass an object through a redirect call you need to send all the properties of the object one by one, as illustrated below. You can't just pass the object as it is.
public class UserLoginProperties
{
public string UserID { get; set; }
public string LoginID { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
var prop = new UserLoginProperties(){ LoginID = "123", UserID = "abc"};
return RedirectToAction("OtherAction", new { UserID=prop.UserID, LoginID=prop.LoginID });
}
public ActionResult OtherAction(UserLoginProperties prop)
{
// do whatever you want with it here
}
}
I am new to mvc and I load ViewBag in a method of controller as,
HomeController: Controller
{
Public ActionResult Index()
{
loadViewBag();
return View();
}
public void loadViewBag()
{
ViewBag.aaa = "something";
}
}
It works fine.
What is my problem is, Now I want to call loadViewBag() method form another controller( say Account) so that I can reuse same method and need to make loadViewBag() method static due to some static variables as:
public static void loadViewBag()
If I make loadViewBag method static, there appear error on ViewBag " An object reference is required for the non-static field, method, or property 'System.Web.Mvc.ControllerBase.ViewBag.get' ".
Is there any solution/suggestion.
Thank You.
Just make it an extension method of ControllerBase e.g.
public static void ControllerExt
{
public static void LoadViewBag(this ControllerBase controller)
{
controller.ViewBag.aaa = "something";
...
}
}
That way you can use it in any controller
public class HomeController : Controller
{
public ActionResult Index()
{
this.LoadViewBag();
return View();
}
}
public class AccountController : Controller
{
public ActionResult Index()
{
this.LoadViewBag();
return View();
}
}
If its only specific to some controllers then it would be more flexible to pass the ViewBag property in e.g.
public static class ControllerHelper
{
public static void LoadViewBag(dynamic viewBag)
{
viewBag.aaa = "something";
}
}
public class HomeController : Controller
{
public ActionResult Index()
{
ControllerHelper.LoadViewBag(ViewBag);
return View();
}
}
ViewBag is a property of your controller (more specifically of ControllerBase), and since a static method has no knowledge of a class instance, you can't access it.
You could pass the controller instance to the method if you want to use a static method or even make it an extension method, but depending on your problem, this solution could be sub-optimal. You may be able to get a better answer if you add more details to your question.
Public ActionResult Index()
{
this.loadViewBag();
return View();
}
public static void loadViewBag(this ControllerBase target)
{
target.ViewBag.aaa = "something";
}
Do you need that to allow different controllers/views to use some common properties?
Then I'd rather recommend a common base controller, while also wrapping ViewBag code into type safe properties (to let the compiler control the data consistency - as you know, ViewBag is not type safe, so any typos and data mismatches won't be noticed until the code gets executed).
1. Introduce a common controller with those wrapper properties
public abstract class MyBaseController : Controller
{
internal long CurrentUserId
{
get { return ViewBag.CurrentUserId; }
set { ViewBag.CurrentUserId = value; }
}
internal Role CurrentUserRole
{
get { return ViewBag.CurrentUserRole; }
set { ViewBag.CurrentUserRole = value; }
}
...
}
Thus, your inherited controllers could simply set the properties - or, with lots of common code just introduce a method in your base controller - similar to what you already have.
2. Introduce a common view class with those wrapper properties
public abstract class MyBaseViewPage<T> : WebViewPage<T>
{
public string Title
{
get { return (string)ViewBag.Title; }
set { ViewBag.Title = value; }
}
public long CurrentUserId
{
get { return (long)ViewBag.CurrentUserId; }
}
public Role CurrentUserRole
{
get { return ViewBag.CurrentUserRole; }
}
}
public abstract class MyBaseViewPage : MyBaseViewPage<dynamic>
{
}
and update web.config to let MVC know you're using a custom base view:
<configuration>
...
<system.web.webPages.razor>
...
<pages pageBaseType="MyRootNamespace.Views.MyBaseViewPage">
...
</pages>
</system.web.webPages.razor>
Now you can use them as normal properties in your controllers and views.
I have an delegate in my controller And I want that to be passed to my views to pass into my settings.
I have tried assigning delegates to ViewData["delegateFunction"]=delegateFunction;
But That too is not valid idea..
I know this is a basic Question. But just learning about delegates.
Thanks in advance,
saravanakumar.
I use the Model class for passing delegates to the View:
Model
public class ExampleModel
{
public Func<string, string> getUIName { get; set; }
}
Method declaration
public string concreteMethod_GetUIName(string text)
{
return text;
}
Controller
public ActionResult Index()
{
ExampleModel model = new ExampleModel { getUIName = concreteMethod_GetUIName };
return View(model);
}
View
#model ExampleModel
#Model.getUIName("sample text")
I am trying to move from webForms to Asp.net-MVC and have some problems. I am trying to figure why this is not working, I am getting this error: "Object reference not set to an instance of an object"
I have the class 'Pages':
namespace _2send.Model
{
public class Pages
{
public string PageContent { get; set; }
public string PageName { get; set; }
public int LanguageId { get; set; }
}
}
I am inserting the value to 'Pages.PageContent' property with this class:
namespace _2send.Model.Services
{
public class PagesService : IPagesService
{
public void GetFooterlinksPage()
{
DB_utilities db_util = new DB_utilities();
SqlDataReader dr;
Pages pages = new Pages();
using (dr = db_util.procSelect("[Pages_GetPageData]"))
{
if (dr.HasRows)
{
dr.Read();
pages.PageContent = (string)dr["PageContent"];
dr.Close();
}
}
}
The Controller method looks like this:
private IPagesService _pagesService;
public FooterLinksPageController(IPagesService pagesService)
{
_pagesService = pagesService;
}
public ActionResult GetFooterLinksPage()
{
_pagesService.GetFooterlinksPage();
return View();
}
I am trying to write the property in the view like this:
#model _2send.Model.Pages
<div>
#Model.PageContent;
</div>
When debugging, the method is fired and the dataReader is inserting the value to the 'PageContent' property, but I am still getting this error from the view.
Thanks!
return View();
You didn't pass a model.
You need to pass the model as a parameter to the View() method.
You need to rewrite service method to return Pages:
public Pages GetFooterlinksPage()
{
DB_utilities db_util = new DB_utilities();
Pages pages = new Pages();
using (var dr = db_util.procSelect("[Pages_GetPageData]"))
{
if (dr.HasRows)
{
dr.Read();
pages.PageContent = (string)dr["PageContent"];
return pages;
// Because you use using, you don't need to close datareader
}
}
}
And then rewrite your action method:
public ActionResult GetFooterLinksPage()
{
var viewmodel = _pagesService.GetFooterlinksPage();
return View(viewmodel);
}
You can return a model:
var viewmodel = new _2send.Model.Pages().
//here you configure your properties
return View(viewmodel);