Creating a C# Module in DNN - c#

I want to embed a C# class in a module so that I can call the functions using buttons and click events. I have no idea how to do this. I've managed to write the class I want to use, but where do I put the code? I created a module in DNN and got this:
<%# Control Language="C#" ClassName="MailingSystem" Inherits="DotNetNuke.Entities.Modules.PortalModuleBase" %>
<h1>Congratulations</h1>
<p>You have successfully created your module. You can edit the source of the module control by selecting the View Source Action from the Action Menu.</p>
<script runat="server">
</script>
I can't put my code in here, I get all sorts of errors about namespaces not allowed, can't import classes with "Using", and so on. So what am I supposed to do? My class is working, I just need to wrap it in a module and put it on a DNN page.

It is better to start with a DotNetNuke Module Template, like this one. It isn't as easy as creating an aspx page.

simply you can double click on design part of the page , then the page load section will be appear in the page and you can put your c# code there.

You may want to do something like this:
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
/// code goes here
}
</script>

If you don't want want to go the whole module template route. Do the following.
Create an webusercontrol (.ascx)
Go to the code behind file (.ascx.cs) and change the class to inherit from DotNetNuke.Entities.Modules.PortalModuleBase (your will need to add DotNetNuke.dll as reference)
Add what ever controls you want to the ascx and attach any event handlers. I prefer to do this in the page init method
In ASCX:
<asp:Button ID="btnButton" Text="Click me" runat="server" />
In Code Behind:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
btnButton.Click += btnButton_Click;
// OR
btnButton.Click += (sender, e)=> { // Button clicked! Do something };
}
protected void btnButton_Click(object sender, EventArgs e)
{
// Your button has been clicked, Do something
}
Compile code
Get [yourprojectname].dll file from the bin folder of your project and copy it into DNN's bin folder. Then, copy your module control ascx into a dedicated folder in DNN's DesktopModules Folder
Example Path: DesktopModule > YourProjectName > [YourASCXName].ascx
Login to DNN, go to Host>Extensions and click add extension. Go through the wizard making sure to set your extension type to Module (there are many different types of extensions in DNN).
Once added, you will be be taken back to the module extensions page. Scroll down and find your module extension. Click edit, go to module definitions and add a module definition with a meaningful name.
Example: YourProjectNameMainView
Then, add your ASCX file as a view to that module extension. Click save and you are done with setup
You should be able to drop your (VERY BASIC) module on a page and use it!

Related

Difference between attaching event from server side and writing event name in aspx

Many times i came across this scenario but didn't know the exact reason of cause.
What is the difference between this
grdQuotes.Sorting+=new GridViewSortEventHandler(grdQuotes_Sorting);
and this(directly declaring in aspx )
OnSorting="grdQuotes_Sorting"
when i attach event using first method mentioning the access level for function is optional but if i use the second option and didn't mention any access level with function then is get 'function is inaccessible due to its protection level error message'
As far as I know there's no difference between binding event in aspx code and doing it in code behind. However as Thangadurai said - when you handle events in the code behind you can attach multiple handlers to one event.
When it comes to the protection level - aspx code can't access code behind methods which are private (and if you don't mention any access level before a method it's private). Here's an example:
Code behind:
public void Test()
{
lblTest.Text = "clicked code behind";
}
Aspx:
<script runat="server">
void btnTest_Click(object sender, EventArgs e)
{
Test();
}
</script>
If you change Test method access level to private the btnTest_Click method won't be able to see it. Only public, protected and protected internal methods are possible to call in aspx code.
It's because the .aspx page inherits from the code-behind class:
If you use code-behind class files with .aspx pages, you can separate
the presentation code from the core application logic (or
code-behind). The code-behind class file is compiled so that it can be
created and used as an object. This allows access to its properties,
its methods, its and event handlers. For this to work, the .aspx page
must specify to inherit from the code-behind base class. To do this,
use the Inherits attribute for the # Page directive. The .aspx page
inherits from the code-behind class, and the code-behind class
inherits from the Page class.
http://support.microsoft.com/kb/312311

designer.cs issues with using user control in Visual Studio

During my development, I have a web user control project and another web project which will use the user controls from the web user control project.
So I copy the DocControl.ascx file to my web project and try to use the properties of the DocControl.ascx.
But VS does not know the properties of the control. So when I check the designer.cs, the reference is like that
protected global::System.Web.UI.UserControl Control;
Which should be
protected global::MSN.DocControl Control;
So I changed the name of the control from System.Web.UI.UserControl to MSN.DocControl and I can use the properties of the DocControl.ascx.
But my issue is whenever I modify ( eg. put a lable in aspx) the aspx file, the reference in designer.cs become
protected global::System.Web.UI.UserControl Control;
So I has to change it whenever I modify my aspx.
What should I do so I don't need to change the designer.cs
Thanks in advance......
I have solved it by moving
protected global::MSN.DocControl Control;
from designer.cs to .cs page.
So whenever you made any changes, it will be OK.
#kokbira - > hope that it helps you.
In my case, it was a bad src path in my register line. This caused no error messages, but would generate the generic control instead of the specific class, with the same symptoms you describe.
I had this (which has the wrong Src path):
<%# Register TagPrefix="uc" TagName="Pipes" Src="/Controls/Pipes.ascx" %>
...
<uc:Pipes id="ucPipes" runat="server" />
and it generated this, which is generic, and has none of the control's properties:
protected global::System.Web.UI.UserControl ucPipes;
When I did the correct path, with Category folder, it worked:
<%# Register TagPrefix="uc" TagName="Pipes" Src="/Category/Controls/Pipes.ascx" %>
...
<uc:Pipes id="ucPipes" runat="server" />
and generated this correct one, so all properties worked:
protected global::Company.Category.Controls.Pipes ucPipes;

