I am only aware of two approaches we can develop webparts using Visual studio.
The First one:
Add a webpart project and write code in the appropriate methods.
protected override void OnInit(EventArgs e)
protected override void OnLoad(EventArgs e)
protected override void CreateChildControls()
protected override void LoadViewState(object savedState) //Only at Postback
protected override void OnPreRender(EventArgs e)
protected override void Render(System.Web.UI.HtmlTextWriter writer)
protected override void OnUnload(EventArgs e)
public override void Dispose()
Deploy the Solution directly from the VS. Take the WSP File and use STSADM.EXE to deploy across the Site/Farm.This is the standard approach to follow.
Second approach:
Create a User Control and copy the Usercontrol.ascx and Usercontrol.ascx.cs to _Layouts.
Create a new webpart project and register the control using the
_UserControl = this.Page.LoadControl("\\_layouts\\_UserControl.ascx");
And Deploy it from the VS.
But this approach is not looking safe as we are manually copying to the _layouts.
The only reason we are going to take this approach is we can display the controls the way we want and not bothered to see the various events of webpart life cycle.
Could anybody let me know what approach you are taking in your company.
Thank you.
Hari Gillala
When I started developing in SharePoint 2007, we used the first method you describe. After some time, we switched to something like the second method.
However, instead of placing the ascx files into layouts, we put them in a custom directory under controltemplates. Our web part code then looked like this:
public class OurControlWebPart : WebPart
{
protected override void CreateChildControls()
{
base.CreateChildControls();
Control userControl =
Page.LoadControl("~/_controltemplates/OurProject/OurControl.ascx");
Controls.Add(userControl);
}
}
If our web part had any additional properties or toolparts, they would be handled in this class and then forwarded onto the control class. I really liked the separation of the logic of the control from the logic of the web part. Also, I liked being able to control the layout of the control in HTML or using the Visual Studio designer.
And these files do not need to be deployed manually. Then can be included in your solution package. Just like you have a path deploying your features to the 12\TEMPLATE\FEATURES directory, you can deploy your ascx files to 12\TEMPLATE\CONTROLTEMPLATES.
Definitely the second one, just look at the visual webparts in 2010 (they are built exactly like that).
sp2007, either way was fine, it just depends on how you like building your control tree. i prefer the first method.
sp2010 you have a few more options.
1) Your first choice should be a sand boxed web part, which uses a code building approach.
2) If that is too limited, you can try a visual web part, similar to the smart part from sp2007.
3) And then there is the standard code based approach.
Related
The code below was copied from this post. I see in other posts the same thing, such as in the answer for this this post.
Why is the line base.OnActionExecuting(filterContext); included inside the overall OnActionExecuting methods?
What purpose does it fulfill?
public class HomeController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// do some irrelevant stuff
base.OnActionExecuting(filterContext);
}
public ActionResult Index()
{
return View();
}
}
Short answer:
currently, the line base.OnActionExecuting(filterContext) does not do anything (performs no work). The functional behavior will be the same with or without the line.
Longer answer:
The .NET source code for Controller.OnActionExecuting looks as follows (taken from here):
protected virtual void OnActionExecuting(ActionExecutingContext filterContext)
{
}
If you look at the OnActionExecuting method, you'll see this method is completely empty. This is the code/method that base.OnActionExecuting(filterContext) is calling. You don't have to call base.OnActionExecuting(filterContext) as it currently does nothing however I would recommend doing so. The reason behind this is that if .NET framework is updated such that the Controller.OnActionExecuting method actually has needed code it in it, then the needed code will not be called without including the line in question. This could lead to some scenarios that can be pretty difficult and time-consuming to debug. It's also certainly possible for new framework code to be introduced that does break your code when you call base.OnActionExecuting however this scenario is generally easier to spot and fix than the other. Of course in the end, it's all going to come down to what code the framework introduces and what it breaks for how easy it is to identify and resolve.
As a side-note, .NET framework is in maintenance mode now so I highly doubt the example I mentioned above with .NET framework updating the code in Controller.OnActionExecuting will ever happen however it serves as a good best practice in other similar scenarios as well.
I'm now building an application in MVC5. Data of different corporations are stored in the same database and people access them under the control of "[Authorize(...)]" and some other costumed filters. With the growing of controllers and actions, I'm more and more worried about the security, for example: is there any actions without authorization or with wrong authorization?
So the question is: Is there any
1. Report views in Visual Studio (might not designed to do the work)
2. Third part tools
3. Something else
that give a clear map of authorization of all controllers/actions? This is a critical work and I think there should be some solutions rather than check through all those code files.
Thanks.
I like to use FluentSecurity because of this. From their docs:
Ignoring missing configurations
By default FluentSecurity will throw an exception if a missing
configuration is encountered for a controller action. If you don't
want FluentSecurity to handle security for all controllers you can
tell it to ignore missing configurations. You can do this by adding
configuration.IgnoreMissingConfiguration(); to your configuration
expression.
It puts security configurations in a single file, makes them unit testable, and is generally useful. There is a small learning curve to figuring out how to bootstrap it and get it set up. You can install it and get going quickly using nuget.
Besides this, there arent really any tools that I know of that can do the reporting that you are asking about... unless you want to write a battery of unit tests against each actionmethod:
[TestFixture]
public class AccountControllerTests {
[Test]
public void Verify_ChangePassword_Method_Is_Decorated_With_Authorize_Attribute() {
var controller = new AccountController();
var type = controller.GetType();
var methodInfo = type.GetMethod("ChangePassword", new Type[] { typeof(ChangePasswordModel) });
var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true);
Assert.IsTrue(attributes.Any(), "No AuthorizeAttribute found on ChangePassword(ChangePasswordModel model) method");
}
}
I am setting up a n tier system and have chosen to use ninject as the IoC/Di container. As part of this application I have got two MVC front ends. One is for the end user and the other is for the Administraion and configuration. I have chose two fron ends so that views & controllers e.t.c are contained and will make thinks a little easier to manage when I get to 100+ containers.
Anyway... What I want to know is?
Can I make my startup project the Admin application and instanciate Ninject e.t.c from here then when my second MVC application is called by the user it can use the same Ninject container which has alread been instantiated?
I hope this make sense to you all.
Also as an aside, does anyone know how to use Ninject to inject the DBcontext connection string/name?
You could create separate class library (called maybe SharedConfiguration?) with class
public static class NinjectSharedConfiguration
{
public static void RegisterServices(IKernel kernel)
{
kernel.Bind<MyDbContext()
.ToSelf()
.InRequestScope()
.WithConstructorArgument("nameOrConnectionString", "server = .;");
}
}
And make call to this method from both projects
I am used to IoC/DI in web applications - mainly Ninject with MVC3. My controller is created for me, filled in with all dependencies in place, subdependencies etc.
However, things are different in a thick client application. I have to create my own objects, or I have to revert to a service locator style approach where I ask the kernel (probably through some interface, to allow for testability) to give me an object complete with dependencies.
However, I have seen several places that Service Locator has been described as an anti-pattern.
So my question is - if I want to benefit from Ninject in my thick client app, is there a better/more proper way to get all this?
Testability
Proper DI / IoC
The least amount of coupling possible
Please note I am not just talking about MVVM here and getting view models into views. This is specifically triggered by a need to provide a repository type object from the kernel, and then have entities fetched from that repository injected with functionality (the data of course comes from the database, but they also need some objects as parameters depending on the state of the world, and Ninject knows how to provide that). Can I somehow do this without leaving both repositories and entities as untestable messes?
If anything is unclear, let me know. Thanks!
EDIT JULY 14th
I am sure that the two answers provided are probably correct. However, every fiber of my body is fighting this change; Some of it is probably caused by a lack of knowledge, but there is also one concrete reason why I have trouble seeing the elegance of this way of doing things;
I did not explain this well enough in the original question, but the thing is that I am writing a library that will be used by several (4-5 at first, maybe more later) WPF client applications. These applications all operate on the same domain model etc., so keeping it all in one library is the only way to stay DRY. However, there is also the chance that customers of this system will write their own clients - and I want them to have a simple, clean library to talk to. I don't want to force them to use DI in their Composition Root (using the term like Mark Seeman in his book) - because that HUGELY complicates things in comparison to them just newing up a MyCrazySystemAdapter() and using that.
Now, the MyCrazySystemAdapter (name chosen because I know people will disagree with me here) needs to be composed by subcomponents, and put together using DI. MyCrazySystemAdapter itself shouldn't need to be injected. It is the only interface the clients needs to use to talk to the system. So a client happily should get one of those, DI happens like magic behind the scenes, and the object is composed by many different objects using best practices and principles.
I do realize that this is going to be a controversial way of wanting to do things. However, I also know the people who are going to be clients of this API. If they see that they need to learn and wire up a DI system, and create their whole object structure ahead of time in their application entry point (Composition Root), instead of newing up a single object, they will give me the middle finger and go mess with the database directly and screw things up in ways you can hardly imagine.
TL;DR: Delivering a properly structured API is too much hassle for the client. My API needs to deliver a single object - constructed behind the scenes using DI and proper practices - that they can use. The real world some times trumps the desire to build everything backwards in order to stay true to patterns and practices.
I suggest to have a look at MVVM frameworks like Caliburn. They provide integration with IoC containers.
Basically, you should build up the complete application in your app.xaml. If some parts need to be created later because you do not yet know everything to create them at startup then inject a factory either as interface (see below) or Func (see Does Ninject support Func (auto generated factory)?) into the class that needs to create this instance. Both will be supported natively in the next Ninject release.
e.g.
public interface IFooFactory { IFoo CreateFoo(); }
public class FooFactory : IFooFactory
{
private IKernel kernel;
FooFactory(IKernel kernel)
{
this.kernel = kernel;
}
public IFoo CreateFoo()
{
this.kernel.Get<IFoo>();
}
}
Note that the factory implementation belongs logically to the container configuration and not to the implementation of your business classes.
I don't know anything about WPF or MVVM, but your question is basically about how to get stuff out of the container without using a Service Locator (or the container directly) all over the place, right?
If yes, I can show you an example.
The point is that you use a factory instead, which uses the container internally. This way, you are actually using the container in one place only.
Note: I will use an example with WinForms and not tied to a specific container (because, as I said, I don't know WPF...and I use Castle Windsor instead of NInject), but since your basic question is not specificaly tied to WPF/NInject, it should be easy for you to "port" my answer to WFP/NInject.
The factory looks like this:
public class Factory : IFactory
{
private readonly IContainer container;
public Factory(IContainer container)
{
this.container = container;
}
public T GetStuff<T>()
{
return (T)container.Resolve<T>();
}
}
The main form of your app gets this factory via constructor injection:
public partial class MainForm : Form
{
private readonly IFactory factory;
public MainForm(IFactory factory)
{
this.factory = factory;
InitializeComponent(); // or whatever needs to be done in a WPF form
}
}
The container is initialized when the app starts, and the main form is resolved (so it gets the factory via constructor injection).
static class Program
{
static void Main()
{
var container = new Container();
container.Register<MainForm>();
container.Register<IFactory, Factory>();
container.Register<IYourRepository, YourRepository>();
Application.Run(container.Resolve<MainForm>());
}
}
Now the main form can use the factory to get stuff like your repository out of the container:
var repo = this.factory.GetStuff<IYourRepository>();
repo.DoStuff();
If you have more forms and want to use the factory from there as well, you just need to inject the factory into these forms like into the main form, register the additional forms on startup as well and open them from the main form with the factory.
Is this what you wanted to know?
EDIT:
Ruben, of course you're right. My mistake.
The whole stuff in my answer was an old example that I had lying around somewhere, but I was in a hurry when I posted my answer and didn't read the context of my old example carefully enough.
My old example included having a main form, from which you can open any other form of the application. That's what the factory was for, so you don't have to inject every other form via constructor injection into the main form.
Instead, you can use the factory to open any new form:
var form = this.factory.GetStuff<IAnotherForm>();
form.Show();
Of course you don't need the factory just to get the repository from a form, as long as the repository is passed to the form via constructor injection.
If your app consists of only a few forms, you don't need the factory at all, you can just pass the forms via constructor injection as well:
public partial class MainForm : Form
{
private readonly IAnotherForm form;
// pass AnotherForm via constructor injection
public MainForm(IAnotherForm form)
{
this.form = form;
InitializeComponent(); // or whatever needs to be done in a WPF form
}
// open AnotherForm
private void Button1_Click(object sender, EventArgs e)
{
this.form.Show();
}
}
public partial class AnotherForm : Form
{
private readonly IRepository repo;
// pass the repository via constructor injection
public AnotherForm(IRepository repo)
{
this.repo= repo;
InitializeComponent(); // or whatever needs to be done in a WPF form
// use the repository
this.repo.DoStuff();
}
}
We're developing 3 asp mvc applications, all will require some of the same shared editor & display template views. Rather than copy/paste these across all 3 projects, is it possible somehow to put them in a shared component and reference them somehow in all applications?
You're going to need to create your own ViewEngine if you want to take to views from a place other than the Views folders.
public class CustomViewEngine : WebFormViewEngine {
public CustomViewEngine() : base() {
MasterLocationFormats = new[] {
"/YourFolder/{1}/{0}.master",
"/YourFolder/Shared/{0}.master"
};
ViewLocationFormats = new[] {
"/YourFolder/{1}/{0}.aspx",
"/YourFolder/{1}/{0}.ascx",
"/YourFolder/Shared/{0}.aspx",
"/YourFolder/Shared/{0}.ascx"
};
PartialViewLocationFormats = ViewLocationFormats;
}
//Override the FindView method to implement your own logic
public override ViewEngineResult FindView(
ControllerContext controllerContext, string viewName,
string masterName, bool useCache)
return base.FindView(controllerContext, viewName, masterName, useCache);
}
}
Then to register your ViewEngine in the Global.asax :
protected void Application_Start() {
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
}
Also, this post might be helpful. (too bad the download link at the bottom is broken though)
Edit : It appears this solution won't work in practice, since ASP.NET won't allow loading content from outside of the application's directory (see Eilon's comments).
But the link above, storing views in DB, could still be helpful.
I am not sure how it can be done but there must be a way to compile the pages in a DLL and share the library.
But if you can afford to use custom view engine and another template system (for example Stringtemplate) then you can share the views as if you are sharing a library:
Create a class library project
Create your templates as normal and mark them as 'Embedded resource'. This will make sure they will be put in the library's DLL
Write your custom view engine to pull the templates from the assembly (DLL). A good start might be editing/forking an existing one: http://code.google.com/p/string-template-view-engine-mvc/source/browse/trunk/StringTemplateViewEngine/StringTemplateViewEngine.cs
Then register your view engine in your ASP.NET MVC project
To share user controls (or almost any content) between multiple ASP.NET applications you can use the trick listed here: http://aspadvice.com/blogs/ssmith/archive/2006/10/05/Tip_3A00_-Share-User-Controls-Between-Applications-in-ASP.NET.aspx
The basic idea is to place the ASCX files in a folder and make that folder in to a virtual folder of other applications (you can have multiple virtual folders pointing at the same physical folder).