mvc3, can you give controller a display name? - asp.net-mvc

I am using mvc3. is it possible to give controller and action a display name.
[DisplayName("Facebook Employee")]
public class EmployeeController : Controller
in my breadcrumb, I will get the controller name and action name
#{
var controllerName = ViewContext.RouteData.Values["Controller"];
var actionName = ViewContext.RouteData.Values["Action"];
}
I expect to see "Facebook Employee", but its not working.

You'll have to reflect on the Controller type itself, using GetCustomAttributes. Use ViewContext.Controller to get a reference to the controller itself. Something like this:
string controllerName;
Type type = ViewContext.Controller.GetType();
var atts = type.GetCustomAttributes(typeof(DisplayNameAttribute), false);
if (atts.Length > 0)
controllerName = ((DisplayNameAttribute)atts[0]).DisplayName;
else
controllerName = type.Name; // fallback to the type name of the controller
Edit
To do similar for an action, you need to first reflect on the method, using Type.GetMethodInfo:
string actionName = ViewContext.RouteData.Values["Action"]
MethodInfo method = type.GetMethod(actionName);
var atts = method.GetCustomAttributes(typeof(DisplayNameAttribute), false);
// etc, same as above

public static class HLP
{
public static string DisplayNameController(this WebViewPage wvp)
{
if (wvp.ViewBag.Title != null && (wvp.ViewBag.Title as string).Trim().Length > 0)
return wvp.ViewBag.Title;
ControllerBase Controller = wvp.ViewContext.Controller;
try
{
DisplayNameAttribute[] attr = (DisplayNameAttribute[])Controller.GetType().GetCustomAttributes(typeof(DisplayNameAttribute), false);
string DisplayName = attr[0].DisplayName;
return DisplayName;
}
catch (Exception)
{
return Controller.ToString();
}
}
public static string DisplayNameAction(this WebViewPage wvp)
{
string actionName = wvp.ViewContext.RouteData.Values["Action"].ToString();
try
{
Type type = wvp.ViewContext.Controller.GetType();
MethodInfo method = type.GetMethod(actionName);
DisplayNameAttribute[] attr = (DisplayNameAttribute[])method.GetCustomAttributes(typeof(DisplayNameAttribute), false);
string DisplayName = attr[0].DisplayName;
return DisplayName;
}
catch (Exception)
{
return actionName;
}
}
}
<title>#this.DisplayNameAction()</title>

Related

Display ads on multiple Views by using single controller method in MVC