How to add html to an aspx C# codebehind page?

I have access to a server with aspx pages. I need to add a title, parapgraphs, etc to a page. The page currently only has the following line:
<%# Page Language="C#" AutoEventWireup="true" Inherits="Access.Login" %>
I do not have access to the CS files, just the DLL. Anyway, when I try to add any html to the document nothing changes. I am able to change the CSS, and if I remove the "inherits" then whatever HTML I have gets displayed, but when the "inherits" is there only the default page gets displayed and none of my additions.
Admittedly I am new to ASP and moreover I am not trying to become a guru just to add some HTML to a page, but any advice would be great, thanks!
Try putting your Page_Load embedded in the .aspx and add controls that way:
<%# Page Language="C#" AutoEventWireup="true" Inherits="Access.Login" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e) {
if (!Page.IsPostBack) {
Controls.Add(whatever);
}
}
</script>
<!-- Try this if the above does not work -->
<script runat="server">
new protected void Page_Load(object sender, EventArgs e) {
base.Page_Load(sender, e);
if (!Page.IsPostBack) {
Controls.Add(whatever);
}
}
</script>
Fundamentally, I'm afraid this is not possible. .NET is a single-inheritance language/framework. So when it says Inherits="Access.Login" that means you can only have it use Access.Login OR your code-behind, but not both.
That said, you could jump through some crazy hoops to accomplish your goal. Like create a brand new "wrapper" page, then in the code-behind fire off an http request to the page you want. Load the response, which will just be a really long string into a 3rd-party DOM parser, or if you're confident you're getting 100% valid XML back, use .NET's built-in XmlDocument or XDocument to parse the page, find your html elements, make your changes, then do a Response.Write with your modified content.
And that's a real-life example of going around your elbow to get to your...
I am not 100% certain this will work, but you could have a code-behind file inherit from Access.Login and use the new (override will not work if Page_Load isn't marked as virtual) keyword with Page_Load. Then you could use Inherits="YourAssembly.NewLogin".
The part I am not sure about is whether or not asp.net uses the page class or your subclass to call the Page_Load method. If page_Load was virtual, it wouldn't matter, but since it isn't the new will only be called if the page is cast into your subclass. It is worth a try though.

ascx runat server script

I have default.aspx with a "Submit" Button and a code behind function called as "btn_Submit" which will perform submit action. Once I deploy the application and if there is any logical problem in btn_Submit code, then I can use runat=server script in default.aspx file and I need not go for another deployment.
But When I tried the same for ascx file, it works very well in development environment i.e in VS but when I move the same to Test server, system throws function not defined. I have renamed the existing function name.
So is it possible to add runat=server script and add c# code in ascx file?
Yes it is possible..
You have to surround your code with markup
<script language="c#" runat="server">
public void Page_Load(object sender, EventArgs e)
{
//hello, world!
}
</script>
Take a look to thisquestion! I think it will help you..
But it is really better to separate your code..
Did you tell the button which method to run on submit? With "auto event wireup" it will try to find a "buttonname_Click" method if you didn't specify anything. If that doesn't exist, you will get an error.
To call a method with a different name, specify that in the OnClick property of the button.
I am not sure why this happened and still was not able to solve it, So redeployed the application :(

Passing parameters to a User Control

We are trying here to localize our user control basically we want to be able to do something like this :
<in:Banner runat="server" ID="banners" Lang="fr" />
The way we do this is by page level and send it to master that then send it to the control:
protected void Page_Load(object sender, EventArgs e)
{
Master.Lang = "FR";
}
Then in the MasterPage.master we do something like this :
<in:Banner runat="server" ID="banners" Lang="<%= Lang %>" />
The masterpage has a public proprety named Lang.
In the control we have set a field that contains the default language and a proprety (Lang) that set the language. It seems that whatever we do, the current language is not sent from the page to the usercontrol... any help?
Not exactly like that, but you can consider the content page like a control in the master page, so its likely that the page load of the page is executing before the page load of that user control.
Regardless of the above, why not set the ui culture to the asp.net thread (probably from the global.asax), and using that from the control.
Another alternative is to have a separate class where you hold the current language, and expose a change event ... that way you can make sure to use the right language even if the load is done differently --- or there is a change language event later.
You can access it in code-behind of the MasterPage like this
public void SetLanguage(string language)
{
banners.Lang = language; //banners is an ID reference to your user control.
}
Or in your markup I think you can do it like this
<in:Banner runat="server" ID="banners" Lang='<%# Bind("Lang") %>' />
I should mention that Bind works in .Net 2.0 and up.

Categories