Now i use to override extensions like :
public abstract class MyWebViewPage<T> : WebViewPage<T>
{
public new MyHtmlHelper<T> Html { get; set; }
public override void InitHelpers()
{
Ajax = new AjaxHelper<T>(ViewContext, this);
Url = new UrlHelper(ViewContext.RequestContext);
Html = new MyHtmlHelper<T>(ViewContext, this);
}
}
public class MyHtmlHelper<T> : HtmlHelper<T>
{
public MyHtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) :
base(viewContext, viewDataContainer)
{
}
public MvcHtmlString ActionLink(string linkText, string actionName)
{
return ActionLink(linkText, actionName, null, new RouteValueDictionary(), new RouteValueDictionary());
}
}
How to add Url.Action helper here with all overloaded version?
UPD: I should override all standard method because many peoples work on this and i they should use standard helpers but with my functionality
You don't need to override neither the Url.Action helper nor the HtmlHelper actions. You can create Extension Methods instead. Here's an example:
public static class MyHelpers
{
public static string MyAction(this UrlHelper url, string actionName)
{
// return whatever you want (here's an example)...
return url.Action(actionName, new RouteValueDictionary());
}
}
Then, you can use the method in your views like this:
#Url.MyAction("MyActionName")
UPDATE:
I wouldn't recommend overriding the Url.Action method. Creating extension methods is much easier and cleaner. But, here's how you can do it:
public class MyUrlHelper : UrlHelper
{
public override string Action(string actionName)
{
return base.Action(actionName, new RouteValueDictionary());
}
}
Related
I have just begun exploring the design patterns and implementation of Web APIs.
I have a scenario where one single API requests to a set of APIs in sequence based on a string value.
Eg: let's say I have an API called StartAPI.
This might send request to a subset of APIs (let's call it API_X, API_Y, API_Z, API_T, API_U) based on given string.
Let's assume the below:
If i pass "string1" or "string2" to StartAPI then it should call API_X, API_Z.
If i pass "string3" it calls API_X, API_Z, API_T.
If i pass "string4" it calls all APIs
API_X, API_Z, API_T, API_Y, API_U.
What design pattern can I follow in this case to minimise the if else conditions?
It looks like that Chain of Responsibity pattern is way to go. As wiki says:
the chain-of-responsibility pattern is a behavioral design pattern
consisting of a source of command objects and a series of processing
objects.1 Each processing object contains logic that defines the
types of command objects that it can handle; the rest are passed to
the next processing object in the chain. A mechanism also exists for
adding new processing objects to the end of this chain.
So let me show an example how code would look like. Let's start from classes which define API:
public class BaseApi
{
public virtual string Get()
{
return "";
}
}
and its concrete implementations:
public class ApiX : BaseApi
{
public override string Get()
{
return "Api_X";
}
}
public class ApiZ : BaseApi
{
public override string Get()
{
return "Api_X";
}
}
public class ApiT : BaseApi
{
public override string Get()
{
return "Api_T";
}
}
Then this is Parameter class:
public class Parameter
{
public string Parameter_1 { get; set; }
}
Then we need some place where we will store all API's that should be called. I think, we can create some very simple factory. This factory will have just one overridable method:
public abstract class ApiSimpleFactory
{
public abstract IEnumerable<BaseApi> GetAll();
}
and its concrete implementations:
public class ApiXZSimpleFactory : ApiSimpleFactory
{
public override IEnumerable<BaseApi> GetAll() =>
new List<BaseApi>()
{
new ApiX(),
new ApiZ(),
};
}
public class ApiXZTSimpleFactory : ApiSimpleFactory
{
public override IEnumerable<BaseApi> GetAll() =>
new List<BaseApi>()
{
new ApiX(),
new ApiZ(),
new ApiT(),
};
}
Now, we are ready to implementat Chain Of Responsibity pattern:
public abstract class ApiHandler
{
private protected abstract IEnumerable<string> ParameterOptions { get; }
private ApiHandler _nextApiHandler;
public void SetSuccessor(ApiHandler nextVehicleHandler)
{
_nextApiHandler = nextVehicleHandler;
}
public virtual ApiSimpleFactory Execute(Parameter parameter)
{
if (_nextApiHandler != null)
return _nextApiHandler.Execute(parameter);
return null;
}
}
and its concrete implementations:
public class XZApiHandler : ApiHandler
{
private protected override IEnumerable<string> ParameterOptions =>
new List<string> { "string1", "string2" };
public override ApiSimpleFactory Execute(Parameter parameter)
{
if (ParameterOptions.Contains(parameter.Parameter_1))
return new ApiXZSimpleFactory();
return base.Execute(parameter);
}
}
public class XZTApiHandler : ApiHandler
{
private protected override IEnumerable<string> ParameterOptions =>
new List<string> { "string3" };
public override ApiSimpleFactory Execute(Parameter parameter)
{
if (ParameterOptions.Contains(parameter.Parameter_1))
return new ApiXZTSimpleFactory();
return base.Execute(parameter);
}
}
And now we can execute our code:
ApiHandler chain = new XZApiHandler();
ApiHandler xztApiHandler = new XZTApiHandler();
chain.SetSuccessor(xztApiHandler);
Parameter parameter = new Parameter { Parameter_1 = "string3" };
ApiSimpleFactory apiFactory = chain.Execute(parameter);
IEnumerable<BaseApi> apiToBeExecuted = apiFactory.GetAll();
Im trying to make form wizard, where I could define steps. For each step I need to have contoller and view based on a type of step. I tried to do it on generic types, but I have problem with running method on controller which is generic.
Here is example.
public interface IExampleInterface { }
public abstract class WizardBaseController<T> : Controller where T : IExampleInterface
{
public abstract List<T> Steps { get; set; }
public abstract ActionResult RenderStep(T step);
public virtual ActionResult RenderNext(T step)
{
var index = Steps.IndexOf(step);
return RenderStep(Steps[index+1]);
}
}
public class ExampleClass : IExampleInterface { }
public class WizardController<T> : WizardBaseController<ExampleClass> where T : ExampleClass
{
public override List<ExampleClass> Steps { get; set; }
public override ActionResult RenderStep(ExampleClass step)
{
//do stuff
throw new NotImplementedException();
}
public virtual ActionResult RenderStep(T step)
{
throw new NotImplementedException();
}
public ActionResult CreateSteps()
{
Steps = new List<ExampleClass>
{
new AnotherExampleClassA(),
new AnotherExampleClassB(),
new ExampleClass(),
new AnotherExampleClassB(),
new AnotherExampleClassA(),
};
return RenderNext(Steps.First());
}
}
public class AnotherExampleClassA : ExampleClass { }
public class ChildWizzardConotroller : WizardController<AnotherExampleClassA>
{
public override ActionResult RenderStep(AnotherExampleClassA e)
{
//do stuff
throw new NotImplementedException();
}
}
public class AnotherExampleClassB : ExampleClass { }
public class AnotherChildWizzardConotroller : WizardController<AnotherExampleClassB>
{
public override ActionResult RenderStep(AnotherExampleClassB e)
{
//do stuff
throw new NotImplementedException();
}
}
but when I try to call action from wizardController I'm receiving 404 error
Trigger Action
Im not sure, if my way for doing it is correct.
Basicly my goal is to create wizard with differennt types of steps and call different methods based on a type of steps. For example for calling method RenderStep(with a parameter type - ExampleClass) I want to call method which is in WizardController,
when RenderStep(with a parameter type - AnotherExampleClassA) to call method in ChildWizzardConotroller etc.
I have an IDisposable HTML helper to create a specific html structure that I need very often in my app. I use it with razor and its works perfectly
#using (Html.SlidePanel("settings-button"))
{
<span>panel content</span>
}
I have a html helper component based on the structure and I want to use my SlidePanel inside.
public class MyComponent : IHtmlString
{
private readonly HtmlHelper html;
public MyComponent(HtmlHelper html)
{
this.html = html;
}
public override string ToString()
{
return Render();
}
public string ToHtmlString()
{
return ToString();
}
private string Render()
{
// I want to use my SlidePanel at this place
string renderHtml = "<div>component html</div>";
return renderHtml;
}
}
public static class MyComponentHtmlHelper
{
public static MyComponent MyComponent(this HtmlHelper html)
{
return new MyComponent(html);
}
}
How can I achieve this ?
Thanks
You'll need to intercept the string that SlidePanel would normally be sending to the general output. Something like this should work:
var originalWriter = html.ViewContext.Writer;
using (var stringWriter = new StringWriter())
{
html.ViewContext.Writer = stringWriter;
using (html.SlidePanel())
{
stringWriter.Write("<div>component html</div>");
}
html.ViewContext.Writer = originalWriter;
return stringWriter.ToString();
}
So here you go, example HERE
public static class DisposableExtensions
{
public static IDisposable DisposableDiv(this HtmlHelper htmlHelper)
{
return new DisposableHelper(
() => htmlHelper.BeginDiv(),
() => htmlHelper.EndDiv());
}
public static void BeginDiv(this HtmlHelper htmlHelper)
{
htmlHelper.ViewContext.Writer.Write("<div>");
}
public static void EndDiv(this HtmlHelper htmlHelper)
{
htmlHelper.ViewContext.Writer.Write("</div>");
}
}
}
As you can see in example "Hello Stranger" placed in additional div
I find a solution thanks to Baximilian and StriplingWarrior answers
Yes, I need to intercept the string that SlidePanel would normally be sending to the general output. So I can't use the ViewContext.Writer.
And yes, I need to send methods a parameters to my SlidePanel constructor.
So the solution is to add a second constructor to SlidePanel class :
public string HtmlString;
public SlidePanel(Func<string> begin, Func<string> content, Func<string> end)
{
this.HtmlString = string.Format("{0}{1}{2}", begin(), content(), end());
}
And add public helpers inside the SlidePanel Component class
public static string BeginSlidePanel(this HtmlHelper html)
{
return BeginHtml();
}
public static string ContentSlidePanel(this HtmlHelper html, string htmlString)
{
return htmlString;
}
public static string EndSlidePanel(this HtmlHelper html)
{
return EndHtml();
}
And then, I can use my SlidePanel like this :
new SlidePanel(
() => html.BeginSlidePanel(),
() => html.ContentSlidePanel(GetMyHtmlContent()),
() => html.EndSlidePanel()).HtmlString
Thanks a lot !
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
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.