Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation Error when adding Attribute to arguments later #66

Open
relief-melone opened this issue Oct 6, 2017 · 14 comments
Open

Validation Error when adding Attribute to arguments later #66

relief-melone opened this issue Oct 6, 2017 · 14 comments
Labels

Comments

@relief-melone
Copy link

I have a weird problem at the moment when creating an appointment. My last issues were solved pretty quick and it was more the problem of the guy behind the screen but this one leaves me completely cluess. First im setting my args like this

var args = {
        "attributes" : {
            "SendMeetingInvitations" : "SendToAllAndSaveCopy"
        },
        "SavedItemFolderId": {
            "DistinguishedFolderId": {
                "attributes": {
                    "Id": "calendar"
                }
            }
        },
        "Items" : {
            "CalendarItem" : {
                "Subject" : "",
                "Body" : {
                    "attributes" : {
                    },
                    "$value" : ""
                },
                "ReminderIsSet" : "true",
                "ReminderMinutesBeforeStart" : "30",
                "Start" : "",
                "End" : "",
                "IsAllDayEvent" : "false",
                "LegacyFreeBusyStatus" : "Busy",
                "Location" : ""
            }
        }
    };

if after that I change for example the Subject by

args.Items.CalendarItem.Subject = req.body.Subject;

everything works fine. However if Subject is not yet set in args the Validation of node-ews passes an error saying that CalendarItem has an invalid child "Subject". req.body.Subject is a normal String and yet the validation only works if I overwrite it and its already present in CalendarItem.

@kcastrotech
Copy link
Contributor

kcastrotech commented Oct 6, 2017

What happens if you try
args.Items.CalendarItem.Subject = "";

I know it's technically the same as was was declared in args, but I'm curious if that it somehow makes a difference.

Alternatively what if you did null in the args instead of ""
"Subject" : null,

@kcastrotech
Copy link
Contributor

Also, can you provide the exact error message?

@relief-melone
Copy link
Author

Unfortunately I won't have access to that machine and Exchange Server till monday. But I'll make sure to post the error message now and the one to "" and null as well then

@relief-melone
Copy link
Author

Also posted the problem on StackOveflow and got the following response. Maybe you can use that as well
https://stackoverflow.com/questions/45512348/node-js-ews-createattachment-failing-due-to-xml-parsing-error?noredirect=1#comment80197173_45512348

