How to assign roles from helper class,MVC5 - c#

I am doing something like in action(Get),
[Authorize(Roles = SmartRoles.smclientadmin,SmartRoles.smclientbranchadmin)]
public ActionResult Index()
{
return View();
}
And Helper Class
public class SmartRoles
{
public static string smclientadmin
{ get { return smclientadmin; }
set { smclientadmin = "SMClientAdmin"; } }
public static string smclientbranchadmin
{ get { return smclientbranchadmin; }
set { smclientbranchadmin = "SMClientBranchAdmin"; } }
public static string smclientoperator
{ get { return smclientoperator; }
set { smclientoperator = "SMClientOperator"; } }
}
Error its giving is "name attribute argument expected".... Is there a
right way to use this method?? If so please help...thanks for your
time...

You creating an infinite loop (the getter is calling itself). Change the getter to return a value (no setter is required)
public static string smclientadmin
{
get { return "SMClientAdmin"; }
}

The property accesors would end up in a recursive call. Also, the attribute arguments must be constant expression. Change your code to as below:
[Authorize(Roles = SmartRoles.smclientadmin)]
public ActionResult Index()
{
return View();
}
public class SmartRoles
{
public const string smclientadmin = "SMClientAdmin";
public const string smclientbranchadmin = "SMClientBranchAdmin";
}

Related

Get parameter custom mapping

I want to write many GET handlers that receive an ID for an object,
site.com/controller/Action1/1234
site.com/controller/Action2/1234
site.com/controller/Action3/1234
I would like to write the code that fetches the complex object from the DB just once:
class ComplexObject
{
public string str1 { get; set; }
public string str2 { get; set; }
}
ComplexObject GetFromId(string id)
{
ComplexObject x = Database.GetById(id);
if (x == null)
{
return Http404();
}
return x;
}
and then just use the object directly:
[Route("/[controller]/[action]/{message}")]
[HttpGet]
public string Action1(ComplexObject message)
{
return message.str1;
}
[Route("/[controller]/[action]/{message}")]
[HttpGet]
public string Action2(ComplexObject message)
{
return message.str1;
}
[Route("/[controller]/[action]/{message}")]
[HttpGet]
public string Action3(ComplexObject message)
{
return message.str1;
}
And that all of my handlers will just get the object, and won't have to check whether the ID is correct, etc.
How is that possible?
The official Microsoft Docs describe exactly how you can bind route parameters to a complex object from a database using a custom model binder.
Here's their example model binder:
public class AuthorEntityBinder : IModelBinder
{
private readonly AuthorContext _context;
public AuthorEntityBinder(AuthorContext context)
{
_context = context;
}
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var modelName = bindingContext.ModelName;
// Try to fetch the value of the argument by name
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
var value = valueProviderResult.FirstValue;
// Check if the argument value is null or empty
if (string.IsNullOrEmpty(value))
{
return Task.CompletedTask;
}
if (!int.TryParse(value, out var id))
{
// Non-integer arguments result in model state errors
bindingContext.ModelState.TryAddModelError(
modelName, "Author Id must be an integer.");
return Task.CompletedTask;
}
// Model will be null if not found, including for
// out of range id values (0, -3, etc.)
var model = _context.Authors.Find(id);
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
And then there are various ways to use this new model binder. One is to add an attribute on the model itself:
[ModelBinder(BinderType = typeof(AuthorEntityBinder))]
public class Author
{
// snip
}
Another is to use an attribute on the action parameters:
[HttpGet("{id}")]
public IActionResult GetById([ModelBinder(Name = "id")] Author author)
{
// snip
}
I am not sure why one would want to do what you are proposing, but it unnecessarily overcomplicates things and causes dependencies on the model binder.
Here is how I would implement this:
Have a class that manages your complex object and hide it behind an interface, the inject it into the controller:
public interface IComplexObjectManager
{
ComplexObject GetFromId(string id);
}
public class ComplexObjectManager : IComplexObjectManager
{
private readonly Database _database;
public ComplexObjectManager(Database database)
{
_database = database;
}
public ComplexObject GetFromId(string id)
{
ComplexObject x = _database.GetById(id);
return x;
}
}
[ApiController]
public class ComplexObjectController
{
public ComplexObjectController(IComplexObjectManager complexObjectManager)
{
ObjectManager = complexObjectManager;
}
public IComplexObjectManager ObjectManager { get; }
}
Then consume it in your method, changing the return type to an action result:
[Route("/[controller]/[action]/{id}")]
[HttpGet]
public IActionResult Action1(string id)
{
var obj = ObjectManager.GetFromId(id);
if(obj != null)
return Ok(obj.str1);
else
return NotFound();
}
Make sure to handle the response accordingly.
This approach decouples things (further abstraction can be added for Database), and allows for injection and unit testing.
Please check the code for consistency. I wrote this in a hurry.
I'm not doing the exactly thing that you are asking but i think it can help you. First of all, i'm using BaseController for it because you can filter your all actions before they are getting executed.
public class BaseController : Controller
{
#region /*IoC*/
public BaseViewModel baseViewModel;
public IUnitOfWork<Product> unitOfWorkProductForCart;
#endregion
#region /*ctor*/
public BaseController(IUnitOfWork<Product> unitOfWorkProductForCart)
{
this.unitOfWorkProduct = unitOfWorkProduct;
}
#endregion
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string controllerName = filterContext.ActionDescriptor.RouteValues["controller"];
string actionName = filterContext.ActionDescriptor.RouteValues["action"];
if (actionName == "ProductDetails")
{
var urlParameters = filterContext.ActionArguments;
if (urlParameters.Count != 0)
{
var isThatSlug = urlParameters.ElementAt(0).Key;
if (isThatSlug == "slug")
{
var slugCondition = urlParameters.ElementAt(0).Value;
var isThatProductExist = unitOfWorkProduct.RepositoryProduct.GetProductBySlugForChecking(slugCondition.ToString());
if (isThatProductExist.Count == 0)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{"controller","Account"},
{"action","NotFound"}
});
}
}
}
}
}
}
in that example, i'm controlling the parameters. if it's something like i don't want, it's redirects you to the NotFound page.
i hope it can give you a idea

