dymosoftware / dymo-connect-framework

DYMO Connect Framework for Javascript.
Other
88 stars 54 forks source link

Broken XML sent to print service in case of DCD labels only #13

Open grezniczek opened 3 years ago

grezniczek commented 3 years ago

When using the label.render or label.print methods, or in general when using the label.getLabelXml method to get the XML for a label, or after doing any DOM operation on the XML and using any serializer, and using it together with dymo.label.framework.printLabel, the DYMO Connect Service will responds with a 500 error:

{"message":"An error has occurred.","exceptionMessage":"'Element' ist ein ungültiger XmlNodeType. Zeile 22, Position 4.","exceptionType":"System.Xml.XmlException","stackTrace":"   
   bei System.Xml.XmlReader.ReadEndElement()
   bei DYMO.LabelAPI.DYMOLabel`1.Deserialize(XmlReader reader)
   bei DYMO.CrossPlatform.Common.Helpers.SerializationHelper.Deserialize[T](XmlReader reader)
   bei DYMO.LabelAPI.LabelHelper.ReadAndOpenLabel(XmlReader reader)
   bei DYMO.LabelAPI.LabelHelper.OpenLabel(XmlReader reader)
   bei DymoSDK.Implementations.DymoLabel.LoadLabelFromXML(String xmlContent)
   bei DYMOWebApi.Windows.Controllers.DymoDLSSDKController.RenderLabel(FormDataCollection formDataCollection)
   bei lambda_method(Closure , Object , Object[] )
   bei System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters)
   bei System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
   bei System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   bei System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   bei System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   bei System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"}: Internal Server Error
    at ajaxSync (dymo.connect.framework.js?1614357232:2)
    at invokeWsCommand (dymo.connect.framework.js?1614357232:2)
    at DlsWebService.renderLabel (dymo.connect.framework.js?1614357232:2)
    at Object.renderLabel (dymo.connect.framework.js?1614357232:2)
    at Object.dymo.label.framework.renderLabel (dymo.connect.framework.js?1614357232:2)
    at previewLabel (dlem.js?1614711352:1005)

Feeding the XML sent in the request to the DYMO Connect Service into the DYMO Connect desktop application, this crashes, too!

The issue appears to be due to the empty element shorthand when used for specific elements: <Color .... /> cannot be digested, it must be <Color ...></Color> And in <DataTable>, <Columns /> must be <Columns></Columns> and <Rows /> must be <Rows></Rows>

Interestingly, the empty element shorthand syntax is acceptable for DYMOThickness in Margin.

Thus, in order to get DCD labels working, I needed to "fix" the XML before passing it to the renderLabel/printLabel functions.

label.print() and label.render() are not fixable this way. YOU need to do that in the framework (it would not hurt though to update the desktop app and print service to better handle XML parsing, and maybe not to crash but handle errors more graceful).

This cost me a lot of time :(

esb commented 3 years ago

I can confirm that this is an issue as I've encountered it myself.

I was unable to get the printing using DieCutLabel template working properly, even though it worked perfectly under the previous DLS software.

I decided to try the newer templates, but this has caused massive issues as well.

When you load an XML template via a openLabelXML call, then set the address using the setAddressText you end up with a template that's unprintable and generates the error described above. In fact, you can see this by capturing the XML from the getLabelXML call. The XML generated uses short-hand closing tag syntax, but the print functions do not support this. Kind of like the left hand not knowing what the right hand is doing.

In the end, I've skipped the setAddressText process altogether as it's busted, and just replace key values in my own template which hasn't been modified by the framework.

Please, can these bugs be fixed. The software is defective as it stands. We have major functions not working, so I'm wondering what sort of test cases were run to validate the software.

kallotec commented 3 years ago

Am also having the same problems as the above people, I'm running the latest Dymo Connect software 8.7.3 and using the PreviewAndPrintLabel sample code from github. Please fix.

devon94 commented 3 years ago

I also ran into this issue, I ended up hacking it to partially work by using DOMParser to read the XML content and add closing tags to the broken elements. That solution seemed to work for DCD/DLS labels using Connect but was broken using the old label software. Here's the code if anyone is interested https://github.com/devon94/dymo-connect-xml-fix/blob/main/src/index.ts

Also mentioned a while ago here that it would be fixed but I see no updates https://github.com/dymosoftware/dymo-connect-framework/issues/10

giuliodamato commented 3 years ago

It seems that the issue is related to the XMLSerializer.serializeToString() method.

As stated in https://w3c.github.io/DOM-Parsing/#xml-serialization Elements not in the HTML namespace containing no children, are serialized using the empty-element tag syntax (i.e., according to the XML EmptyElemTag production)..

This means that, in compliance with its specification, the XMLSerializer.serializeToString() method returns <tag/> instead of <tag></tag> in case of an empty tag.

The problem is that the DYMO Connect Service APIs doesn't comply with the empty-element tag syntax. What's even more interesting was reading to dymosoftware/DCD-SDK-Sample#28 where @mbmleone observed that the issue doesn't occur when the label is opened using OpenLabelFile!

The reason for this is that OpenLabelFile requests the label's content through the DYMO Connect Service APIs which conveniently introduces a space into the empty tags ... forcing the XMLSerializer.serializeToString() method not to return new tags following the empty-element syntax.

However, the same trick has not been applied when feeding XML strings to the dymo-connect-framework. @dymosoftware: in the end the solution is quite straightforward and I'm planning to release it tomorrow 😊

ps. I don't work for DYMO!

giuliodamato commented 3 years ago

Guys, I released a fixed (?) version of the framework at https://github.com/giuliodamato/dymo-connect-framework 😉

The problem seems to be all about the management of Color elements, they MUST be in the form <Color></Color>. I just make sure that what dymo.xml.serialize returns doesn't contain a self-closing Color element.

dymo.xml.serialize = function (e) {
    function fix (e) {
        return e.replaceAll(/<Color([^\/]+)?\/>/g, "<Color$1> </Color>");
    }   

    return fix(goog.dom.xml.serialize(e))
}

Interestingly enough, not every element works well converting it in the <tag></tag> form, this could be what gave problems to @devon94. For example, DYMOThickness MUST follow the empty-element tag syntax ... whereas other elements work in both ways.

By the way, the DYMO Connect Service APIs introduces a space just into the Color elements, so I think we can assume that the above solution is correct.

Please, make some tests and let me know ... ok? 😊 Cheers!

EDIT: I just improved the fix with a better regex 😉

cage85 commented 2 years ago

@giuliodamato thanks, this fix indeed works! Did you create a PR for this in the master branch?

giuliodamato commented 2 years ago

@giuliodamato thanks, this fix indeed works! Did you create a PR for this in the master branch?

hi @cage85, I'm glad the fix worked for you too 😊 I was actually waiting for a comment from @dymosoftware before creating the PR!

cheers ✌

dymosoftware commented 2 years ago

Hi @giuliodamato, feel free to create the PR. Thanks.

dp-sgr commented 2 years ago

Hello, the fix from https://github.com/dymosoftware/dymo-connect-framework/pull/34/files works. But the current Dymo Connect Framework is not working for us. We have changed the fix() function back to the PR one:

image

@dymosoftware This worked for our Software. Why has the fix been changed to the current behavior?

giuliodamato commented 2 years ago

Hello, the fix from https://github.com/dymosoftware/dymo-connect-framework/pull/34/files works. But the current Dymo Connect Framework is not working for us. We have changed the fix() function back to the PR one:

image

@dymosoftware This worked for our Software. Why has the fix been changed to the current behavior?

I don't really know why they changed it ... of course I implemented a quick fix but it did work! 😅 The problem with the bugged one seems that it doesn't support <Color/> as a tag ...