I want to display different ads on multiple Views from single method. Currently, I have created separate controller method for the ads and then passing page name by using session from each View's controller method. I want to get rid off any code related to ads from each controller method.
Please suggest me way to do this.
Home controller
public ActionResult Index()
{
ClsHomeContent model = new ClsHomeContent();
List<Advertisement> advertList = new List<Advertisement>();
var context = new ApplicationDbContext();
var advert = context.Advertisement.ToList();
var pageName = context.Advertisement.Where(x => x.Page == "Home").Select(y => y.Page).FirstOrDefault();
Session["PageName"] = pageName;
return View(model);
}
HorseTracker Controller
public ActionResult HorseTracker()
{
List<Advertisement> advertList = new List<Advertisement>();
var advert = context.Advertisement.ToList();
var pageName = context.Advertisement.Where(x => x.Page == "HorseTracker").Select(y => y.Page).FirstOrDefault();
Session["PageName"] = pageName;
return View(model);
}
Then using this session value
public ClsAdvertisment advertPosition()
{
List<Advertisement> advertList = new List<Advertisement>();
ClsAdvertisment model = new ClsAdvertisment();
var context = new ApplicationDbContext();
var advert = context.Advertisement.ToList();
foreach (var advertisementData in advert)
{
if (advertisementData.Position == Session["PageName"] + "_Top_Left" || advertisementData.Position == Session["PageName"] + "_Top_Right" || advertisementData.Position == Session["PageName"] + "_Middle" || advertisementData.Position == Session["PageName"] + "_Left")
{
advertList.Add(new Advertisement()
{
AdvertId = advertisementData.AdvertId,
Position = advertisementData.Position,
FilePath = advertisementData.FilePath,
Hemisphere = advertisementData.Hemisphere,
Link = advertisementData.Link,
Title = advertisementData.Title
});
}
}
model.advertisement = advertList;
return model;
}
[ChildActionOnly]
public PartialViewResult Advertisement()
{
var model= advertPosition();
return PartialView("_pAdvertisement", model);
}
Created separate partial view
foreach (var item in Model.advertisement)
{
if (#item.Hemisphere == 1 && item.Position == (string)Session["PageName"]+"_Top_Left")
{
<a href="#item.Link" title="#item.Title" target="_blank">
#Html.Image(item.FilePath, "Image", "", "")
</a>
}
}
You can get the name of the parent controller and action methods in the child method using the ParentActionViewContext property of ControllerContext
[ChildActionOnly]
public PartialViewResult Advertisement()
{
ViewContext context = ControllerContext.ParentActionViewContext;
string controllerName = context.RouteData.Values["controller"].ToString();
string actionName = context.RouteData.Values["action"].ToString();
ClsAdvertisment model = advertPosition(controllerName, actionName);
return PartialView("_pAdvertisement", model);
}
Then modify your advertPosition() to
public ClsAdvertisment advertPosition(string controllerName, string actionName)
and within that method, select the ads to be displayed based on those values, and there is also no need to use Session.

ASP.NET MVC - Check for duplicate in country name without using Model Annotation

I have a ViewModel and Repository that are being used by the Controller Action for Create
Repository
BackendEntities entity = new BackendEntities();
public void AddCountry(CountriesViewModel countryModel)
{
COUNTRIES2 newCountry = new COUNTRIES2()
{
COUNTRY_ID = countryModel.COUNTRY_ID,
COUNTRY_CODE = countryModel.COUNTRY_CODE,
COUNTRY_NAME = countryModel.COUNTRY_NAME,
ACTION_STATUS = countryModel.ACTION_STATUS,
CREATED_BY = countryModel.CREATED_BY,
CREATED_DATE = countryModel.CREATED_DATE
};
entity.COUNTRIES.Add(newCountry);
entity.SaveChanges();
}
Then, I call the Repository from the Controller Action for Create.
Controller
public ActionResult Create(FormCollection collection, CountriesViewModel countries)
{
CountriesRepository countryRepo = new CountriesRepository();
if (ModelState.IsValid)
{
try
{
// TODO: Add update logic here
countryRepo.AddCountry(countries);
//countryRepo.
var notif = new UINotificationViewModel()
{
notif_message = "Record saved successfully",
notif_type = NotificationType.SUCCESS,
};
TempData["notif"] = notif;
return RedirectToAction("Index");
}
catch (Exception e)
{
this.AddNotification("Country cannot be added.<br/> Kindly verify the data.", NotificationType.ERROR);
}
}
return View(countries);
}
Please how do I Validate for duplicate COUNTRY_NAME using the condition, where ACTION_STATUS is not equal to 2
I don't want to do it from Model or View, but in the Controller or Repository.
Probably putting it before countryRepo.AddCountry(countries) in the Controller.
Create a Method In your Country Repository
public bool IsNameExist(string name, int id)
{
var result =entity.COUNTRIES.Any(c => c.COUNTRY_NAME == name && c.ACTION_STATUS != 2 && && c.COUNTRY_ID != id);
return result;
}
Then In your controller
public ActionResult Create(FormCollection collection, CountriesViewModel countries)
{
.......
if (countryRepo.IsNameExist(countries.COUNTRY_NAME, countries.COUNTRY_ID))
{
ModelState.AddModelError("COUNTRY_NAME", "COUNTRY NAME already exist.");
}
........
}

Error based on Remote Validation in mvc

This is my controller code:
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult CheckBuildingName()
{
var isUnique = true;
string _buildingName = Request.Form["buildingName"]; // put your control name here
var connectionstring = ConnectionProvider();
AddBuildingModel model = new AddBuildingModel();
using (var context = new Notifier.AccountDatabase(connectionstring))
{
var objBuilding = (from building in context.Buildings
where building.buildingName == model.buildingName && building.buildingActive == true
select building).FirstOrDefault();
if (objBuilding == null)
{
isUnique = true;
}
else
{
isUnique = false;
}
}
if (isUnique == false)
{
return Json("Building already taken, Pleaes try with different name.", JsonRequestBehavior.AllowGet);
}
else
{
return Json(true, JsonRequestBehavior.AllowGet);
}
}
}
and my model is like below:
[System.ComponentModel.DisplayName("buildingName")]
[Remote("CheckBuildingName", "ConfigLocationController",ErrorMessage = "Building already exists!")]
public string buildingName { get; set; }
I am getting errors on this. The controller path cannot be found out or does not implement IController. What does that mean. Am I missing something ? Or is my code completely wrong. ? Please help
The reason for the error is that your RemoteAttribute is calling the CheckBuildingName method of ConfigLocationControllerController. Assuming that you controller is actually named ConfigLocationController, then you attributes need to be
[Display(Name = "Building Name")] // use this attribute, not DisplayName
[Remote("CheckBuildingName", "ConfigLocation",ErrorMessage = "Building already exists!")]
public string buildingName { get; set; }
However your method also contains errors. You initialize a new instance of a model and then use the value of its buildingName property (which will be null) in your query so it will always return null. In additional, you should add a parameter for the value your ajax call is submitting rather than using Request.Form. You method can be simply
[HttpPost]
public JsonResult CheckBuildingName(string buildingName)
{
bool exists = context.Buildings.Any(x => x.buildingName == buildingName && x.buildingActive);
return Json(!exists, JsonRequestBehavior.AllowGet);
}
which will return true if there is no match, or false if there is, in which case the message you have defined in the attribute will be displayed in the view assuming you have included #Html.ValidationMessageFor(m => m.buildingName)