Yes, fixed now. I used to pass a buffer as content (Buffer.from(b64string, 'base64') so it used to fail. I am now passing the b64string itself as content without converting it to Buffer. It could be something else in your case (if you're having an issue) but there's high chance it's the content format. – Hochman7G

@relief-melone
Copy link
Author

Ok, So "" and null have the same effect. If the Subject is not previously set to something in the args and later defined this is the error message you'll receive

a:ErrorSchemaValidation: The request failed schema validation: The element 'Cale
ndarItem' in namespace 'http://schemas.microsoft.com/exchange/services/2006/type
s' has invalid child element 'Subject' in namespace 'http://schemas.microsoft.co
m/exchange/services/2006/types'. List of possible elements expected: 'When, IsMe
eting, IsCancelled, IsRecurring, MeetingRequestWasSent, IsResponseRequested, Cal
endarItemType, MyResponseType, Organizer, RequiredAttendees, OptionalAttendees,
Resources, ConflictingMeetingCount, AdjacentMeetingCount, ConflictingMeetings, A
djacentMeetings, Duration, TimeZone, AppointmentReplyTime, AppointmentSequenceNu
mber, AppointmentState, Recurrence, FirstOccurrence, LastOccurrence, ModifiedOcc
urrences, DeletedOccurrences, MeetingTimeZone, ConferenceType, AllowNewTimePropo
sal, IsOnlineMeeting, MeetingWorkspaceUrl, NetShowUrl' in namespace 'http://sche
mas.microsoft.com/exchange/services/2006/types'.
a:ErrorSchemaValidation: The request failed schema validation: The element 'Cale
ndarItem' in namespace 'http://schemas.microsoft.com/exchange/services/2006/type
s' has invalid child element 'Subject' in namespace 'http://schemas.microsoft.co
m/exchange/services/2006/types'. List of possible elements expected: 'When, IsMe
eting, IsCancelled, IsRecurring, MeetingRequestWasSent, IsResponseRequested, Cal
endarItemType, MyResponseType, Organizer, RequiredAttendees, OptionalAttendees,
Resources, ConflictingMeetingCount, AdjacentMeetingCount, ConflictingMeetings, A
djacentMeetings, Duration, TimeZone, AppointmentReplyTime, AppointmentSequenceNu
mber, AppointmentState, Recurrence, FirstOccurrence, LastOccurrence, ModifiedOcc
urrences, DeletedOccurrences, MeetingTimeZone, ConferenceType, AllowNewTimePropo
sal, IsOnlineMeeting, MeetingWorkspaceUrl, NetShowUrl' in namespace 'http://sche
mas.microsoft.com/exchange/services/2006/types'.

@kcastrotech
Copy link
Contributor

It looks like Subject cannot be blank:
https://msdn.microsoft.com/en-us/library/office/aa565100(v=exchg.150).aspx#Anchor_3

However your statement just now about

If the Subject is not previously set to something in the args and later defined this is the error message you'll receive

is a bit confusing. You stated in your original message:

if after that I change for example the Subject by
args.Items.CalendarItem.Subject = req.body.Subject;
everything works fine.

So does this error happen if you leave it blank ("" or null)? If so then this should be answered by definition of Subject in the MS link above.

Or does this error only happen if you set it then later change it?

@relief-melone
Copy link
Author

It just happens if i haven't previously set it. So I completely leave out Subject and define the "Items" like
var args = { "attributes" : { "SendMeetingInvitations" : "SendToAllAndSaveCopy" }, "SavedItemFolderId": { "DistinguishedFolderId": { "attributes": { "Id": "calendar" } } }, "Items" : { "CalendarItem" : { "Subject" : "", "Body" : { "attributes" : { }, "$value" : "" }, "ReminderIsSet" : "true", "ReminderMinutesBeforeStart" : "30", "Start" : "", "End" : "", "IsAllDayEvent" : "false", "LegacyFreeBusyStatus" : "Busy", "Location" : "" } } };

then

`args.Items.CalendarItem.Subject = req.body.Subject'

then ews.run

it will not work. Even though the result of console.log(args) will look exaclty the same.

@kcastrotech
Copy link
Contributor

That is interesting.

I'd suggest taking a peek at the generated XML. The way I do that is to edit \MY_NODE_PROJECT\node_modules\node-ews\node_modules\soap\lib\client.js
and add
console.log('XML:',xml);
after the
xml = "<?xml ...."
line which for me was line 263.

Try comparing the working XML to the broken XML and see if anything jumps out at you.

@relief-melone
Copy link
Author

OK. The only difference I see is the order of the tags. I'll post 2 xmls. The first one is the non-working one. The second one will work.

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:tns="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/">
  <soap:Header>
  </soap:Header>
  <soap:Body>
    <CreateItem SendMeetingInvitations="SendToAllAndSaveCopy" xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
      <SavedItemFolderId>
        <t:DistinguishedFolderId Id="calendar" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
        </t:DistinguishedFolderId>
      </SavedItemFolderId>
      <Items>
        <t:CalendarItem xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
          <t:Body BodyType="HTML">TEST</t:Body>
          <t:ReminderIsSet>true</t:ReminderIsSet>
          <t:ReminderMinutesBeforeStart>15</t:ReminderMinutesBeforeStart>
          <t:Start>2017-10-11T06:10:36.890Z</t:Start>
          <t:End>2017-10-11T07:10:48.909Z</t:End>
          <t:IsAllDayEvent>false</t:IsAllDayEvent>
          <t:LegacyFreeBusyStatus>Busy</t:LegacyFreeBusyStatus>
          <t:Location>
          </t:Location>
          <t:Subject>TEST</t:Subject>
        </t:CalendarItem>
      </Items>
    </CreateItem>
  </soap:Body>
</soap:Envelope>

Here's the working one

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:tns="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/">
  <soap:Header>
  </soap:Header>
  <soap:Body>
    <CreateItem SendMeetingInvitations="SendToAllAndSaveCopy" xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
      <SavedItemFolderId>
        <t:DistinguishedFolderId Id="calendar" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
        </t:DistinguishedFolderId>
      </SavedItemFolderId>
      <Items>
        <t:CalendarItem xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
          <t:Subject>TEST</t:Subject>
          <t:Body BodyType="HTML">TEST</t:Body>
          <t:ReminderIsSet>true</t:ReminderIsSet>
          <t:ReminderMinutesBeforeStart>15</t:ReminderMinutesBeforeStart>
          <t:Start>2017-10-11T06:10:36.890Z</t:Start>
          <t:End>2017-10-11T07:10:48.909Z</t:End>
          <t:IsAllDayEvent>false</t:IsAllDayEvent>
          <t:LegacyFreeBusyStatus>Busy</t:LegacyFreeBusyStatus>
          <t:Location>
          </t:Location>
        </t:CalendarItem>
      </Items>
    </CreateItem>
  </soap:Body>
</soap:Envelope>

Still a little bit weird that seems to be enough to fail validation.

@kcastrotech
Copy link
Contributor

kcastrotech commented Oct 11, 2017

It is picky about the order of elements so that makes sense. However it doesn't make sense that even though you've defined Subject in your args (albeit as "") that it somehow changes the order when you later set it. I have done that in several of my scripts without issue.

It's a bit off-the-wall, but can you test if maybe if setting it as ["Subject"] instead of .Subject makes a difference like so:

var args = {
	"attributes" : { "SendMeetingInvitations" : "SendToAllAndSaveCopy" },
	"SavedItemFolderId": { "DistinguishedFolderId": { "attributes": { "Id": "calendar" } } },
	"Items" : {
		"CalendarItem" : {
			"Subject" : "",
			"Body" : { "attributes" : { }, "$value" : "" },
			"ReminderIsSet" : "true",
			"ReminderMinutesBeforeStart" : "30",
			"Start" : "",
			"End" : "",
			"IsAllDayEvent" : "false",
			"LegacyFreeBusyStatus" : "Busy",
			"Location" : ""
		}
	}
};

args.Items.CalendarItem["Subject"] = "A TEST SUBJECT";

Alternatively something I've also done with success is to create a template object and then merge my args with it like this:

var _ = require('lodash'); //loadash should be installed by default as part of node-ews

var ewsArgs = { //EWS argument template with defaults
	"attributes" : { "SendMeetingInvitations" : "SendToAllAndSaveCopy" },
	"SavedItemFolderId": { "DistinguishedFolderId": { "attributes": { "Id": "calendar" } } },
	"Items" : {
		"CalendarItem" : {
			"Subject" : "",
			"Body" : { "attributes" : { }, "$value" : "" },
			"ReminderIsSet" : "true",
			"ReminderMinutesBeforeStart" : "30",
			"Start" : "",
			"End" : "",
			"IsAllDayEvent" : "false",
			"LegacyFreeBusyStatus" : "Busy",
			"Location" : ""
		}
	}
};

var args = {
	"Items" : {
		"CalendarItem" : {
			"Subject" : "MY TEST SUBJECT",
			"Body" : {"$value" : "This is a test email" },
			"Start" : "2017-10-21T18:00:00.000Z",
			"End" : "2017-10-21T19:00:00.000Z"
		}
	}
};

//This should merge args into ewsArgs, preserving ewsArgs structure
_.merge(ewsArgs,args);

ews.run("CreateItem", ewsArgs);

You can also simplify this by just merging the CalendarItem:

var _ = require('lodash'); //loadash should be installed by default as part of node-ews

var ewsArgs = { //EWS argument template with defaults
	"attributes" : { "SendMeetingInvitations" : "SendToAllAndSaveCopy" },
	"SavedItemFolderId": { "DistinguishedFolderId": { "attributes": { "Id": "calendar" } } },
	"Items" : {
		"CalendarItem" : {
			"Subject" : "",
			"Body" : { "attributes" : { }, "$value" : "" },
			"ReminderIsSet" : "true",
			"ReminderMinutesBeforeStart" : "30",
			"Start" : "",
			"End" : "",
			"IsAllDayEvent" : "false",
			"LegacyFreeBusyStatus" : "Busy",
			"Location" : ""
		}
	}
};

var args = {
	"Subject" : "MY TEST SUBJECT",
	"Body" : {"$value" : "This is a test email" },
	"Start" : "2017-10-21T18:00:00.000Z",
	"End" : "2017-10-21T19:00:00.000Z"
};

//This should merge args into ewsArgs.Items.CalendarItem, preserving ewsArgs structure
_.merge(ewsArgs.Items.CalendarItem,args);

ews.run("CreateItem", ewsArgs);

@kcastrotech
Copy link
Contributor

Just following up on this. Were you able to get it working?

@relief-melone
Copy link
Author

Yep. Ill elaborate a bit more when Im back from vacation. So much. I figured out what happens but you won't be able to change the behaviour

@kcastrotech
Copy link
Contributor

Thanks for the update!

@kcastrotech
Copy link
Contributor

@relief-melone, just a friendly reminder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants