【问题标题】:Typescript + C# + Angular - Response does not match configured parameterTypescript + C# + Angular - 响应与配置的参数不匹配
【发布时间】:2016-10-22 04:49:08
【问题描述】:

我从一位前开发人员那里继承了一个应用程序,并且我几乎用尽了我所有的调试能力。这个应用程序是我第一次接触 Typescript,所以我也觉得有点失落。我在已发布的 StackOverflow 上也找不到与此相关的任何内容,所以这是我的问题:

我有一个名为“Task”的实体,它在C#中的定义如下:

public class Task : ModelBase
{
    public Task()
    {
        FiscalYears = new List<TaskFy>(28);
        Flags = new List<TaskFlags>();
    }

    [Required, AuditField("Project", typeof(Project))]
    public Guid Project_Id { get; set; }
    public virtual Project Project { get; set; }

    public Guid ScenarioId { get; set; }

    [AuditField("Active Status")]
    public bool IsActive { get; set; }

    [RegularExpression(@"^[A-z0-9]+$", ErrorMessage = "A Task # must be alphanumeric.")]
    [Required, MaxLength(4), AuditField("Task Name"), AuditDisplay]
    public string TaskName { get; set; }

    [Required, MaxLength(100), AuditField("Title")]
    public string Title { get; set; }

    [AuditField("Description")]
    public string Description { get; set; }

    [AuditField("ATO", typeof(Dropdown))]
    public Guid TaskAto_Ident { get; set; }
    public virtual Dropdown Ato { get; set; }

    [AuditField("DTO", typeof(Dropdown))]
    public Guid? DtoId { get; set; }
    public virtual Dropdown Dto { get; set; }

    [AuditField("Performer", typeof(Performer))]
    public Guid Performer_Id { get; set; }
    public virtual Performer Performer { get; set; }

    //<snip, several string fields here>

    public virtual List<TaskFy> FiscalYears { get; set; }
    public virtual List<Workpackage> Workpackages { get; set; }
    public virtual List<TaskFlags> Flags { get; set; }
}

请求任务时,返回的任务不为空,实际上是完全有效的任务(通过调试确认)。我在 Typescript 中也有定义:

export interface ITask extends ng.resource.IResource<ITask> {
    id: string;
    projectId: string;
    isActive: boolean;
    taskName: string;
    title: string;
    description: string;
    ato: IDropdown;
    atoId: string;
    dto: IDropdown;
    dtoId: string;
    performerId: string;
    performer: IPerformer;
    //<snip, same string fields here>
    fiscalYears?: ITaskFy[];
}

taskCtrl.ts如下:

