简体   繁体   English

json 2打字稿映射给出类型错误

[英]json 2 typescript mapping gives type error

Okej so Im trying to map a list of .Net objects to my Angular frontend by way of Web Api 2. The objects are sent, I get them, but depending on the circumstances the objects and their properties might be an Employment reference, Assignment reference or an Assignment organization unit reference. Okej所以我试图通过Web Api 2将.Net对象列表映射到我的Angular前端。对象被发送,我得到了它们,但是根据情况,对象及其属性可能是“就业参考”,“工作分配参考”或分配组织单位参考。

Here is an image of how the list of objects can look, with one AssignmentHolder that can be one of those three classes and a list of DependentEntities that can be one of those three classes. 这是一个对象列表的图像,其中一个AssignmentHolder可以是这三个类之一,而DependentEntities列表可以是这三个类之一。 在此处输入图片说明 Here is how they look in my Angular app: 它们在我的Angular应用中的外观如下:

This is the object containing them: 这是包含它们的对象:

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

These are the classes. 这些是类。

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

So those are the objects I want to map too depending on what Is in the assignmentlist I get back 这些也是我要映射的对象,具体取决于我返回的任务列表中的内容

This is my custom DTO so that I can use a custom converter: 这是我的自定义DTO,因此我可以使用自定义转换器:

@JsonObject('AssignmentsDto')
export class AssignmentsDto {

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

this is my JsonCustomConverter 这是我的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;
}
}

And finally, this is the Assignment Api Service where i use the converter. 最后,这是我使用转换器的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;

The error I get in console is : 我在控制台中得到的错误是:

Fatal error in JsonConvert. JsonConvert中的致命错误。 Failed to map the JSON object to the JavaScript class "AssignmentsDto" because of a type error. 由于类型错误,无法将JSON对象映射到JavaScript类“ AssignmentsDto”。 Class property: AssignmentList Expected type: undefined JSON property: AssignmentList JSON type: [object, object, object, object, object] 类属性:AssignmentList期望的类型:未定义的JSON属性:AssignmentList JSON类型:[对象,对象,对象,对象,对象]

I solved this by making sure every single property from the json object was being mapped to the typescript classes and in AssignmentsDto I added a second The object property as well as the converter, like so: 我通过确保将json对象中的每个属性都映射到typescript类来解决此问题,并在AssignmentsDto中添加了第二个object对象以及转换器,如下所示:

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

Hope this helps someone! 希望这对某人有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM