1

Versions: DNN PLATFORM v. 09.01.00 (367) / 2sic 2SexyContent 09.06.00

Hello,

The external call to the WebAPI App.Data.Create method does not seem to work anymore (it was working with v9.4).

My controller is :

public class gouvGouvernementController : SxcApiController
{
    [HttpPost]
    [AllowAnonymous]
    public bool Create(organism postOrganisme)
    {
        var organisme = new Dictionary<string, object>();
        organisme.Add("Nom", postOrganisme.Nom.ToString());
        organisme.Add("Acronyme", postOrganisme.Acronyme.ToString());

        App.Data.Create("Organismes", organisme, "External system");
        return true;
    }
}


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

My ajax call (in a simple html page)

<script>
    var vJson = {
                "Nom": "Organism",
                "Acronyme": "ACRO1"
                };

    $.ajax({
    url:"https://www.mywebsite.net/api/2sxc/app/myapp/api/mycontroller/Create",
    data: vJson,
    type:"POST",
    dataType: 'json',
    success: function(donnees) {
            console.log(donnees);
        }
    }
);
</script>

The response of the method is

{"Message":"Bad Request","ExceptionType":"System.NullReferenceException","ExceptionMessage":"Object reference not set to an instance of an object."}

When I delete the line App.Data.Create("Organismes", organisme, "External system");, I receive a response 200 so the problem seems to be located in this method.

Can you tell me if I do something wrong ? As I already told it, the code was runing fine with 2sic_2SexyContent_09.04.03.

Thank you for your help!

f

EDIT: I just reinstall the version 9.4 and I have the same error so this is not related to the 2sxc version.

Obviously, I have a problem with my code so if someone can give me some advice, I will be really happy!

EDIT2: I installed the version 9.06.01 (labeled 9.06.00) and I still have the same issue. Here is the error stack:

at mycontroller.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, IDictionary2 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__181.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()

EDIT3: I tried to add this code in the page:

<a href="javascript:submitFeedback(@Dnn.Module.ModuleID)">test</a>
 <script>
    function submitFeedback(mid) {
        $2sxc(mid).webApi.post("gouvGouvernement/Create", {}, { 
                Nom: "Test ministère",
                Acronyme: "ACRO 123"
                }
        ).then(function (result) {
            alert("Ok");
        });
    }
</script>

and it works perfectly. It seems really to happend when I try to call from an Ajax form.

  • could you add more details? incl. stack trace? – iJungleBoy Oct 01 '17 at 07:38
  • note: we did just fix something in a pre-release of 9.6.1, might want to test that - see this issue and the download at the bottom: https://github.com/2sic/2sxc/issues/1310 – iJungleBoy Oct 01 '17 at 07:39

3 Answers3

0

Thanks for a very well documented question. Here's what's happening:

for 2sxc to do various checks like security etc. it needs to know some context, like what app it should be operating on. When you're using/inheriting the SxcApiController, it will auto-detect this context based on the module-id (and with that, look up a bunch of stuff), which is usually included in the header of the http request. If you use F12 on the browser you will see that there are about 5 headers added to a webapi call, ca. 3-4 are from DNN and 1 additional one from 2sxc. Here's an example

ContentBlockId:1199
ModuleId:1199
Debugging-Hint:bootstrapped by 2sxc4ng
TabId:470
RequestVerificationToken:gbqK5UyDGP7ZUqVN...

In your case you are either not sending these - but I'm guessing that you are, as you're executing your call with the $2sxc(mid) controller. Just check with F12 and look at the XHR-Requests to be sure.

In that case you are probably sending a module id which is not a 2sxc-module, so the controller cannot look up the remaining things necessary to complete auto-detection. For example, it can't auto-detect what app you are currently using.

...but there is a way :) ...at least two in fact

The preferred one is to not fully auto-detect the app, but to include the name in the url. You'll find it documented here: https://github.com/2sic/2sxc/wiki/WebApi

I would have to experiment a bit, but most likely you'll just replace

$2sxc(mid).webApi.post("gouvGouvernement/Create",

with

$2sxc(mid).webApi.post("app/[your app name]/api/gouvGouvernement/Create",

Please post the final solution when you figured it out :)

iJungleBoy
  • 4,419
  • 1
  • 6
  • 17
  • The use of the $2sxc(mid).webApi.post does work properly,,, That's not the point. The problem is more when trying to use the method outside DNN / 2sxc with a html file for exemple. The html file in my first question doesn't work, Can you try it on your side using the steps I gave you in the GitHub ticket? – Frédéric Laurent Oct 04 '17 at 10:33
  • the simple url you use will will be extendet to a app/auto/..., which tries to auto-detect. if you use app/[appname]/ it can detect the app from that. It must know what app it's working on. have you tried it? – iJungleBoy Oct 04 '17 at 14:57
  • As already exchanged by e-mail: tested your code in dnn 7.4.2 and dnn 9.1 using 2sxc 9.7 beta 2 and it worked. I presume this is fixed. – iJungleBoy Nov 03 '17 at 22:18
0

Not certain this is related but I found the same error in a tutorial you published: 1/ installed the "Tutorial - JavaScript - using the REST API" tutorial. 2/ using the "13+ - Simple get content-items out of a query with REST" gives an error 500. In the DNN logs, I have this "Object reference not set to an instance of an object" (see picture https://i.stack.imgur.com/uJxbO.png)

However my problem is not with a GET (I do a POST) and I'm not linked to Query but a Controller, at the end, the stack error shows the same problem. May be you'll be able to figure out what's happening with your own application.

Thank you very much!

0

For the record, here is the final answer of the developer:

When 2sxc calls a web api controller, it appends headers to the request which allow DNN and 2sxc to identify which portal, tab, module and app the request belongs to. This is needed because DNN needs to verify if the user has the corresponding rights to view the module, and 2sxc has to know in which context the api runs (for example, in which app to place data that should be created).

But when calling a 2sxc api-controller from outside (no 2sxc context), the request headers are missing, so you need to specify them by hand. Instead of using http headers, you can add querystring parameters to the request.

For your example, this would be the post url: http://mywebsite.com/api/2sxc/app/myapplication/api/mycontroller/Create?moduleid=123&tabid=12

If other are using the api call, consider this bug when developing.

Community
  • 1
  • 1