export default class TasksCtrl {
static $controllerAs = 'p';
private isEditing: boolean;
private taskId: string;
private item: ITask;
private children: IByFlagsResult[];
private flags: ITaskFlags;
private objective: ITaskObjective;
private tso: IPoc;
private poc: ITaskPerformingOrg;
private fyStartYear: number;

static $inject = ['$stateParams', '$state', '$modal', 'Task', 'TaskFlags', 'TaskObjective',
    'TaskPerformingOrg', 'Toast', 'Login', 'KeyGen', 'fyStartYear', 'taskInfo', 'dropdowns'];
constructor(private $stateParams: ITaskParams, private $state: ng.ui.IStateService,
    private $modal: ng.ui.bootstrap.IModalService, private task: ITaskResource,
    private taskFlags: ITaskFlagsResource, private taskObjective: ITaskObjectiveResource,
    private taskPerformingOrg: ITaskPerformingOrgResource, private toast: IToast,
    private login: ILogin, private keygen: IKeyGen,
    fyStartYear: number, taskInfo: ITaskResolveResults, private dropdowns: any) {

    this.item = taskInfo.task;
    this.children = this.keygen.convertTreeToLinkElements(taskInfo.children, 'workpackage');
    this.flags = taskInfo.flags;
    this.objective = taskInfo.objectives;
    this.tso = taskInfo.tso;
    this.poc = taskInfo.poc;
    this.isEditing = taskInfo.isEditing;
    this.taskId = this.item.id;
    this.fyStartYear = fyStartYear;
}
//<snip, other methods here>

这就是问题所在 - 我有这个项目的两个版本。有旧的 repo 和新的 repo(旧的 repo 与 Java 应用程序混合在一起,在一个 repo 中太麻烦了)。如果我尝试运行新的 repo 版本,那么我最终会得到 ​​p>

Error in resource configuration for action `get`. Expected response to contain an object but got an array (Request: {3} {4})

当我尝试查看任务时在控制台中。如果我在新的 repo 代码运行时打开旧的 repo,一切都会开始工作,但我所做的(对 html 的)更改不会显示。在我关闭 Visual Studio 中的新存储库之前,此更改一直存在。

第二个错误伴随着控制台中的第一个错误:

TypeError: Unable to get property 'task' of undefined or null reference

指向线

this.flags = taskInfo.flags;

调试这表明 taskInfo 本身为空。这可能是上述错误的结果,但我认为提及它可能会有所帮助。

如果您需要任何进一步的信息或代码,请告诉我。

感谢您的收看!

编辑:

我已将我的问题缩小到以下 Typescript 块:

if ($stateParams.taskId) {
            return task.getByName({
                id: $stateParams.taskId,
                projectName: $stateParams.projectId,
                peName: $stateParams.peId,
                pcName: $stateParams.pcId,
                scenarioId: login.scenario.id
            }).$promise.then((retrievedTask: ITask) => {
                var flags = task.getFlags({ id: retrievedTask.id }).$promise.catch(() => []);
                var objectives = taskObjective.query({ id: retrievedTask.id }).$promise.catch(() => {
                    return new taskObjective({ taskId: retrievedTask.id }).$save();
                });
                var pOrgs = taskPerformingOrg.getByTask({ id: retrievedTask.id }).$promise.catch(() => {
                    return new taskPerformingOrg({ taskId: retrievedTask.id }).$save();
                });
                var tso = project.get({ id: retrievedTask.projectId }).$promise.then((project: IProject) => {
                    return poc.query({ id: project.pocId }).$promise.catch(() => {});
                });
                var children = workpackage.getByParent({ parentId: retrievedTask.id, scenarioId: login.scenario.id }).$promise.catch(() => [{"error":"Error"}]);

                return $q.all([flags, objectives, pOrgs, tso, children]).then(
                    (<any>_).spread((flags: ITaskFlags, objectives: ITaskObjective,
                        poc: ITaskPerformingOrg, tso: IPoc, children: ITreeNode[]) => {

                        visit.createVisit({ itemType: ReportLevel.Task, itemId: retrievedTask.id, scenarioId: login.scenario.id });

                        angular.extend(promiseResults, {
                            isEditing: true,
                            task: retrievedTask,
                            children: children,
                            flags: flags,
                            objectives: objectives,
                            poc: poc,
                            tso: tso
                        });

                        return promiseResults;
                    })
                    ).catch((err: any) => console.log(err));
            }).catch(() => {
                promiseResults.task = <ITask> { id: '404' };
                return promiseResults;
            });

具体来说,失败的行似乎是:

return $q.all([flags, objectives, pOrgs, tso, children]).then(
                    (<any>_).spread((flags: ITaskFlags, objectives: ITaskObjective,
                        poc: ITaskPerformingOrg, tso: IPoc, children: ITreeNode[]) => 

【问题讨论】:

  • 您的依赖项有时会发生变化,如 NuGet 依赖项或其他。在那里很难为您提供帮助。但是,我以前见过这个错误。这通常是因为 1)您的 WebAPI 端点返回 IEnumerable 而不是对象,或者 2)由于请求中传递的错误/缺失参数或错误的路由配置,您的路由被错误地命中。使用 Fiddler 调试确切的请求,查看它击中的端点(WebAPI 控制器函数),并验证它没有返回 IEnumerable。如果是,您可以从那里进行调试。
  • WebAPI 控制器函数被适当地命中,并返回单个任务。依赖角度很有趣,我有旧的代码库(如果我知道在哪里查找以及如何执行)可能会恢复到那些版本。
  • 那么响应正文应该包含在 {...} 而不是 [{...}] 中。我相信 Angular 的 $resource 服务正在检测 [] 是这个错误的意思。可能是错的,我不确定 TypeScript 是如何改变的。
  • 响应正文以 {...} 打开和关闭,但其中包含多个 [{...}]。使用旧代码库会生成相同的响应,并且似乎工作正常。编辑:您是否知道任何获取所有依赖项列表的方法(NuGet 或其他)?我将尝试看看接下来的那些。
  • 复制所有依赖项,没有骰子。关于从这里开始的任何想法?

标签: c# angularjs git typescript


【解决方案1】:

找出问题所在。事实证明,我从 C# 实体中删除了 Dto 字段和 DtoId 字段,但没有从 Typescript 定义中删除它们。如果您遇到同样的问题,我强烈建议您逐行查看您的实体定义并尝试确定是否缺少某些内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多