Can we create a global variable whose value can be accessed in any where in the application?

I have a class library project, I want to create a variable and assign a value to it through MethodA() whose value can be access through MethodB().
Just like we have a session in ASP.NET.
I cannot pass as a parameter to MethodB() because MethodB() is being used in many places and if I change it, all the other methods will get affected.
Public Void MethodA()
{
string value ="Hello";
}
public Void MethodB()
{
-- I want to read the value which is set in MethodA()
}
I need to dispose the value as well after reading it in MethodB().
Both of these methods are in different classes inside the same project.
First try to create a property with a private setter:
public class A
{
public string Value { get { return MethodA(); } }
public string MethodA()
{
return "Hello";
}
public void MethodB()
{
var value = Value;
}
}
If you have two classes:
public class A
{
public string FooMethod()
{
return string.Empty;
}
}
public class B
{
public string BarMethod()
{
var result = new A().FooMethod();
return result;
}
}
You can get idea to handle your exception
public class test
{
public static int value = 0; //Global variable
public void MethodA()
{
//you can assign here as well
value++;
}
}
public class HomeController : Controller
{
test t = new test();
public IActionResult Index()
{
t.MethodA();
int d = test.value;
//you can assign here as well
test.value = 100;
int dd = test.value;
return View();
}
}

calling a property from method

can I call my property TaskAll from the method Task
My code is
private ObservableCollection<TaskExecutionHistoryModel> _TaskAll;
public ObservableCollection<TaskExecutionHistoryModel> TaskAll
{
get{ return _TaskAll;}
set
{
_TaskAll = value;
base.NotifyPropertyChanged(x => x.TaskAll);
}
}
public Task(ObservableCollection<TaskExecutionHistoryModel> ExecutionHistory)
{
}
Yes.
public Task(ObservableCollection<TaskExecutionHistoryModel> ExecutionHistory)
{
ObservationCollection<TaskExecutionHistoryModel> model = TaskAll;
}
Yes you can by simply calling it:
public Task(ObservableCollection<TaskExecutionHistoryModel> ExecutionHistory)
{
TaskAll = someValue;
someOtherValue = TaskAll;
}

Common functions and helpers ASP.NET MVC

