I'm consuming a SOAP webservice made by an external party. Using .net core 3.0 when I generated the soap client using svc util(by adding a connected reference) it wouldn't let me send correct messages.
So I created a client like so:
[ServiceContract(Namespace = "SomeNameSpace")]
public interface IUMService
{
[OperationContract(Action = "SendMessage", Name = "SendMessageRequest", ReplyAction = "SendMessageResponse", AsyncPattern = true)]
Task<ReturnObject> SendMessageRequestAsync(Object1 obj1, Obj2 obj2);
}
First I would just get a null response so I changed my return type to stream which gave me following error:
Start element 'SendMessageRequestResponse' from namespace 'urn:be:healthconnect:unifiedmessagingservice:1_0:common' expected.
Found element 'SendMessageResponse' from namespace
'urn:be:healthconnect:unifiedmessagingservice:1_0:common'. Line 1,
position 262.
With my very basic understanding of Soap clients the ReplyAction attribute should take care of this except it doesn't.
Related
I have a question on JAXB mapping using org.springframework.ws.server.endpoint.annotations.
I was able to generate Java domain object with provided *.xsd. The thing is after I define my endpoint with
#PayloadRoot, I have to wrap my request and response as below to successfully trigger the method and return a result:
#PayloadRoot( localPart = "PmtAuthAddRequest",
namespace = "http://*com/emb/webseries")
#ResponsePayload
public JAXBElement billPayment(#RequestPayload JAXBElement var1){
PmtAuthAddResponseType response=billPaymentHandler.execute(var1.getValue());
return of.createPmtAuthAddResponse(response); // Used ObjectFactory to create JAXBElement.
}`
`
From all the tutorial I see, they dont need to wrap it as JAXBElement to return the correct type, but the below code does not work for me:
`
`#PayloadRoot( localPart = "PmtAuthAddRequest",
namespace = "http://*com/emb/webseries")
#ResponsePayload
public PmtAuthAddResponseType billPayment(#RequestPayload PmtAuthAddRequestType> var1){
PmtAuthAddResponseType response=billPaymentHandler.execute(var1.getValue());
return response;
}`
`
Do you guys know why? How can I resolve this? Thanks
I tried without wrapping it as JAXBElement, but soap UI return with error message:
`no adapter for endpoint [public com.*.*.*.webseries.billpay.CustPayee50InqResponseType com.*.Endpoint.InquirePayeeEndpoint.inquirepayees(com.*.*.*.webseries.billpay.CustPayee50InqRequestType) throws javax.xml.bind.JAXBException]: Is your endpoint annotated with #Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?</faultstring>
`
Actually solved my own question....
The way to do it is to add #XmlRootElement under generated Java class from JAXB2 with below to correctly mapping:
#XmlRootElement(namespace = "http://..*/emb/webseries",name = "CustPayee50InqRequest")
The name should match with the localPart provided name from #PayloadRoot.
Added both for request and response makes it work for me
I'm migrating an application from NancyFx to Kestrel in ASP.NET Core 6.
In Nancy, you could specify the Accept value in the URI. For example, these Uris:
http://localhost:5000/my/resource.json
http://localhost:5000/my/resource.protobuf
http://localhost:5000/my/resource.xml
Would be the equivalent of setting the Accepts header to application/json, application/protobuf or application/xml respectively.
Does this exist in Kestrel? I remember finding one example, long ago, of regex-ing the route and doing it somewhat manually. But
I can't find that post again, and
If I have to do that, I'm not sure I want to :)
Is there a way to configure this behavior in ASP.NET Core 6?
The object returned from my handler in the controller is already capable of being serialized to json/xml/whatever. I just need to check the URI to set the content-type of the response so the correct formatter will be invoked.
At the moment, I have a client that will speak to both Nancy and Kestrel and it was written to use the URI to get the type. I'm fine to rewrite/update the client so it will use the Accept header. But getting the URI method to work will make the initial integration easier and a refactor to use the headers can come next.
I created a very simple middleware that reads the accept value from the query string and sets the Accept header to the request:
public class AcceptHeaderFromQueryString
{
private readonly RequestDelegate _next;
public AcceptHeaderFromQueryString(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var accept = context.Request.Query["accept"];
if (!string.IsNullOrEmpty(accept))
{
context.Request.Headers.Accept = accept;
}
await _next(context);
}
}
Register the middleware:
app.UseMiddleware<AcceptHeaderFromQueryString>();
I added [Produces(MediaTypeNames.Application.Json, MediaTypeNames.Application.Xml)] attribute to my api controller action (this step is not required):
[HttpGet]
[Produces(MediaTypeNames.Application.Json, MediaTypeNames.Application.Xml)]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
Finally I added support for xml serialization in Program.cs:
builder.Services.AddControllers()
.AddXmlDataContractSerializerFormatters();
Then I tried these urls and they both gave appropriate response:
https://localhost:7258/weatherforecast?accept=application/json
https://localhost:7258/weatherforecast?accept=application/xml
You possibly want the [Consumes] attribute. This allows you to specify a controller action that only gets called from a route of the specified content type.
Obviously this is not using the Accepts header but the content type of the request.
I am trying to upload Array of Multipart file object using feign client.
This is the service am trying to call using Feign client.
public ResponseEntity<Object> manageFileUpload(#RequestParam("files") MultipartFile[] files)
I tried using,Feign client Annotation,
#FeignClient(value = "UPLOADUTILITIES", configuration = Upload.MultipartSupportConfig.class, fallback = UploadFallback.class)
My Method,
#RequestMapping(name = "upload", value = "/object", method = RequestMethod.POST)
#Headers("Content-Type: multipart/form-data")
ResponseEntity<Object> manageFileUpload(#Param("files") MultipartFile[] files);
I was rewarded by the error,
"message": "Type definition error: [simple type, class java.io.FileDescriptor]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile[0]->org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile[\"inputStream\"]->java.io.FileInputStream[\"fd\"])",
Then by referring this link.I tried in my client side, the blow code.
public class MultipartSupportConfig {
#Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
#Bean
public Encoder feignFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
Then by the code example, i changed my MultiPart File object into File Object.Now my request got fired, but i got Not a multipart request.
I tried this https://github.com/pcan/feign-client-test#feign-client-test,
I created a class and used the encoder class, and changed my encoder as FeignSpringFormEncoder,
Still I am getting No serializer found error.
Could anyone share a simple client, server example with Array of Multipart file request, using feign cleint. Thanks!
I am developing a plugin for nexus oss .My app creates a rest call response(to a request from server) . But when the server receives it , it throws error as follows
javax.xml.bind.UnmarshalException:
unexpected element (uri:"", local:"com.collabnet.teamforge.ia.types.GetConfigurationParametersResponse").
Expected elements are
\lt{http://www.collab.net/teamforge/integratedapp}CreateProjectConfigurationRequest\gt,
\lt{http://www.collab.net/teamforge/integratedapp}GetConfigurationParametersRequest\gt,
\lt{http://www.collab.net/teamforge/integratedapp}GetConfigurationParametersResponse\gt,
\lt{http://www.collab.net/teamforge/integratedapp}GetPageComponentParametersRequest>
I guess the reason behind this exception is that the response doesn't match with the expected because the uri ( this is just my guess , if it's wrong please correct me),that is the namespace in response is not set .
snip of the Code in my plugin is as follows
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"configurationParameter"
})
#XmlRootElement(name = "GetConfigurationParametersResponse", namespace = "http://www.collab.net/teamforge/integratedapp")
public class GetConfigurationParametersResponse
extends BaseResponse
{
Why is name space not picked up while creating response ?
Even correct me if the real reason for the exception is not the empty uri. If so what is the real reason behind this exception ?
Please help .
Based on the error message the XML document being passed to JAXB is. It appears as though this XML is being created by something other than JAXB (I suspect XStream).
<com.collabnet.teamforge.ia.types.GetConfigurationParametersResponse>
...
</com.collabnet.teamforge.ia.types.GetConfigurationParametersResponse>
Your JAXB mappings are expecting an XML document like the following:
<GetConfigurationParametersResponse xmlns="http://www.collab.net/teamforge/integratedapp">
...
</GetConfigurationParametersResponse>
If you need to interact with the following XML:
<com.collabnet.teamforge.ia.types.GetConfigurationParametersResponse>
...
</com.collabnet.teamforge.ia.types.GetConfigurationParametersResponse>
Then you can change your mapping to be:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"configurationParameter"
})
#XmlRootElement(name = "com.collabnet.teamforge.ia.types.GetConfigurationParametersResponse")
public class GetConfigurationParametersResponse
extends BaseResponse
{
I am wishing to serialize a complex object for returning from a web service request. Here are my assumptions. I need to have the serialized (deflated) object in an XML document (as opposed to a string) before returning to the calling client. I "believe" I am deserializing just fine it is just a matter of getting it loaded into the XMLDocument. However I could be wrong and the deserialization may be wrong therefore the XmlDocument blows up. Here is the code:
My Complex Object:
namespace ABCTest
{
[XmlRoot("TapRoot")]
public class UserDetails
{
[XmlElement]
public String AccountName { get; set; }
}
}
My serialization code:
FYi: UsrDtls == List<UserDetails>
XmlSerializer Obj2XML = new XmlSerializer(UsrDtls.GetType());
Stream strWriter = Stream.Null;
XmlWriter XWriter = new XmlTextWriter(strWriter, Encoding.Unicode);
XmlDocument XDoc = new XmlDocument();
Obj2XML.Serialize(XWriter, lst_Exercises);
string abc = Obj2XML.ToString(); //debugging line to attempt to browse the obj2xml object
XDoc.LoadXml(abc);
return XDoc;
I have no idea where you learned about web services in .NET. Just return the object. The web service infrastructure will take care of it.
You don't say whether you're using WCF services or the legacy ASMX services. The ASMX services should not be used for new development.
If you still have trouble when you "just return it", then please post the details of any exceptions you receive.