2sic / 2sxc

DNN + 2sxc = #DNNCMS - This tool helps web designers and developers prepare great looking content in DNN (DotNetNuke). It's like mixing DNN with Umbraco and Drupal :)
http://2sxc.org
MIT License
145 stars 40 forks source link

App.Data.Create returns System.NullReferenceException #1318

Closed Eudoxe closed 6 years ago

Eudoxe commented 6 years ago

I'm submitting a

about

Current behavior When calling a POST method in a controller outside of DNN and a 2sxc application (a stand alone htm file on the computer desktop for exemple), the method App.Data.Create returns a NullReferenceException. However, when the same method is called from a 2sxc template, it works perfectly.

Expected behavior We should be abble to call the WebAPI create function from outside a 2sxc app.

Minimal reproduction of the problem with instructions 1/ Create a new app "gouvGouvernement". Add a content Type "Organismes". Add 2 string fields "Nom" and "Acronyme" 2/ Create a controller file "api/gouvGouvernementController.cs". Code below 3/ Create a htm file on the computer desktop. Code below 4/ Load the htm page on Chrome or other browser 5/ Go to the admin log. You should see the exception and of course no item added. 6/ Create a template. Add the code bellow. 7/ Click on the link. The new entry should have been added.

< ================================================== >

gouvGouvernementController code

using DotNetNuke.Security;
using DotNetNuke.Web.Api;
using System.Web.Http;
using System.Collections.Generic;
using ToSic.SexyContent.WebApi;
using System.Linq;
using System;

public class gouvGouvernementController : SxcApiController

{
    [HttpPost]
    [AllowAnonymous]
    public string Create(Message postMessage)
    {    
        var Organismes = new Dictionary<string, object>();
            Organismes.Add("Nom", postMessage.Nom.ToString());
            Organismes.Add("Acronyme", postMessage.Acronyme.ToString());
            Organismes.Add("URL","URL");
            Organismes.Add("Sommaire","Sommaire");
            Organismes.Add("Détails","Détails");

            App.Data.Create("Organismes", Organismes, "Anonymous");

        return postMessage.Acronyme.ToString();
    }
}

public class Message
{
    public string Nom { get; set; }
    public string Acronyme { get; set; }
}

< ================================================== >

htm file

<html>
    <header>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <meta charset="UTF-8"/>
        <script>
            var vJson = {"Nom": "New org webapi","Acronyme": "ACRO webapi"};

            $.ajax({
            url:"https://wwwmywebsite/api/2sxc/app/gouvGouvernement/api/gouvGouvernement/Create",
            data:vJson,
            type:"POST",
            dataType: 'json',
            success: function(donnees) {
                    console.log(donnees);
                }
            }
        );
        </script>
    </header>
    <body>

    </body>
</html>

< ================================================== >

Code in a template

<a href="javascript:submitNewOrg(@Dnn.Module.ModuleID)">test</a>

<script>
    function submitNewOrg(mid) {
        $2sxc(mid).webApi.post("gouvGouvernement/Create", {}, { 
                Nom: "New org from template",
                Acronyme: "ACRO template"
                }
        ).then(function (result) {
            alert("Ok");
        });
    }
</script>

< ================================================== >

Stack errors 2 significative errors are logged in DNN:

Message:Object reference not set to an instance of an object.
StackTrace:
at ToSic.SexyContent.WebApi.SxcApiController.get_App() in C:\Projects\2SexyContent\Web\DesktopModules\ToSIC_SexyContent\Sxc WebApi\SxcApiController.cs:line 64 at gouvGouvernementController.Create(Message postMessage) at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.b__9(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Tracing.ITraceWriterExtensions.d__18`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Tracing.ITraceWriterExtensions.d__18`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Filters.ActionFilterAttribute.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Web.Http.Filters.ActionFilterAttribute.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Filters.ActionFilterAttribute.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Filters.AuthorizationFilterAttribute.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext()
InnerMessage:
InnerStackTrace:
Source:ToSic.SexyContent.WebApi

and an admin alert (which is not really revelant):

2sxc-Api:Auto-Log Exception
ModuleId:unknown
2sApiC(2f):find app by path:gouvGouvernement, found a:16

What is the motivation / use case for changing the behavior? External systems should be able to send their data to an application via webAPI POST

Please tell us about your environment: Azure application

Anything you would like to add This is the same problem reported on StackOverflow https://stackoverflow.com/questions/46476657/2sxc-method-app-data-create-returns-system-nullreferenceexception

iJungleboy commented 6 years ago

Thank you for a very well prepared question - I love answering these :). Since it's not a bug but just missing something in your work, I'll continue to answer it on your question in StackOverflow.

Eudoxe commented 6 years ago

I wanted to add a context. The call of the webApi SHOULD be done outside of DNN / 2sxc module. We have systems having data and want them to be sent these data to the DNN website. We can't use the $2sxc(mid).webApi.post javascript as we are outside.

So when called from outside, there is an error but when called from inside, there is no problem. Of course, it's the same controller code. Maybe it's something I'm doing wrong in the ajax call but I have a doubt that it is the problem because I receive properly the json sent in the controller and after that, it's the same instructions that are called for building the object that will be sent to the App.Data.Create instruction (the second arg).

May I respectfully ask you to reconsider the problem and can I suggest that you reproduce the problem with the supplied html file without paying attention to the "$2sxc(mid).webApi.post" code that works with my controller correctly?

Thank you very much for your involvement and support!

iJungleboy commented 6 years ago

I'm actually really convinced that my answer in stack-overflow is correct. did you read it? it explains how it works when using 2sxc-controllers from "outside".