I don't get something, and if somebody can clarify:
I need to access this function / helper from here and there:
namespace Laf.Helpers
{
public class Common
{
public string TimeSpanToString(TimeSpan val)
{
return val.ToString(#"hh\:mm");
}
}
}
And in my controller I access it by:
var tmp = new Common();
string str = tmp.TimeSpanToString(tp.DepartureTime);
transferPoint.Add(
new ListTransferPointVM { PortName = tp.PortName, DepartureTime = str }
str);
And the question is how can I achieve and not have duplicate in every controller:
DepartureTime = TimeSpanToString(tp.DepartureTime)
Possible Answer
I just found a way that compiler is not frowning on:
public class TransferController : Controller
{
private Common common = new Common();
public ActionResult Index ()
{
...
and later, when I need it:
string time = common.TimeSpanToString((TimeSpan)variable);
You could make your method string TimeSpanToString(TimeSpan) a static method. This way you can access it without having to make a Common object. Your code will look as follows:
namespace Laf.Helpers
{
public class Common
{
public static string TimeSpanToString(TimeSpan val)
{
return val.ToString(#"hh\:mm");
}
}
}
And your Controller:
transferPoint.Add(
new ListTransferPointVM {
PortName = tp.PortName,
DepartureTime = Common.TimeSpanToString(tp.DepartureTime) }
Common.TimeSpanToString(tp.DepartureTime));
EDIT: As suggested by Michael Petrotta an extension method would be better. An implementation could be:
namespace LaF.ExtensionMethods
{
public static class MyExtensions
{
public static string TimeSpanToString(this TimeSpan ts)
{
return ts.ToString(#"hh\:mm");
}
}
}
You can now call the method like:
tp.DepartureTime.TimeSpanToString();
More on Extension Methods in C#

Encapsulating Action<T> and Func<T>?

I'm trying to make a design for some sort of IExecutable interface. I will not get into details, but the point is that I have several Actions that need to be executed from a base class. They may take different parameters (no big deal), and they may/may not return a value.
So far, this is my design:
public abstract class ActionBase
{
// ... snip ...
}
public abstract class ActionWithResultBase<T>: ActionBase
{
public abstract T Execute();
}
public abstract class ActionWithoutResultBase: ActionBase
{
public abstract void Execute();
}
So far, each of my concrete actions need to be a child from either ActionWithResultBase or ActionWithoutResult base, but I really don't like that. If I could move the definition of Execute to ActionBase, considering that the concrete class may or may not return a value, I will have achieved my goal.
Someone told me this could be done with using Func and Action, for which I totally agree, but I can't find a way to have that into one single class so that the caller would know if the action is going to return a value or not.
Brief: I want to do something like:
// Action1.Execute() returns something.
var a = new Action1();
var result = a.Execute();
// Action2.Execute() returns nothing.
var b = new Action2();
b.Execute();
If you want a lightweight solution, then the easiest option would be to write two concrete classes. One will contain a property of type Action and the other a property of type Func<T>:
public class ActionWithResult<T> : ActionBase {
public Func<T> Action { get; set; }
}
public class ActionWithoutResult : ActionBase {
public Action Action { get; set; }
}
Then you can construct the two types like this:
var a1 = new ActionWithResult<int> {
CanExecute = true,
Action = () => {
Console.WriteLine("hello!");
return 10;
}
}
If you don't want to make Action property read/write, then you could pass the action delegate as an argument to the constructor and make the property readonly.
The fact that C# needs two different delegates to represent functions and actions is quite annoying. One workaround that people use is to define a type Unit that represents "no return value" and use it instead of void. Then your type would be just Func<T> and you could use Func<Unit> instead of Action. The Unit type could look like this:
public class Unit {
public static Unit Value { get { return null; } }
}
To create a Func<Unit> value, you'll write:
Func<Unit> f = () => { /* ... */ return Unit.Value; }
The following interfaces should do the trick -- it's essentially copying the Nullable pattern
public interface IActionBase
{
bool HasResult { get; }
void Execute() { }
object Result { get; }
}
public interface IActionBase<T> : IActionBase
{
new T Result { get; }
}
public sealed class ActionWithReturnValue<T> : IActionBase<T>
{
public ActionWithReturnValue(Func<T> action) { _action = action; }
private Func<T> _action;
public bool HasResult { get; private set; }
object IActionBase.Result { get { return this.Result; } }
public T Result { get; private set; }
public void Execute()
{
HasResult = false;
Result = default(T);
try
{
Result = _action();
HasResult = true;
}
catch
{
HasResult = false;
Result = default(T);
}
}
}
public sealed class ActionWithoutReturnValue : IActionBase
{
public bool HasResult { get { return false; } }
object IActionBase.Result { get { return null; } }
public void Execute() { //... }
}
You know that you can ignore the return value of a method right? You don't have to use it.
what about something simple:
public class ActionExecuter
{
private MulticastDelegate del;
public ActionExecuter(MulticastDelegate del)
{
this.del = del;
}
public object Execute(params object[] p)
{
return del.DynamicInvoke(p);
}
}

Categories

Resources