Help me set up a password redirect page!
# help-with-umbraco
d
I haven't worked in Umbraco for very long, so I am struggling with this. Most of our document types have this password property on them(first pic). If an editor enters a password in that property, then the page is password protected. We accomplish this by modifying the Index() method of BasePageController.cs (second pic) 1. checks if there is a password 2. you can append the password to the end of the url , if it is there you will get access to the page 3. If there is no password in the url, it should redirect to a page with an input for the password. If you notice, VS is complaining about line 122. This is my problem. To redirect to the password page view, I need to pass in the corresponding model. The model is "IPasswordFormPageViewModel". Here is my class that inherits from the view model (third pic). All of our document types inherit from base types so I made this model do the same. The problem is that the constructor takes 12 arguments, which are normally resolved through dependecny injection. So when I try to create a new instance of my class, I don't have all of the parameters to pass in to the constructor. So I can't make a model, so I can't actually render the view. I don't know how to get around this. Does anyone have any suggestions? I don't know if this is even the right approach for what I am trying to accomplish. I was thinking maybe PasswordForm should be a component and not a full page. Any help would be great, I can provide more code screenshots too if necessary. https://cdn.discordapp.com/attachments/1161757189560610936/1161757189787111434/image.png?ex=653975b2&is=652700b2&hm=cfddbf663850fe71f05942206c43813b4572c9eb6464b6b82c9f0b17e68185ca& https://cdn.discordapp.com/attachments/1161757189560610936/1161757190034554982/image.png?ex=653975b2&is=652700b2&hm=d6f15dc8ba082b8fdb52a50d6e15e5956fd1f5c05882c5a864b2bc724bd785bc& https://cdn.discordapp.com/attachments/1161757189560610936/1161757190294614058/image.png?ex=653975b2&is=652700b2&hm=5beb96430db17b65f988fdb5acc7e733c6f550d46eae98bcd521cec4e2cc14dd&
d
Hi there!! It would seem to me that you're giving the published content models too much responsibility. For example: you're using an xmlsitemapitem (published content?) model to check for password protection. If your password protection is added as a composition, you could instead use the interface of the composition as the argument for
.IsPasswordProtected()
Then there is the PasswordFormPage. It seems that this model has a significant amount of service dependencies. How about you take those dependencies out of the model and precalculate the values they produce in a controller instead? Once all the services are out of the model, all thats left for you is to fill the model with data of your choice.
👆 that was written on mobile. To elaborate: From an outsider's perspective, it seems strange to involve 'sitemap' related elements in a feature related to password protection. That is a signal that indicates to me that this sitemap class might be doing more than it's supposed to. As for the PasswordFormPage: the idea of MVC is that the Model contains the data, the View presents the data and the Controller performs the business logic. The fact that your model requires this many services as dependencies, is a signal to me that your model might be doing the work of the controller.
If you're using the modelsbuilder in source mode, you might have a good candidate for a custom content finder perhaps? I'm not entirely sure, but you might be able to inherit from
ContentFinderByUrl
and see if you can find the content by URL. You could let that base class find the current content for you and check your requirements (is it a password protected page? and Is a password configured?) If so, you can use the published content model to navigate through your content tree and locate the password page using the
.Parent()
,
.Ancestor()
,
.Children()
and
.Descendants()
methods on the
IPublishedContent
model that the base class provided. Check out this page in the documentation for more information about content finders: https://docs.umbraco.com/umbraco-cms/reference/routing/request-pipeline/icontentfinder
d
Thanks for the replies! I think you are right that my model is doing way too much. All of my models inherit from that base class “Page” which is what required all the DI. I removed that from my model so that I could remove most of those dependencies. Then I was able to create a new instance of my model in basepagecontroller, and my password redirect page worked! I get what you are saying about putting the logic in the controller, but how would I call the controller from basepagecontroller? (Dumb question?) I think some of your suggestions require me to analyze my architecture as a whole. Every page is built this way pretty much. Also all of the views are using a base layout to style the page. The problem is the model for that base layout comes from the “Page” model that I just removed from my model! So while I got the my password page to work, I had to remove the bass layout so it has no styling now….
I don’t even know what an xmlsitemapItem is! Much to learn lol
d
Ah, I see. Ofcourse you don't want to refactor your entire application, that would probably not be productive. I guess the 'quick hack' would be to just inject the dependencies in your current controller and pass them into the model? If, however, you plan to do this in multiple places, you would probably be better of making a factory. You can make a factory class that uses dependency injection to get all those dependencies that you need and add a 'create' method in which you pass an
IPublishedContent
model and it creates the PasswordFormPage for you. Inject this factory into your controller and you have your logic nicely isolated, in case you decide at some point that you need a different way to create this model.