I want to create Html helper that will display inner content only if user in role,
Something like this:
#using(Html.AdminBlock()) {
}
And the code in the block will shown only if user in role...
How I can done it?
If you didn't understand what I mean here example, I want that those 2 codes will return equal result:
#if(Html.IsUserInRole("Admin")) {
<span>hey</span>
}
.
#using(Htm.RoleBlock()) {
<span>hey</span>
}
What you are trying to do is not possible with an HTML helper that is returning IDisposable. The reason for that is because its body will always be rendered. You cannot conditionally exclude the body from being rendered in such a statement:
#using(Htm.RoleBlock()) {
<span>hey</span>
}
Besides, the following looks readable enough:
#if(Html.IsUserInRole("Admin")) {
<span>hey</span>
}
or you could write a helper that will return a boolean value and could be used like that:
#if(Html.IsAdmin()) {
<span>hey</span>
}
Update 2
So you want to keep as much logic out of the view as possible, in this case you can just pull the if conditions out of the view and into a HtmlHelper extension method.
public static class HtmlHelperExtensions
{
public static bool IsAdmin(this HtmlHelper htmlHelper)
{
return htmlHelper.ViewContext.HttpContext.Current.User.IsInRole("admin");
}
}
Usage:
#if (Html.IsAdmin()) {
...
}
Update
If what you want to only output something if a user is in a role this sort of helper is completely overkill. You should go for a simple if statement in your view.
#if (HttpContext.Current.User.IsInRole("admin")) {
...
}
Making a custom helper
I posted a blog post about this very topic last year where I opened up the ASP.NET MVC source to see how BeginForm() was put together and made my own. Here are the highlights, this will allow you to wrap a <div> around a block in an MVC view.
public class MvcDiv : IDisposable
{
private bool _disposed;
private readonly FormContext _originalFormContext;
private readonly ViewContext _viewContext;
private readonly TextWriter _writer;
public MvcDiv(ViewContext viewContext)
{
if (viewContext == null)
{
throw new ArgumentNullException("viewContext");
}
_viewContext = viewContext;
_writer = viewContext.Writer;
_originalFormContext = viewContext.FormContext;
viewContext.FormContext = new FormContext();
Begin();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Begin()
{
_writer.Write("<div>");
}
private void End()
{
_writer.Write("</div>");
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
_disposed = true;
End();
if (_viewContext != null)
{
_viewContext.OutputClientValidation();
_viewContext.FormContext = _originalFormContext;
}
}
}
public void EndForm()
{
Dispose(true);
}
}
Then put this extension method somewhere:
public static class HtmlHelperExtensions
{
public static MvcDiv BeginDiv(this HtmlHelper htmlHelper)
{
return new MvcDiv(htmlHelper.ViewContext);
}
}
Then you can use it like so:
#using (Html.BeginDiv())
{
...
}
Related
Hey I have two classes
class Main
{
public exLog exLog;
public Main()
{
}
}
and
class exLog
{
public exLog()
{
}
public exLog(String where)
{
}
public exLog(String where, String message)
{
}
}
i tried to call exLog direct without giving exLog a parameter. So I can call any class with the Main Method.
How should I do that?
public String ReadFileString(String fileType, String fileSaveLocation)
{
try
{
return "";
}
catch (Exception)
{
newMain.exLog("", "");
return null;
}
}
I like to call them like a funtion in Main
You can call it as soon as you instantiate it.
public Main()
{
exLog = new exLog();
exLog.MethodInClass();
}
Also, if you are not in the same assembly you'll need to make exLog public.
Finally, this is C# and the style dictates that class names should be PascalCased. It's a good habit to form.
Methinks you want something like Adapter Pattern
class Main
{
private exLog exLog;
public Main()
{
}
public void ExLog()
{
exLog = new exLog();
}
public void ExLog(String where)
{
exLog = new exLog(where);
}
public void ExLog(String where, String message)
{
exLog = new exLog(where, message);
}
}
I think you're confused about classes, instances, constructors, and methods. This does not work:
newMain.exLog("", "");
because exLog in this case is a property, not a method. (It's confusing because you use the same name for the class and the property, which is why most conventions discourage that).
You can call a method on the instance:
newMain.exLog.Log("", "");
but then you'll need to change the names of the methods (and add a return type) in your exLog class so they don't get interpreted as constructors:
class exLog
{
public void Log()
{
}
public void Log(String where)
{
}
public void Log(String where, String message)
{
}
}
class Main
{
public exLog exLog;
public Main()
{
exLog = new exLog();
exLog.ReadFileString("", "");
}
}
I am trying to implement the Ninject.Extensions.Factory pattern and my program is telling me my bindings aren't right, but I can't figure out why. I keep getting an "Error activating IHashable. No matching bindings are available, and the type is not self-bindable" exception thrown. The relevant areas of my code are below:
public interface IHashable
{
FileInfo File { get; }
string ComputeHash();
}
public interface IHashableFactory
{
IHashable GetNew(FileInfo file);
}
public class MD5ChecksumProvider : IHashable
{
private FileInfo _file;
public FileInfo File
{
get { return _file; }
}
public MD5ChecksumProvider(FileInfo file)
{
if (file == null)
throw new ArgumentNullException("file");
_file = file;
}
public string ComputeHash()
{
// implementation
}
}
public class AppFileProvider : IAppFileProvider
{
private IHashableFactory _hashFactory;
public IHashableFactory HashProvider
{
get { return _hashFactory; }
}
public AppFileProvider(IHashableFactory hashProviderFactory)
{
_hashFactory = hashProviderFactory;
}
public string GetChecksum(FileInfo fileInfo)
{
var hasher = _hashFactory.GetNew(fileInfo);
return hasher.ComputeHash();
}
}
public class BindingProviders : NinjectModule
{
public override void Load()
{
Bind<IHashable>()
.To<MD5ChecksumProvider>();
}
}
public class BindingFactories : NinjectModule
{
public override void Load()
{
Bind<IHashableFactory>()
.ToFactory();
}
}
// my DI container
public sealed class Container : IDisposable
{
private bool _isDisposed;
private IKernel _kernel;
private BindingFactories _bindingFactories;
private BindingObjects _bindingObjects;
private BindingProviders _bindingProviders;
public Container()
{
_isDisposed = false;
_bindingFactories = new BindingFactories();
_bindingObjects = new BindingObjects();
_bindingProviders = new BindingProviders();
_kernel = new StandardKernel(_bindingObjects, _bindingProviders, _bindingFactories);
}
public T Get<T>()
{
return _kernel.Get<T>();
}
public void Dispose()
{
// nothing worth seeing
}
private void Dispose(bool disposing)
{
// nothing worth seeing
}
}
// the program (composition root)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
using (var container = new Container())
{
var fileProvider = container.Get<IAppFileProvider>();
foreach (var file in files)
{
string hash = fileProvider.GetChecksum(storePath, file); // this line throws "Error activating IHashable. No matching bindings are available, and the type is not self-bindable.""
}
}
}
}
I feel like my bindings are setup correctly but I must be missing something obvious. Any ideas why I'm getting the exception from the above code?
This is caused by a feature of Ninject.Extensions.Factory.
It treats methods which start with Get differently from those which don't.
If you rename IHashableFactory.GetNew to Create or Make everything works fine.
The "Get" feature is described here:
The default instace provider of the extension has the convention that it tries to return an instance using a named binding whenever a method starts with “Get”. E.g. IFoo GetMySpecialFoo() is equal to
resolutionRoot.Get<IFoo>("MySpecialFoo");
Since i think this is not obvious to the user and the exception isn't helpful at all in this regard, i have filed an issue report here
Is there any way to inject a parameter to constructor, which that parameter is currently created in Initialize method on basecontroller?
sample code:
public class SSBaseController : Controller
{
protected UserProfileClass UserProfile;
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
UserProfile = UserProfileGetter.getProfileFromDB();
}
}
public class SSController:SSBaseController
{
private IProcessService processService;
public SSController(IProcessService _processService)
{
processService = _processService;
}
}
public interface IProcessService
{
void doStuff();
}
public class ProcessService1 : IProcessService
{
private UserProfileClass upc;
private string _name;
public ProcessService1(UserProfileClass _profileClass)
{
upc = _profileClass;
}
public void doStuff()
{
_name = upc.name;
upc.name = "xxx";
}
}
public class UserProfileGetter
{
public static UserProfileClass getProfileFromDB()
{
return null;
}
}
public class UserProfileClass
{
public string name;
}
Also i want to get rid of initialize, is this possible?
how to register ProcessService with that parameter without being null in SSController?
It is possible to integrate ASP.NET MVC and Autofaq. The only two things you have to do then is to register interface implementation and specify the Controller's constructor params. Framework will do all the rest.
See https://code.google.com/p/autofac/wiki/MvcIntegration
Here is one more article: http://blogs.msdn.com/b/roncain/archive/2012/07/16/dependency-injection-with-asp-net-web-api-and-autofac.aspx
How to avoid a pair of repetitive lines before and after invocations in sample below ?
Details: This is compileable mock of what is real larger code. Generally it is a layer of proxy classes containing service clients with variety of APIs. The repetitive part is pre- and post- invocation for every method of every client. Unfortunately there is no single signature for all possible methods, the pre- and post- parts need a pointer to client's channel and context.
Is it possible to apply something advanced like AOP, Generics, Delegates, Attributes etc. ? Thank you
using System;
namespace ConsoleApplication
{
class ClassServiceClient: IDisposable
{
public Object channel()
{
return "something";
}
public Object context()
{
return "something other";
}
}
class ClassA : ClassServiceClient
{
public Object methodA()
{
return "something other";
}
}
class ClassB : ClassServiceClient
{
public void methodB(string param)
{
return;
}
}
class ClassAProxy
{
public Object methodA()
{
using (ClassA client = new ClassA())
{
Program.preparation(client.channel()); //<---- repetitive part
Object result = client.methodA();
Program.postinvocation(client.context());//<---- repetitive part
return result;
}
}
}
class ClassBProxy
{
public void methodB(string param)
{
using (ClassB client = new ClassB())
{
Program.preparation(client.channel()); //<---- repetitive part
client.methodB(param);
Program.postinvocation(client.context());//<---- repetitive part
return;
}
}
}
class Program
{
public static void preparation(Object channel)
{
// Do something with channel
}
public static void postinvocation(Object context)
{
// Do something with context
}
static void Main(string[] args)
{
}
}
}
If you can use a common base class, you can easily use a public sealed method that does the invocation and a protected abstract method that does the logic, e.g.
class ProxyBase{
public void Method(params object[] args){
PreConditions();
Invoke(args);
PostConditions();
}
protected abstract void Invoke(object[] args);
}
class ClassAProxy{
protected override void Invoke(object[] args){
client.Method(args[0]);
}
}
You can achieve similar results functionally by declaring a InvocationHandler in your Program class that takes an action:
class Program{
public static void Invoke(object[] args, Action action){
PreConditions();
action();
PostConditions();
}
}
class ClassAProxy{
public void MethodA(int i){
Program.Invoke(() => client.Something(i));
}
}
I'm trying to secure my MVC routes from a set of users that meet a set of criteria. Since MVC seems to use attributes quite a bit and Steven Sanderson uses one for security extensibility in his pro MVC book I started heading down this route, but I'd like to define the rule contextually based on the action I am applying it to.
Some actions are for employees only, some aren't.
Some actions are for company1 only, some aren't.
So I was thinking this type of usage...
[DisableAccess(BlockUsersWhere = u => u.Company != "Acme")]
public ActionResult AcmeOnlyAction()
{
...
}
[DisableAccess(BlockUsersWhere = u => u.IsEmployee == false)]
public ActionResult EmployeeOnlyAction()
{
...
}
Looks pretty clean to me and is really pretty easy to implement, but I get the following compiler error:
'BlockUsersWhere' is not a valid named attribute argument because it is not a valid attribute parameter type
Apparently you can not use a Func as an attribute argument. Any other suggestions to get around this issue or something else that provides the simple usage we've come to love in our MVC projects?
Necros' suggestion would work, however you would have to invoke his SecurityGuard helper in the body of every action method.
If you would still like to go with the declarative attribute-based approach (which has the advantage that you can apply the attribute to the whole Controller) you could write your own AuthorizeAttribute
public class CustomAuthorizeAttribute : AuthorizeAttribute {
public bool EmployeeOnly { get; set; }
private string _company;
public string Company {
get { return _company; }
set { _company = value; }
}
protected override bool AuthorizeCore(HttpContextBase httpContext) {
return base.AuthorizeCore(httpContext) && MyAuthorizationCheck(httpContext);
}
private bool MyAuthorizationCheck(HttpContextBase httpContext) {
IPrincipal user = httpContext.User;
if (EmployeeOnly && !VerifyUserIsEmployee(user)) {
return false;
}
if (!String.IsNullOrEmpty(Company) && !VerifyUserIsInCompany(user)) {
return false;
}
return true;
}
private bool VerifyUserIsInCompany(IPrincipal user) {
// your check here
}
private bool VerifyUserIsEmployee(IPrincipal user) {
// your check here
}
}
Then you would use it as follows
[CustomAuthorize(Company = "Acme")]
public ActionResult AcmeOnlyAction()
{
...
}
[CustomAuthorize(EmployeeOnly = true)]
public ActionResult EmployeeOnlyAction()
{
...
}
Since you can only use constants, types or array initializers in attribute parameters, they probably won't do, or at least the won't be as flexible.
Alternatively, you could use something similar I came up with when solving this problem.
This is the API:
public static class SecurityGuard
{
private const string ExceptionText = "Permission denied.";
public static bool Require(Action<ISecurityExpression> action)
{
var expression = new SecurityExpressionBuilder();
action.Invoke(expression);
return expression.Eval();
}
public static bool RequireOne(Action<ISecurityExpression> action)
{
var expression = new SecurityExpressionBuilder();
action.Invoke(expression);
return expression.EvalAny();
}
public static void ExcpetionIf(Action<ISecurityExpression> action)
{
var expression = new SecurityExpressionBuilder();
action.Invoke(expression);
if(expression.Eval())
{
throw new SecurityException(ExceptionText);
}
}
}
public interface ISecurityExpression
{
ISecurityExpression UserWorksForCompany(string company);
ISecurityExpression IsTrue(bool expression);
}
Then create an expression builder:
public class SecurityExpressionBuilder : ISecurityExpression
{
private readonly List<SecurityExpression> _expressions;
public SecurityExpressionBuilder()
{
_expressions = new List<SecurityExpression>();
}
public ISecurityExpression UserWorksForCompany(string company)
{
var expression = new CompanySecurityExpression(company);
_expressions.Add(expression);
return this;
}
public ISecurityExpression IsTrue(bool expr)
{
var expression = new BooleanSecurityExpression(expr);
_expressions.Add(expression);
return this;
}
public bool Eval()
{
return _expressions.All(e => e.Eval());
}
public bool EvalAny()
{
return _expressions.Any(e => e.Eval());
}
}
Implement the security expressions:
internal abstract class SecurityExpression
{
public abstract bool Eval();
}
internal class BooleanSecurityExpression : SecurityExpression
{
private readonly bool _result;
public BooleanSecurityExpression(bool expression)
{
_result = expression;
}
public override bool Eval()
{
return _result;
}
}
internal class CompanySecurityExpression : SecurityExpression
{
private readonly string _company;
public CompanySecurityExpression(string company)
{
_company = company;
}
public override bool Eval()
{
return (WhereverYouGetUser).Company == company;
}
}
You can add as many custom expressions as you need. The infrastructure is a bit complicated, but then usage is really simple:
public ActionResult AcmeOnlyAction()
{
SecurityGuard.ExceptionIf(s => s.UserWorksForCompany("Acme"));
}
You can also chain the expression, and use it as a condition in view fro example (using SecurityGuard.Require()).
Sry for long post, hope this helps.