Issue while calling Controller Method

I have two controllers called FormController and CorticonResponseController.
FormController:
[HttpPost]
public ActionResult Index(FormCollection formCollection)
{
Session["CorticonServiceEndpoint"] = this.CorticonServiceEndpoint;
Session["CorticonServiceName"] = this.CorticonServiceName;
Session["CorticonServiceMajorVersion"] = this.CorticonServiceMajorVersion;
Session["CorticonServiceMinorVersion"] = this.CorticonServiceMinorVersion;
Session["payLoad"] = “Test”;
return RedirectToAction("CorticonIndex ", “CorticonResponseController”);
}
CorticonResponseController:
public ActionResult CorticonIndex()
{
string payLoad = (string)Session["payLoad"];
string CorticonServiceEndpoint = (string)Session["CorticonServiceEndpoint"];
string CorticonServiceName = (string)Session["CorticonServiceName"];
string CorticonServiceMajorVersion = (string)Session["CorticonServiceMajorVersion"];
string CorticonServiceMinorVersion = (string)Session["CorticonServiceMinorVersion"];
var viewModel = this.Model.GetViewModel(payLoad);
return View ("Default", viewModel);
}
Here, I was sending some information from FormController to CorticonResponseController. In CorticonResponseController, I made some calculations and returning the view with the model.
Hence the URL is changing from http://localhost:35583/banking/open-an-account To http://localhost:35583/banking/open-an-account/CorticonIdex.
However, I don’t want to change the URL so I have modified my code as below.
CorticonResponseController:
public void CorticonIndex()
{
string payLoad = (string)Session["payLoad"];
string CorticonServiceEndpoint = (string)Session["CorticonServiceEndpoint"];
string CorticonServiceName = (string)Session["CorticonServiceName"];
string CorticonServiceMajorVersion = (string)Session["CorticonServiceMajorVersion"];
string CorticonServiceMinorVersion = (string)Session["CorticonServiceMinorVersion"];
var viewModel = this.Model.GetViewModel(payLoad);
TempData["ResponseController"] = viewModel;
}
FormController:
[HttpPost]
public ActionResult Index(FormCollection formCollection)
{
Session["CorticonServiceEndpoint"] = this.CorticonServiceEndpoint;
Session["CorticonServiceName"] = this.CorticonServiceName;
Session["CorticonServiceMajorVersion"] = this.CorticonServiceMajorVersion;
Session["CorticonServiceMinorVersion"] = this.CorticonServiceMinorVersion;
Session["payLoad"] = “Test”;
CorticonResponseController obj = new CorticonResponseController();
obj.CorticonIndex();
CorticonResponseModel viewModel = (CorticonResponseModel)TempData["ResponseController"];
string controllerName = DecisionServiceProgram.GetResponseWidgetName();
return View("Default", viewModel);
}
Here,In my FormController, I was calling CorticonResponseController method and getting CorticonResponseModel data using TempData and then returning the view.
I am facing the issues while executing the controller.
Can someone help me how to resolve the issue?

