Why is The XML Serializer appending characters to my XmlAttribute? - c#

Here is my property:
/// <summary>
/// The Business Unit
/// </summary>
[XmlAttribute("ows_Business_x0020_Unit")]
public string BusinessUnit { get; set; }
When I call Serialize on the object that has BusinessUnit I get:
ows_Business_x005F_x0020_Unit=\"Hi\"
Where does the _x005F come from?

It's an escape sequence. The _x0020 is actually another escape sequence for a space, so it's trying to escape the escape sequence so it doesn't get confused that you literally want the escape sequence, not the unescape value. So your attribute should look like this:
public class MyClass
{
[XmlAttribute("ows_Business Unit")]
public string BusinessUnit { get; set; }
}
That will serialize the attribute as ows_Business_x0020_Unit.

Microsoft encodes certain characters as _xZZZ_, so any names that look like _xZZZ_ get escaped. They chose to handle this by searching for "_x" and encoding the underscore as _x005F.
Your life will be easier if you avoid including "_x" in any of your names.

Related

Control format of Guid using xml serializer

I have a problem controlling how the xml serializer formats a Guid.
is there anyway to force the property of the first example to exclude the dashes, using the XmlSerialzer?
example:
public class Example{
[XmlElement]
public Guid Value {get; set;}
}
when serializing the above class i would get: (36 characters)
<Example>
<Value>3164fc09-1dc5-4629-b04c-e9cdc5e85de4</Value>
</Example>
but i want the value not to include dashes (32 characters)
<Example>
<Value>06102471381242609d0176b269120082</Value>
</Example>
normally i would not care about the difference, but in this particular case i don't have a choice as i have to follow a standard provided by a third party that includes a set of xsd's.
I know i can do something like this to solve the problem, but it is messy and i would like to avoid it:
public class Example
{
[XmlIgnore]
public Guid Value { get; set; }
[XmlElement(nameof(Value))]
public string ValueString {
get => Value.ToString("N");
set
{
if (Guid.TryParse(value, out var uuid))
Value = uuid;
else
throw new InvalidOperationException();
}
}
}
Provided xsd
the xsd provided by this company define the custom type to be a string with a range of 1 to 35 characters, but their documentation states that the value should always be a uuid version 4 with no dashes and 32 characters long.
the documentation provided only have a danish version.
See page 5 sekt 01.07.2016 UUID i EpisodeOfCareIdentifier for the specific problem.
about the standard (optional reading):
This standard is part of a message service between counties, hospitals and other independent healthcare specialists, regarding patient treatments.
All in all there is quite a few software systems that have to implement this standard.

Aspnet Mvc decimal serialization error

I have a post method that accepts object containing decimal property as below
[HttpPost]
public async Task<IActionResult> Create(CreateDto createDto)
{
...do stuff here
}
public class CreateDto
{
[Required]
public string Id{ get; set; }
[Required]
public decimal? Rate{ get; set; }
}
when a value containing leading 0 being passed in for Rate field, eg: 0015, it is always coming in as 10.
Would appreciate if somebody could explain this phenomena.
The issue lies within aspnet core mvc JSON parser which allows leading zeros before numbers that are all in the range [0-7], and treats them as octal, to match the sort of results one would get using eval in javascript.
This behaviour contradicts with guildlines stated in on http://json.org:
"A number is very much like a C or Java number, except that the octal
and hexadecimal formats are not used."
and the syntax graph does not allow a number to have a leading non-significant zero.
RFC 4627 Section 2.4. agrees:
"Octal and hex forms are not allowed. Leading zeros are not allowed."
So in short, the only way is to use JSON parser that implements the Json specs correctly.
Reference: Override Json deserializing a number with a leading zero as a decimal and not an octal value

XML special character escape not working

I'm trying to use the "!" special character in my C# class but my xml doesn't result in this "!MovieName" instead it results in " _x0021_MovieName "
I have tried to &#x21 ; and also use CDATA but they dont work. They turn into a string of more x0021 (an example) types for each special character.
public class Movie
{
[XmlElement("!MovieName")]
public string Title
{ get; set; }
[XmlElement("MovieRating")]
public float Rating
{ get; set; }
[XmlElement("MovieReleaseDate")]
public DateTime ReleaseDate
{ get; set; }
}
An XML element name cannot begin with a ! which is why it's being replaced.
You should be able to start with:
Any letter
Underscore _
Colon :
See the XML Spec for more information, or more specifically the section on NameStartChar.
It's illegal to have a ! as the opening character of a tag in XML. You'll just have to use a different naming strategy.

MVC4 Class Data Annotations - How to check that field does not equal a given string?

Hopefully that title made sense. Essentially I want to set up validation using Data Annotations in a class that will fail if one the fields (call it Field1 for example) equals a given string (i.e. "abc").
For example
public class myClass
{
[Required]
public string Filed1 {get;set;} //*** I want validation to fail if this string equals "abc"
}
Hope that all makes sense. Any ideas?
Thanks
You can use RegularExpression attribute for this:
[RegularExpression("^(?!abc$).*$")]
The regex is a negative lookahead (basically checking that string does not start with abc followed by string end), and then allowing any other sequence.

String comparison assertion failing when it looks like it should pass

I have a test for checking that an item is serialized correctly
public interface IMyJsIdentity
{
string Forename { get; }
string Surname { get; }
string Guid { get; }
}
public class MyIdentity : IMyJsIdentity
{
public string Forename { get; set; }
public string Surname { get; set; }
public string Guid { get; set; }
public int Id { get; set; }
}
[Fact]
public void SerialiseCorrectly()
{
// Arrange
MyIdentity identity = new MyIdentity()
{
Forename = "forename",
Surname = "surname",
Guid = "abcdefghijk"
};
// Act
string result = JsonConvert.SerializeObject(
identity,
new JsonSerializerSettings()
{
ContractResolver = new InterfaceContractResolver(typeof(IMyJsIdentity))
});
// Assert
result.Should().Be(
"{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}"
);
}
However I get the following error on the test failure
Xunit.Sdk.AssertException: Expected string to be
"{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}" with a length of 66, but
"{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}" has a length of 64.
There's clearly something special that Json.net is doing to the string but I can't figure out what.
Weirdly this passes
result.Should().Be(
String.Format("{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}")
);
I guess it's not a big deal but I'd like to know why.
I just tested and the value of result is:
{"Forename":"forename","Surname":"surname","Guid":"abcdefghijk","Id":0}
Which will naturally fail against your expected string of:
"{{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}}"
Using double curly braces is an escape sequence only for format strings used in the String.Format method so that you may include a single brace. From the Composite Formatting MSDN page:
Opening and closing braces are interpreted as starting and ending a
format item. Consequently, you must use an escape sequence to display
a literal opening brace or closing brace. Specify two opening braces
("{{") in the fixed text to display one opening brace ("{"), or two
closing braces ("}}") to display one closing brace ("}").
If you aren't using String.Format, then the double brace will be interpreted literally as two braces as per the C# Specification 2.4.4.5 since it is not an escape character for string literals.
The resultant error message is confusing. I'm not sure if this is because how the debugger is reporting it to the GUI, or an error with how they are formatting their error message (perhaps they are overly aggressive escaping braces for output), or what.
If you change your test to be:
result.Should().Be(
"{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}"
);
Then it will pass I suspect. This is backed up by your additional test using the String.Format call which changes your double braces to single braces. Now, if you intended to have double wrapping braces around your JSON, that's another issue entirely, but I suspect that that isn't your intent.

Categories

Resources