Jump to content

Can I use an asp.net web form in plugin


chef

Recommended Posts

chef

I am almost trough with trial and error. You give me a basic task to build in vb.net and I am your man! But trying to fiddle my way through learning javascript in html5 and I want to completely destroy the computer I am working on, literally through the console through an open window and watch it smash into little pieces.

It may be depreciated but I miss vbscript in web browsers! At least it look familiar!

So, my question is:

 

Can I build an asp.net web form to use as my plugins configuration page for media browser?

 

I need to code .net in my web form.

 

I am so bad at JavaScript I can't even get alerts to work half the time, and the plugin needs to do some reading and writing to xml. So you can imagine my frustration!

 

Any experts want to weigh in on possible alternatives to JavaScript in html?

Link to comment
Share on other sites

It really isn't that hard.  You'll get it.

 

We need to maintain the continuity of the configuration experience for the user.  We don't want to be jumping out to new pages for some plug-ins.

 

Any actual file manipulation should be done by the main plug-in and not actually the configuration page.  The configuration system provides you with your own, customizable config file and a way to read and update it from the js config page.  Lots of examples of this in the various repos.

 

If you really require more custom processing, you can also write your own API end points in your plug-in and call those from your config page.  A simple example of this is in the "Cleaner" plug-ins which make a simple call to retrieve and display the plug-in version.

Link to comment
Share on other sites

chef

I don't have a js config page in my project, that could probably be the problem.

 

I have been trying to read online how to call a sub procedure from js in a class in .net that is In the same project, but holy mackerel!

 

I need to add a config js file to my project.

 

Back to the repos I go.

Edited by chef
Link to comment
Share on other sites

