json 2 typescript 映射给出类型错误

Posted

技术标签:

【中文标题】json 2 typescript 映射给出类型错误【英文标题】:json 2 typescript mapping gives type error 【发布时间】:2019-03-04 13:11:38 【问题描述】:

Okej,所以我试图通过 Web Api 2 将 .Net 对象列表映射到我的 Angular 前端。对象被发送,我得到它们,但根据具体情况,对象及其属性可能是就业参考, 作业参考或作业组织单位参考。

这是对象列表的外观图像,其中一个 AssignmentHolder 可以是这三个类之一,一个 DependentEntities 列表可以是这三个类之一。 以下是它们在我的 Angular 应用中的外观:

这是包含它们的对象:

@JsonObject('AssignmentListItem')
export class AssignmentListItem 
@JsonProperty('AssignmentHolder')
AssignmentHolder: any = undefined;

@JsonProperty('DependentEntities')
DependentEntities: any = undefined;

@JsonProperty('AssignmentRoles', [AssignmentRole])
AssignmentRoles: AssignmentRole[] = undefined;

@JsonProperty('NumberOfDependentEntities', Number)
NumberOfDependentEntities: Number = undefined;

@JsonProperty('IsInherited', Boolean)
IsInherited: boolean = undefined;

这些是类。

@JsonObject('ReferenceBase')
export class ReferenceBase 

@JsonProperty('OrganizationRegistrationNumber', OrganizationRegistrationNumber)
OrganizationRegistrationNumber: OrganizationRegistrationNumber = undefined;

@JsonProperty('IsIncomplete', Boolean)
IsIncomplete: Boolean = undefined;

@JsonProperty('SortingName', String)
SortingName: string = undefined;


-------

@JsonObject('EmploymentReference')
export class EmploymentReference extends ReferenceBase 

@JsonProperty('NationalCivicRegistrationNumber', String)
NationalCivicRegistrationNumber: NationalCivicRegistrationNumber = undefined;

@JsonProperty('GivenName', String)
GivenName: string = undefined;

@JsonProperty('Surname', String)
Surname: string = undefined;

@JsonProperty('FullName', String)
FullName: string = undefined;

constructor() 
    super();
    this.FullName = (this.GivenName + ' ' + this.Surname);
    this.SortingName = this.FullName;



-----
@JsonObject('AssignmentReference')
export class AssignmentReference extends ReferenceBase 

@JsonProperty('AssignmentRoles', [AssignmentRole])
AssignmentRoles: AssignmentRole[] = undefined;

@JsonProperty('OrganizationName', String)
OrganizationName: string = undefined;

@JsonProperty('NationalCivicRegistrationNumber', NationalCivicRegistrationNumber)
NationalCivicRegistrationNumber: NationalCivicRegistrationNumber = undefined;

@JsonProperty('Surname', String)
Surname: string = undefined;

@JsonProperty('FullName', String)
FullName: string = undefined;

@JsonProperty('GivenName', String)
GivenName: string = undefined;


------

@JsonObject('AssignmentOrganizationalUnitReference')
export class AssignmentOrganizationalUnitReference extends ReferenceBase 

@JsonProperty('OrganizationName', String)
OrganizationName: string = undefined;

@JsonProperty('Name', String)
Name: string = undefined;

@JsonProperty('Active', Boolean)
Active: Boolean = undefined;

@JsonProperty('IncludeSubUnits', Boolean)
IncludeSubUnits: Boolean = undefined;

@JsonProperty('AssignmentRoles', [AssignmentRole])
AssignmentRoles: AssignmentRole[] = undefined;

@JsonProperty('UnitId', String)
UnitId: string = undefined;

@JsonProperty('Type', OrganizationalUnitReferenceType)
Type: OrganizationalUnitReferenceType = undefined;

所以这些也是我想要映射的对象,具体取决于我返回的分配列表中的内容

这是我的自定义 DTO,因此我可以使用自定义转换器:

@JsonObject('AssignmentsDto')
export class AssignmentsDto 

@JsonProperty('AssignmentList', ObjectConverter)
AssignmentList: AssignmentListItem[] = undefined;

这是我的 JsonCustomConverter

@JsonConverter
export class ObjectConverter implements JsonCustomConvert<AssignmentListItem[]> 

// We receive the instance and just serialize it with the standard json2typescript method.
serialize(assignmentListItems: AssignmentListItem[]): any 
    const jsonConvert = new JsonConvert();
    return jsonConvert.serialize(assignmentListItems);