How to get MVC Action parameter from AuthorizationContext?

I am currently trying to write a custom authentication filter and I need to access the dto that is being passed as a parameter to the action in my filter. Lets say I have an action like this
[AuthenticateProfile]
public ActionResult EditProfile(ProfileDTO profileDto)
{
if (ModelState.IsValid)
{
// Do crazy stuff
}
return something....
}
I need to do my authentication based on some of the properties that are inside profiledto object.
I want to know how I can get this object inside my filter from AuthorizationContext.
Here's how I did it:
var parameters = filterContext.ActionDescriptor.GetParameters();
var values = parameters.Select(s => new
{
Name = s.ParameterName,
Value = filterContext.HttpContext.Request[s.ParameterName]
});
Assuming that your logic is happening in OnActionExecuting (meaning before the actual controller action is run), then one way of doing this (as outlined here) would be:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.Controller.ViewData.ModelState.IsValid)
return;
var profileDto = filterContext.ActionParameters.SingleOrDefault(ap => ap.Key == "profileDto").Value;
if (profileDto != null)
{
// do something with profileDto
}
}
ASP.NET Core
var parameters =
filterContext
.ActionDescriptor
.Parameters
.Select(s => new
{
Name = s.Name,
Value = context.HttpContext.Request.Query[s.Name]
});
extension
public static StringValues? Parameter(this AuthorizationFilterContext context, string name)
{
var parameter = context.ActionDescriptor.Parameters.FirstOrDefault(it => it.Name == name);
if (parameter == null) return null;
return context.HttpContext.Request.Query[parameter.Name];
}
use
var parameter = context.Parameter("id");
Here are some examples for you to try out:
public class AuthenticateProfileAttribute : AuthorizeAttribute {
public override void OnAuthorization(AuthorizationContext filterContext) {
// Looping through named parameters
foreach (string name in filterContext.HttpContext.Request.QueryString.AllKeys) {
var value = filterContext.HttpContext.Request.QueryString[name];
// do something with the iteration
Console.WriteLine(name + ": " + value);
}
// Looping through un-named parameters a.k.a route parameters
foreach (KeyValuePair<string, object> parameter in filterContext.RouteData.Values) {
var name = parameter.Key;
var value = parameter.Value;
// do something with the iteration
Console.WriteLine(name + ": " + value);
}
// Get single named parameter
string parameter = filterContext.HttpContext.Request.QueryString["parameter"];
// Get single route parameter
parameter = filterContext.RouteData.Values["parameter"].ToString();
}
}
Using MVC 5.

Resources