ScottGu showed a feature in vNext to use the Activate Attribute like this:
public class HomeController : Controller
{
[Activate]
public TimeService TimeService { get; set; }
}
I'm on beta-8 and I can't seem to find this attribute, did it get removed?
In addition to using the renamed [FromServices] annotation on your properties, you can also utilize constructor injection:
public class HomeController : Controller
{
private TimeService _timeService;
public HomeController(TimeService timeService)
{
_timeService = timeService;
}
}
I prefer this approach since ASP.NET 5 will fail to construct HomeController if it cannot find TimeService, rather than failing later with timeService being null.
Found it...changed to [FromService]
Related
I have a controller for example:
namespace MyApi.Controllers
{
[Authorize(Roles = "Administrador, SuperAdmin")]
public class AccountController : Controller
{
}
[Authorize(Roles = "Administrador, SuperAdmin")]
public AccountController()
{
}
[Authorize(Roles = "Administrador, SuperAdmin")]
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
}
As you can see I add same Authorize to each method, and I know if there any way to do a global one that take effect on all of them? Regards
I can't believe no-one has properly answered this question for 5 months. Also, the question has a misleading title. People would come here looking for MVC form validation, that is a different concept from authorization, which is what this question is about.
The answer is very simple, as indicated in the comments to the question: remove the Authorize attribute from all the methods, and just leave it at the class level - It will then automatically apply to all public methods.
Also, be careful when pasting code to preserve all the proper braces and indentation.
namespace MyApi.Controllers
{
[Authorize(Roles = "Administrador, SuperAdmin")]
public class AccountController : Controller
{
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
}
...
}
}
I have a project that has a 'core' version, and a 'customised' version.
They are separate projects.
'customised' inherits functionality from 'core' and in some case overrides methods.
For example:
I have a user model that looks like this:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Then, in a separate assembly,
public class User : Core.User
{
public string CustomProperty { get; set; }
}
I then have a controller (in my 'core' assembly)
public class UserController : Controller
{
[HttpPost]
public ActionResult SaveUser(User user)
{
}
}
In my other project, I have a UserController that inherits from Core.UserController:
public class UserController : Core.UserController
{
[HttpPost]
public ActionResult SaveUser(Custom.User user)
{
}
}
Obviously, in my Global.asax I have the controller namespaces mapped
However, when I hit the SaveUser method, I get
The current request for action SaveUser on controller type
UserController is ambiguous between the following action methods
While I understand the problem, is there any way around this?
In a nutshell:
I want to use Core.UserController methods most of the time, but in this instance, I need to use my Custom.UserController SaveUser method (since it takes my Custom.User type)
Polymorphism?
public class UserController : Controller
{
[HttpPost]
public virtual ActionResult SaveUser(User user)
{
}
}
public class UserController : Core.UserController
{
[HttpPost]
public override ActionResult SaveUser(User user)
{
var customUser = user as Custom.User;
if(customUser != null)
{
//Your code here ...
}
}
}
Another possible workaround if the polymorphism solution doesn't work or isn't acceptable, would be to either rename your UserController or its action method to something slightly different:
public class CustomUserController : Core.UserController
{
[HttpPost]
public ActionResult SaveUser(Custom.User user)
{
}
}
public class UserController : Core.UserController
{
[HttpPost]
public ActionResult SaveCustomUser(Custom.User user)
{
}
}
If you wanted to keep the routes consistent with the other project, you would just have to create a custom route for this.
I encountered the same problem in my own project today and came across your post.
In my case, while I didn't want to alter the way the core controller's logic functioned, I was able to make changes to its code, and thus its modifier keywords. After adding virtual to the base controller's actions, and override to my derived controller's actions. The original controller's actions still function, my derived controller uses my customized actions, no more ambiguous errors.
I realize you may not be able to modify your Core controller, and if this is the case, then you need to differentiate your actions using some other means. Action name, parameters or some other solution such as a custom implementation of ActionMethodSelectorAttribute. That was my first attempt at this problem, but before I got too far down that path of how to implement it, I discovered the virtual/override solution. So I don't have code to share on that route unfortunately.
I have been reading for a couple of days about Unity in MVC, and I've been trying to get this to work - hoping you guys can help.
I've set up Unity in the way described here which, from extensive googling, seems common enough. I can probably confirm that this setup is working, since on my Home Controller I can get this DI to work nicely:
public class HomeController : Controller
{
[Dependency]
public IRepository repo { get; set; }
public ActionResult Index()
{
string message = repo.GetMessage();
ViewData["OUT"] = message;
return View();
}
}
However, I have a class ("Contact") which for various reasons also needs access to repository methods, hence the coupling, and the requirement for DI. So within the class I have a [Dependency] property just as above. So for example I have the following code:
public partial class Contact
{
[Dependency]
public IRepository repo { get; set; }
public string CoupledProperty
{
get
{
return repo.GetCoupledProperty();
}
}
So then if I attempt to retrieve an already existing Contact object on the Home Controller, e.g.:
public class HomeController : Controller
{
[Dependency]
public IRepository repo { get; set; }
public ActionResult Index()
{
Contact contact = repo.GetContact(1);
string message = contact.CoupledProperty;
ViewData["OUT"] = message;
return View();
}
}
I get an object not instantiated error highlighting the line of the code on the Contact class where the CoupledProperty attempts to access the repository. And of course, swapping out the Dependency property in the Contact class for a hard coded repository object works properly.
Can anyone see what is going wrong here?
Cheers,
Tim.
EDIT:
The GetContact(int) method in the repository is:
public Contact GetContact(int id)
{
return db.Contacts.SingleOrDefault(c => c.ContactID == id);
}
What does the GetContact(int) method look like in your repository implementation? Does it use Unity to produce the contact? I suspect it doesn't.
You can resolve it with DependencyResolver, if thats the resolver you are using.
repo = DependencyResolver.Current.GetService<IRepository>();
I would suggest you write some unit tests alongside all this code to continuously test and validate the code you have written. Besides StriplingWarrior's suggestion, I would also recommend you to check your DI Container wireup.
I'd like to create a custom validation attribute for MVC2 for an email address that doesn't inherit from RegularExpressionAttribute but that can be used in client validation. Can anyone point me in the right direction?
I tried something as simple as this:
[AttributeUsage( AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false )]
public class EmailAddressAttribute : RegularExpressionAttribute
{
public EmailAddressAttribute( )
: base( Validation.EmailAddressRegex ) { }
}
but it doesn't seem to work for the client. However, if I use RegularExpression(Validation.EmailAddressRegex)] it seems to work fine.
You need to register an adapter for the new attribute in order to enable client side validation.
Since the RegularExpressionAttribute already has an adapter, which is RegularExpressionAttributeAdapter, all you have to do is reuse it.
Use a static constructor to keep all the necessary code within the same class.
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class EmailAddressAttribute : RegularExpressionAttribute
{
private const string pattern = #"^\w+([-+.]*[\w-]+)*#(\w+([-.]?\w+)){1,}\.\w{2,4}$";
static EmailAddressAttribute()
{
// necessary to enable client side validation
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EmailAddressAttribute), typeof(RegularExpressionAttributeAdapter));
}
public EmailAddressAttribute() : base(pattern)
{
}
}
For more information checkout this post explaining the complete process.
http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
The CustomValidationAttribute Class MSDN page has a few examples on it now. The Phil Haacked post is out of date.
Look at the universal Dependent Property Validator in this article
Have you tried using Data Annotations?
This is my Annotations project
using System.ComponentModel.DataAnnotations;
public class IsEmailAddressAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
//do some checking on 'value' here
return true;
}
}
This is in my Models project
namespace Models
{
public class ContactFormViewModel : ValidationAttributes
{
[Required(ErrorMessage = "Please provide a short message")]
public string Message { get; set; }
}
}
This is my controller
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ContactUs(ContactFormViewModel formViewModel)
{
if (ModelState.IsValid)
{
RedirectToAction("ContactSuccess");
}
return View(formViewModel);
}
You'll need to google DataAnnotations as you need to grab the project and compile it. I'd do it but I need to get outta here for a long w/end.
Hope this helps.
EDIT
Found this as a quick google.
Brad Willson has a great article on descripting how to use DataAnnotations. http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html What I would like to do is extend the available attributes that I can use. Something like [ PastDate(you must enter a date in the past)] or [InvoiceNumber( all invoices start with INV and end with 002)]. I know that I could use the Regular expression attribute to accomplish this. However having more descriptive attributes would be a cleaner solution.
You need to create a class that inherits from System.ComponentModel.DataAnnotations.ValidationAttribute and then use that attribute like this :
public class yourModel {
[CustomValidation(typeof(yourClass), "yourMethod")]
public int yourProperty { get; set; }
}
Haven't tried it but it should work.
I have a few of these in my project - some still use regular expressions, but at least this way they're only in one place:
public class TelephoneAttribute : RegularExpressionAttribute
{
public TelephoneAttribute()
: base(#"^\(?(\d{3}\)?)((-| )?\d{3})(-?\d{4})$") { }
}
And more like what your example:
public class MinimumDateAttribute : RangeAttribute
{
public MinimumDateAttribute(string MinimumDate)
: base(typeof(DateTime), MinimumDate, DateTime.MaxValue.ToShortDateString()) { }
}