// We receive a json object (not string) and decide
// based on the given properties whether we want to
// create an instance of AssignmentReference or AssignmentOrgUnitReference.
deserialize(assignmentListItems: any): AssignmentListItem[] 

    const jsonConvert = new JsonConvert();

    let assignments = new Array<AssignmentListItem>();

    //Map the Holder entity.
    for (let assignment of assignmentListItems) 
        if (assignment.AssignmentHolder['__type'] === 'something.something.Web.Models.EmploymentReference' ||
            assignment.AssignmentHolder['__type'] === 'something.something.Web.Models.AssignmentEmploymentReference') 

            let tempAssignment: AssignmentListItem = jsonConvert.deserialize(assignment.AssignmentHolder, EmploymentReference);

            //For every assignment there is a list of Dependents. Here we map those.
            for (let dependent of assignment.DependentEntities) 
                if (dependent['__type'] === 'something.something.Web.Models.EmploymentReference' ||
                    dependent['__type'] === 'something.something.Web.Models.AssignmentEmploymentReference') 

                    let tempDependent: EmploymentReference = jsonConvert.deserialize(dependent, EmploymentReference);
                    tempAssignment.DependentEntities.push(tempDependent);

                 else if (dependent['__type'] === 'something.something.Web.Models.AssignmentOrganizationalUnitReference') 

                    let tempDependent: AssignmentOrganizationalUnitReference = jsonConvert.deserialize(dependent, AssignmentOrganizationalUnitReference);
                    tempAssignment.DependentEntities.push(tempDependent);
                
            

            assignments.push(tempAssignment);

         else if (assignment.AssignmentHolder['__type'] === 'something.something.Web.Models.AssignmentOrganizationalUnitReference') 

            let tempAssignment: AssignmentListItem = jsonConvert.deserialize(assignment.AssignmentHolder, AssignmentOrganizationalUnitReference);

            //For every assignment there is a list of Dependents. Here we map those.
            for (let dependent of assignment.DependentEntities) 
                if (dependent['__type'] === 'something.something.Web.Models.EmploymentReference' ||
                    dependent['__type'] === 'something.something.Web.Models.AssignmentEmploymentReference') 

                    let tempDependent: EmploymentReference = jsonConvert.deserialize(dependent, EmploymentReference);
                    tempAssignment.DependentEntities.push(tempDependent);

                 else if (dependent['__type'] === 'something.something.Web.Models.AssignmentOrganizationalUnitReference') 

                    let tempDependent: AssignmentOrganizationalUnitReference = jsonConvert.deserialize(dependent, AssignmentOrganizationalUnitReference);
                    tempAssignment.DependentEntities.push(tempDependent);
                
            
            assignments.push(tempAssignment);
        
    
    console.log('return ', assignments);
    return assignments;


最后,这是我使用转换器的 Assignment Api 服务。

    // GET LIST OF ASSIGNMENTS
getAssignmentList(
    filterStr: string,
    orgNoParam: string,
    skip: number,
    take: number
): Observable<any> 

    // set headers
    let head = new HttpHeaders();
    head = head.append('Content-Type', 'application/json'); 
    // set binds to model reciever
    const data = 
        'orgNoParam': orgNoParam,
        'filterStr': filterStr,

    ;
    let body = JSON.stringify(data);

    // set query parameters
    let url = this.assignmentListUrl + '?skip=' + skip + '&take=' + take;

    return this.http.post<any>(url, body,  headers: head )
        .map(this.convertData)
        .catch(this.handleError);


private convertData(res: Response) 

    let jsonConvert = new JsonConvert();
    jsonConvert.valueCheckingMode = ValueCheckingMode.ALLOW_NULL;

    let deSerializedAssignments: AssignmentListItem[] = jsonConvert.deserialize(res, AssignmentsDto).AssignmentList;

    return deSerializedAssignments;

我在控制台中遇到的错误是:

JsonConvert 中的致命错误。由于类型错误,无法将 JSON 对象映射到 javascript 类“AssignmentsDto”。类属性:AssignmentList 预期类型:未定义 JSON 属性:AssignmentList JSON 类型:[object, object, object, object, object]

【问题讨论】:

【参考方案1】:

我通过确保 json 对象中的每个属性都映射到 typescript 类来解决这个问题,并在 AssignmentsDto 中添加了第二个对象属性以及转换器,如下所示:

@JsonProperty('AssignmentList',[AssignmentListItem], ObjectConverter) 分配列表:分配列表项[] = 未定义;

希望这对某人有所帮助!

【讨论】:

以上是关于json 2 typescript 映射给出类型错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 2 的 TypeScript 中映射嵌套的 Json

如何在 TypeScript Angular 2 中将 Json 对象数组映射到另一个普通 json 对象

将 JSON 对象映射到 TypeScript 对象

更改(映射)JSON列表形状 - 在TypeScript中向对象添加标记

Java 映射到 JSON 到 Typescript 映射

优化 JSON 到 Typescript 映射