2sxc 方法 App.Data.Create returns System.NullReferenceException

2sxc method App.Data.Create returns System.NullReferenceException

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

您好,

对 WebAPI App.Data.Create 方法的外部调用似乎不再有效 (它在 v9.4 中有效).

我的控制器是:

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; }
}

我的 ajax 调用(在一个简单的 html 页面中)

<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>

方法的响应是

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

当我删除行 App.Data.Create("Organismes", organisme, "External system"); 时,我收到一个响应 200,所以问题似乎出在这个方法中。

如果我做错了什么,你能告诉我吗?正如我已经说过的,代码在 2sic_2SexyContent_09.04.03.

下运行良好

感谢您的帮助!

f

编辑: 我刚重装了9.4版本,还是一样的错误,所以这跟2sxc版本没有关系。

显然,我的代码有问题,所以如果有人能给我一些建议,我会很高兴!

编辑2: 我安装了 9.06.01 版本(标记为 9.06.00),但我仍然遇到同样的问题。这是错误堆栈:

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()

编辑3: 我试图在页面中添加此代码:

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

而且效果很好。当我尝试从 Ajax 表单调用时,这似乎真的发生了。

感谢您提出一个有据可查的问题。这是正在发生的事情:

为了让 2sxc 进行安全等各种检查,它需要知道一些上下文,比如它应该在哪个应用程序上运行。当你是 using/inheriting SxcApiController 时,它会 auto-detect 这个基于 module-id 的上下文(并且用它来查找一堆东西),它通常包含在 header 的 http 请求。如果您在浏览器上使用 F12,您会看到大约有 5 headers 添加到 webapi 调用中,ca。 3-4 个来自 DNN,另外 1 个来自 2sxc。这是一个例子

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

在你的情况下,你要么没有发送这些 - 但我猜你是,因为你正在使用 sxc(mid) 控制器执行你的调用。只需使用 F12 检查并查看 XHR-Requests 即可确定。

在那种情况下,您可能正在发送一个不是 2sxc 模块的模块 ID,因此控制器无法查找完成 auto-detection 所需的剩余内容。例如,它无法 auto-detect 您当前使用的是什么应用程序。

...但是有办法:) ...事实上至少有两个

首选的是不完全 auto-detect 应用程序,而是将名称包含在 url 中。您会在此处找到它的记录:https://github.com/2sic/2sxc/wiki/WebApi

我需要做一些实验,但很可能你会直接替换

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

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

请post想出最终解决方案:)

不确定这是否相关,但我在您发布的教程中发现了同样的错误: 1/ 安装了 "Tutorial - JavaScript - using the REST API" 教程。 2/ 使用“13+ - 使用 REST 从查询中简单获取内容项”给出错误 500。在 DNN 日志中,我有这个 "Object reference not set to an instance of an object"(见图 https://i.stack.imgur.com/uJxbO.png)

但是我的问题不在于 GET(我执行了 POST)而且我没有链接到 Query 而是链接到 Controller,最后,堆栈错误显示了同样的问题。也许您将能够弄清楚您自己的应用程序发生了什么。

非常感谢!

作为记录,这里是开发者的最终答案:

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

如果其他人正在使用 api 调用,请在开发时考虑此错误。