locked
Posting XML issue RRS feed

  • Question

  • User-1458727574 posted

    In my controller, I have a function that takes the incoming XML and deserialises it to an object. Here is the function definition:

            // POST api/<controller>
            [HttpPost("")]
            public string Post([FromBody] billingDataEntity billingData, [FromQuery] string s = "")
            {

    It also picks up a string from the query string. If the client posts XML that doesn't match the XSD from which the class was generated, the API bombs out with an internal server error. I can't even put in a try/catch block because it fails at the point of calling the function. Any idea how I can gracefully catch that and return a response? Can't seem to find a way to do it.

    Monday, October 8, 2018 1:06 PM

All replies

  • User283571144 posted

    Hi AnyUserNameThatLetsMeIn,

    I can't even put in a try/catch block because it fails at the point of calling the function. Any idea how I can gracefully catch that and return a response?

    According to your description, I have created a test demo on my side, it could access the controller's action.

    Could you please share the billingDataEntity codes, xml, xsd example?

    Could you please share the details error message?

    If you could post more details information, it will be more easily to reproduce the issue and find out the solution.

    Best Regards,

    Brando

    Tuesday, October 9, 2018 7:09 AM
  • User-1458727574 posted

    The controller is one of about 20 in the API I'm writing and they will all do the same when presented with the wrong XML. If I put a break point on that function, if the function receives the wrong XML it will just bomb out and it gives an internal server error before I can do anything. The error is an internal server error. It won't even go passed the first line because the endpoint is the function definition. The XML parser tries to deserialise the XML against the XSD. If the XML is valid, great. If I deliberately provide the wrong XML to the endpoint, it just errors before I can catch it. I don't need to provide the XML or the XSD. Just use any XML and XSD from the web, and then when you send a request to the endpoint with XML that is totally incorrect, it will generate the error.

    An unhandled exception occurred while processing the request.
    
    InvalidOperationException: <BillingData xmlns=''> was not expected.
    Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderachStatement.Read35_Statement()
    
    InvalidOperationException: There is an error in XML document (1, 14).
    System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, string encodingStyle, XmlDeserializationEvents events)
    
    Stack Query Cookies Headers
    InvalidOperationException: <BillingData xmlns=''> was not expected.
    Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderachStatement.Read35_Statement()
    
    Show raw exception details
    System.InvalidOperationException: <BillingData xmlns=''> was not expected.
       at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderachStatement.Read35_Statement()
    InvalidOperationException: There is an error in XML document (1, 14).
    System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, string encodingStyle, XmlDeserializationEvents events)
    System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)
    Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
    Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
    Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, object value)
    Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider+<>c__DisplayClass0_0+<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
    Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
    Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
    Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
    Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
    Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
    Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
    Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
    Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
    
    Show raw exception details
    System.InvalidOperationException: There is an error in XML document (1, 14). ---> System.InvalidOperationException: <BillingData xmlns=''> was not expected.
       at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderachStatement.Read35_Statement()
       --- End of inner exception stack trace ---
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)
       at Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
       at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
       at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)
       at Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
       at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
       at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
       at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
       at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
       at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
       at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
    Variable	Value
    s	DEVDAT
    No cookie data.
    
    Variable	Value
    Accept	*/*
    Accept-Encoding	gzip, deflate
    Authorization	Basic V0VCQVBJOkJENjcwMTg5RjFGRQ==
    Cache-Control	no-cache
    Connection	Keep-Alive
    Content-Length	89841
    Content-Type	application/xml
    Host	localhost:44316
    MS-ASPNETCORE-TOKEN	24be8c8b-1fe3-4058-b978-579f2a7dab21
    Postman-Token	766bfc04-16e2-4cec-8dd4-c6c134a33e40
    User-Agent	PostmanRuntime/7.3.0
    X-Original-For	127.0.0.1:61788
    X-Original-Proto	http

    To test I'm using Postman to push the XML to the endpoint. If I send some valid XML to the right endpoint, it is fine. If I send the same XML to the wrong endpoint, this happens but I'd rather catch the error and respond with an error message.

    Tuesday, October 9, 2018 10:08 AM
  • User283571144 posted

    Hi AnyUserNameThatLetsMeIn,

    As far as I know, validate the xml fomat method is called in the asp.net core model bind BindModelAsync method.

    If you want to try catch this exception, I suggest you could create Custom model binder to bind the xml with the model class.

    More details about how to create a  Custom model binder in asp.net core, I suggest you could refer to below article.

    https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-2.1 

    Best Reards,

    Brando

    Wednesday, October 10, 2018 6:09 AM