C# XML ModelBinding - ASP.NET Core 8 Web API - required field not found

34 views Asked by At

I want to bind this XML:

<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D='DAV:' xmlns:A='http://apple.com/ns/ical/'
    xmlns:C='urn:ietf:params:xml:ns:caldav'>
    <D:prop>
        <D:resourcetype />
        <D:owner />
        <D:displayname />
        <D:current-user-principal />
        <D:current-user-privilege-set />
        <A:calendar-color />
        <C:calendar-home-set />
    </D:prop>
</D:propfind>

to XML objects:

[XmlRoot("propfind", Namespace = DavNamepaces.davXmlNamespace)]
public class PropFindRequest()
{
    [XmlElement(ElementName = "prop", Namespace = DavNamepaces.davXmlNamespace)]
    public Properties Properties { get; set; } = null!;
}

[XmlRoot(ElementName="prop")]
public class Properties
{
    [XmlElement(ElementName="resourcetype")] 
    public object Resourcetype { get; set; } 

    [XmlElement(ElementName="owner")] 
    public object Owner { get; set; } 

    [XmlElement(ElementName="displayname")] 
    public object Displayname { get; set; } 

    [XmlElement(ElementName="current-user-principal")] 
    public object Currentuserprincipal { get; set; } 

    [XmlElement(ElementName="current-user-privilege-set")] 
    public object Currentuserprivilegeset { get; set; } 

    [XmlElement(ElementName="calendar-color")] 
    public object Calendarcolor { get; set; } 

    [XmlElement(ElementName="calendar-home-set")] 
    public object Calendarhomeset { get; set; } 
}

Program.cs:

// Add services to the container.
builder.Services
       .AddControllers(options =>
                {
                    options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();
                    options.InputFormatters.RemoveType<SystemTextJsonInputFormatter>();
                })
// Adds builder.AddXmlDataContractSerializerFormatters(); && builder.AddXmlSerializerFormatters();
       .AddXmlFormaterExtensions();

Controller:

[ApiController]
[Route("caldav/")]
public class CalDavController
{
    [AcceptVerbs("POST")]
    [ApiExplorerSettings(IgnoreApi = false)]
    [Produces("application/xml")]
    [Consumes("application/xml")]
    public async Task<IActionResult> Propfind([FromXmlBody(XmlSerializerType = XmlSerializerType.XmlSerializer)]PropFindRequest propFindRequest,[FromHeader] int Depth)
    {
        throw new NotImplementedException();
    }
}

Error:

Error: Bad Request
Response body
Download
400

One or more validation errors occurred. https://tools.ietf.org/html/rfc9110#section-15.5.1 00-e1611d29682cd7e995d256c79850082d-ebfcd416977a94a7-00 An error occurred while deserializing input data. The propFindRequest field is required.

I was expecting that the mapping works with the annotations I added.

I tried first to change the Request just to match the expectations in the Response

Trial and error request:

<?xml version="1.0" encoding="UTF-8"?>
<propFindRequest>
    <properties>
        <resourcetype>string</resourcetype>
        <owner>string</owner>
        <displayname>string</displayname>
        <currentuserprincipal>string</currentuserprincipal>
        <currentuserprivilegeset>string</currentuserprivilegeset>
        <calendarcolor>string</calendarcolor>
        <calendarhomeset>string</calendarhomeset>
    </properties>
</propFindRequest>

but it resulted in the same error, therefore I think I made a mistake but I have no clue where.

Am I missing something important?

Do I have to use DataContractSerializer? I thought that this should work out of the box with the default XmlSerializer according to MS.

0

There are 0 answers