The js can be a separate file but, for plug-in config pages, it is easier to just embed it in the html file (

 

What routine would you need to call from your config page?  As I said, to do this, you would write a custom API end point, but first be sure you really need to do it...

Link to comment
Share on other sites

chef

Edit: If I could access a subroutine in my Plugins class. I could handle everything in vb.net, that would be amazing.

 

If that is possible.

Edited by chef
Link to comment
Share on other sites

But what are you actually trying to do?

 

You could cause a routine in your plug-in to run by creating an API end point - but, depending on what you really need to do, that may not be necessary.

Link to comment
Share on other sites

chef

In my html page, I have a text box which I need to write the contents to an xml node when a button is pressed.

Edited by chef
Link to comment
Share on other sites

Okay, so your plugin has a configuration file defined in it.  It is called PluginConfiguration.cs.

 

You can add whatever properties you wish to this class and it will be serialized and saved and also read in when your plug-in is loaded.

 

When your config html page is loaded, there is an api call that will retrieve this class as a js object and you can access the properties on it.  Take the value and put it in the text field on page load and take the text value and put it in the property and then save the configuration when the save button is hit.

 

Just about every plugin in the repo has this basic process in it if it has any configuration.

Link to comment
Share on other sites

chef

What is the object name which is accessing the Properties? 

 

 

 

-----

When I build my plugin, and copy it over to the plugin folder, and restart the server, the html page doesn't always update when I choose "settings" on my plugin.

 

I have the "config.html" set as an embedded resource in my solution, is this correct?

Edited by chef
Link to comment
Share on other sites

Your config page will be cached based on the version of the plug-in.  So if you change something, the version number needs to change (or you can force refresh with the browser).

 

Your configuration object will be the response to the call to load your configuration.

                    ApiClient.getPluginConfiguration(CoverArt.pluginUniqueId).done(function(config) {

                        CoverArt.config = config;
                        Dashboard.hideLoadingMsg();
                        
                    });

Link to comment
Share on other sites

chef

Wait a minute! I think I am missing javascripts in my plugin solution.

 

Are there supposed to be scripts attached that would decalre "ApiClient"?  Because I haven't any.

Edited by chef
Link to comment
Share on other sites

Wrong class.  That is the class that defines the plugin configuration page not the configuration file itself.

 

The configuration file itself is PluginConfiguration inheriting from BasePluginConfiguration.

Link to comment
Share on other sites

chef

Right, Sorry there is a lot happening here. Two separate questions I think. thank you for tanking the time to help, by the way. If I learn this properly then I can help others.

 

Inorder to fix my problem, (based on what I see Snazy did in some of his plugins) I went a head and created a new class called "MyPluginConfiguration" it is separate from the "PluginConfiguration" class:

 

"MyPluginConfiguration":

Imports System.IO
Imports MediaBrowser.Model.Plugins
Imports MediaBrowser.Controller.Plugins
Imports MediaBrowser.Common.Plugins

Public Class MyPluginConfiguration
    Inherits BasePluginConfiguration
    Implements IPluginConfigurationPage

    Public Function IPluginConfigurationPage_GetHtmlStream() As Stream Implements IPluginConfigurationPage.GetHtmlStream
        Return [GetType]().Assembly.GetManifestResourceStream([GetType]().[Namespace] + ".configPage.html")
    End Function

    Public ReadOnly Property IPluginConfigurationPage_ConfigurationPageType() As ConfigurationPageType Implements IPluginConfigurationPage.ConfigurationPageType
        Get
            Return ConfigurationPageType.PluginConfiguration
        End Get
    End Property

    Public ReadOnly Property IPluginConfigurationPage_Name() As String Implements IPluginConfigurationPage.Name
        Get
            Return "Media Browser Vera Smart Home Control"
        End Get
    End Property


    Public ReadOnly Property IPluginConfigurationPage_Plugin() As IPlugin Implements IPluginConfigurationPage.Plugin
        Get
            Return Plugin.Instance
        End Get
    End Property
End Class

Here is my "Plugin" class now:


Imports System.Security.Permissions
Imports MediaBrowser.Common.Configuration
Imports MediaBrowser.Common.Plugins
Imports MediaBrowser.Model.Serialization


<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
<Runtime.InteropServices.ComVisibleAttribute(True)> _
Public Class Plugin
    Inherits BasePlugin(Of MyPluginConfiguration)

    Public Sub New(ByVal applicationPaths As IApplicationPaths, ByVal xmlSerializer As IXmlSerializer)
        MyBase.New(applicationPaths, xmlSerializer)


        Instance = Me

    End Sub

   
#Region "Properties"

    ''' <summary>
    ''' Gets the instance.
    ''' </summary>
    ''' <value>The instance.</value>
    Public Shared Property Instance() As Plugin
        Get
            Return _mInstance
        End Get
        Private Set(value As Plugin)
            _mInstance = value
        End Set
    End Property
    Private Shared _mInstance As Plugin

    Public Overrides ReadOnly Property Name() As String
        Get
            Return "Media Browser Vera Smart Home Control"
        End Get
    End Property


#End Region


End Class

And the new class which I believe we were just speaking about is the "PluginConfiguration" class, which is where I think you said all the properties will be written too:




''' <summary>
''' Class MyConfigurationPage
''' </summary>
Public Class PluginConfiguration
    

    Public Property SerializeThisStirngProperty As String
        Get
            Return _test
        End Get
        Set(value As String)
            _test = value
        End Set

    End Property
    Private _test As String = "Horray it Serilaized to the XML"

End Class

In actuality there are three main classes which the plugin must have... right?

Link to comment
Share on other sites

No, you are mixing two things that shouldn't be.  Your class that inherits BasePluginConfiguration is just your configuration properties - the things that will be saved to a file and referenced by your plug-in when you need to know options.

 

IPluginConfigurationPage is an interface that defines to the system the existence and location of your actual configuration Page.  These should be two separate classes.

Link to comment
Share on other sites

chef

Okay:

 

"PluginConfiguration" now inherits BasePluginConfiguration (to serialize to xml):


Imports MediaBrowser.Model.Plugins

''' <summary>
''' Class ConfigurationPage
''' </summary>
Public Class PluginConfiguration
    Inherits BasePluginConfiguration

    Public Property SerializeThisStirngProperty As String
        Get
            Return _test
        End Get
        Set(value As String)
            _test = value
        End Set

    End Property
    Private _test As String = "Horray it Serilaized to the XML"

End Class

and "MyPluginConfiguration" now implements the "IPluginConfigurationPage" interface:

Imports System.IO
Imports MediaBrowser.Model.Plugins
Imports MediaBrowser.Controller.Plugins
Imports MediaBrowser.Common.Plugins

Public Class MyPluginConfiguration
    Implements IPluginConfigurationPage

    Public Function IPluginConfigurationPage_GetHtmlStream() As Stream Implements IPluginConfigurationPage.GetHtmlStream
        Return [GetType]().Assembly.GetManifestResourceStream([GetType]().[Namespace] + ".configPage.html")
    End Function

    Public ReadOnly Property IPluginConfigurationPage_ConfigurationPageType() As ConfigurationPageType Implements IPluginConfigurationPage.ConfigurationPageType
        Get
            Return ConfigurationPageType.PluginConfiguration
        End Get
    End Property

    Public ReadOnly Property IPluginConfigurationPage_Name() As String Implements IPluginConfigurationPage.Name
        Get
            Return "Media Browser Vera Smart Home Control"
        End Get
    End Property


    Public ReadOnly Property IPluginConfigurationPage_Plugin() As IPlugin Implements IPluginConfigurationPage.Plugin
        Get
            Return Plugin.Instance
        End Get
    End Property
End Class

Edited by chef
Link to comment
Share on other sites

chef

Finally! When I call the UpdateConfiguration procedure on load, it places my property in the XML file.

 

For the first time in days I finally feel relief. I don't want to destroy the entire world.

 

....eh... so why doesn't my html doc load properly again?...

Edited by chef
Link to comment
Share on other sites

chef

@@ebr,

 

can the PluginConfiguration Serialize a Dictionary to xml?

 

Edit: crap I think I have to build an api endpoint

To read a dictionary

Edited by chef
Link to comment
Share on other sites

Dictionaries will serialize to json just fine so you can see them in your config page no problem.  However, the basic xml serialization we use in the server cannot serialize a dictionary.

 

I have an implementation of an xml serializable dictionary but it is in c#.

Link to comment
Share on other sites

chef

Dictionaries will serialize to json just fine so you can see them in your config page no problem. However, the basic xml serialization we use in the server cannot serialize a dictionary.

 

I have an implementation of an xml serializable dictionary but it is in c#.

That would be great. I wrote a routine which iterates the dictionary and builds the xml I need, but it is useless here:

 

My dictionary is:

 

Dictionary(of String, Dictionary(Of String,String)

 

The first string in the dictionary holds the client name.

The value of the dictionary is another dictionary, which holds the key which is a MediaBrowser event name, and the value will be the http request for Vera home automation.

 

I was hoping to serialize an xml which looks like this:

<?xml version="1.0"?>
<PluginConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
  <DLNA>
    <PlaybackStarted>Test Play</PlaybackStarted>
    <PlaybackStopped>Test Stopped</PlaybackStopped>
    <PlaybackPaused>Test Paused</PlaybackPaused>
    <PlaybackUnpaused>Test UnPaused</PlaybackUnpaused>
  </DLNA>
  <Dashboard>
    <PlaybackStarted>Test Play</PlaybackStarted>
    <PlaybackStopped>Test Stopped</PlaybackStopped>
    <PlaybackPaused>Test Paused</PlaybackPaused>
    <PlaybackUnpaused>Test UnPaused</PlaybackUnpaused>
  </Dashboard>
</PluginConfiguration>
Edited by chef
Link to comment
Share on other sites

chef

 

Your config page will be cached based on the version of the plug-in. So if you change something, the version number needs to change (or you can force refresh with the browser).

 

Your configuration object will be the response to the call to load your configuration.

                    ApiClient.getPluginConfiguration(CoverArt.pluginUniqueId).done(function(config) {

                        CoverArt.config = config;
                        Dashboard.hideLoadingMsg();
                        
                    });

@@ebr things are moving along, I spent all night learning jquery and now the code writing is super fast.

 

Earlier in our conversation you mentioned caching the config file.

 

You used "Apiclinet" call.

 

If I needed to take a string selected from a drop downbox in my html form and place it into a property in my configuration file, is this how I would do it?

Link to comment
Share on other sites

@@ebr things are moving along, I spent all night learning jquery and now the code writing is super fast.

 

Earlier in our conversation you mentioned caching the config file.

 

You used "Apiclinet" call.

 

If I needed to take a string selected from a drop downbox in my html form and place it into a property in my configuration file, is this how I would do it?

 

Chipping in by virtue of knowing JavaScript, rather than by virtue of being an expert on MediaBrowser, so if I am wrong somebody please correct me :)

 

The NextPVR configPage.html should give you a good example of how to submit your config page to the API:

https://github.com/MediaBrowser/MediaBrowser.Plugins/blob/master/MediaBrowser.Plugins.NextPvr/Configuration/configPage.html

 

The relevant portion of code is lines 70-87:

$('.nextpvrConfigurationForm').on('submit', function (e) {
    Dashboard.showLoadingMsg();
    var form = this;
    ApiClient.getPluginConfiguration(NextPvrConfigurationPage.pluginUniqueId).done(function (config) {
        config.WebServiceUrl = $('#txtWebServiceUrl', form).val();
        config.Pin = $('#txtPin', form).val();
        config.EnableDebugLogging = $('#chkDebugLogging', form).checked();
        ApiClient.updatePluginConfiguration(NextPvrConfigurationPage.pluginUniqueId, config).done(Dashboard.processPluginConfigurationUpdateResult);
    });
    // Disable default form submission
    return false;
});

This adds an event listener for the 'submit' event on the form (the supplied function will fire when the user submits the form)

 

the ApiClient.updatePluginConfiguration([::myPluginId], [::myConfigObject]) uses the ApiClient JavaScript library to submit your config object to the server. To get the value from your dropdown you would simply do:

config.MyPropertyName = $('#mySelectId', form).val();

Prior to the updatePluginConfiguration call. You could probably just use the NextPvr configPage.html as a starting point in your plugin, and just replace the input elements in the form with what you need, and the pluginUniqueId on line 51 with your plugin's ID. Just a thought.

Edited by TedA
  • Like 2
Link to comment
Share on other sites

chef

@@TedA

 

Thank you! I see the code now. JavaScript is new to me. Your through explaination helped me get the result I was looking for.

Does Submitting the form mean: when it is loaded, or when a submit button is pressed?

Web lingo is new to me as well.

Link to comment
Share on other sites

chef

@@ebr,

 

sorry, I know you're busy, but after testing numerous lines of javascript (including tedA's code, which I see is all over all the plugin repo, and I know is right),

 

I can not access the property through the ApiClient call in my Configuration class. I can't retrieve  any property Values, and I can't set new ones.

 

This is literally what I have in my code (pretty much exactly from the repo):

                var Vera = {
                    pluginUniqueId: "5a7bb1a0-15d6-4af4-9b22-866cddf39547"
                  
                };

                ApiClient.getPluginConfiguration(Vera.pluginUniqueId).done(function (config) {
                    Vera.config = config;
                    var mConfig = config.Options.filter(function (c) {
                      
                        
                    });
                        config.Options.push(mConfig);
                        ApiClient.updatePluginConfiguration(Vera.pluginUniqueId, config).done(Dashboard.processPluginConfigurationUpdateResult);
                    });

Does it matter that I get a warning in intellisense that "ApiClient" is possibly never assigned?  

 

Does the Plugin DLL get the ApiClient object from the server when it is installed in the "plugins" folder and run?

 

Are there javascript files that I should have added to my project (besides the nuget package DLL  mentioned in the Plugin Wiki on Github)?

 

I am sorry about all the questions, but I have spent far to long on this, with it going nowhere for me.

 

Ben

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...