Servicestack JsonClient - Object reference not set to an instance of an object - servicestack

We have a basic servicestack frontend that sends using the jsonclient to backend services and works for the past few years.
I am trying to investigate why we are receiving the below exception on any frontend JSON Client.get requests,
System.NullReferenceException
Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Collections.Specialized.NameObjectCollectionBase.BaseGetAllKeys()
at System.Collections.Specialized.NameValueCollection.get_AllKeys()
at ServiceStack.PclExportClient.AddHeader(WebRequest webReq, NameValueCollection headers)
at ServiceStack.ServiceClientBase.PrepareWebRequest(String httpMethod, String requestUri, Object request, Action`1 sendRequestAction)
at ServiceStack.ServiceClientBase.SendRequest(String httpMethod, String requestUri, Object request)
at ServiceStack.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request)
at ABC.api.InitializationService.Any(InitializationRequest request) in C:\.....\api\InitializationService.cs:line 27
It's strange, and i'm trying to reproduce this issue by hitting the breakpoint, and nulling / modifying the headers, but can't reproduce or figure out what this issue is.
To me, doesn't the exception imply the header base keys are null, and it can't be retrieved - but how does that occur ?
Using ServiceStack 5.80
ASP.NET MVC
.Net Framework 4.6.1
EDIT:
Calling line of code that produces this issue is
var deviceResult = client.Get(new DRequest{ U = r.D });

Related

Azure Functions .NET 5 Isolated HttpTrigger Path Variable Input Binding

I'm just trying to figure out how to do something in .NET 5 that worked in 3.1 and before.
In 3.1, the route variable binds correctly to the Guid parameter of the same name:
[FunctionName("Function1")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "records/{clientId:Guid}")] HttpRequest req,
Guid clientId,
ILogger log)
{
return new OkObjectResult(clientId);
}
A comparable .NET 5 version of this same function fails to bind the path variable:
[Function("Function1")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = "records/{clientId:Guid}")] HttpRequestData req,
Guid clientId,
FunctionContext executionContext)
{
var response = req.CreateResponse(HttpStatusCode.OK);
response.WriteString(clientId.ToString());
return response;
}
The error that is thrown is as follows:
Exception:
Microsoft.Azure.Functions.Worker.Diagnostics.Exceptions.FunctionInputConverterException:
Error converting 1 input parameters for Function 'Function1': Cannot
convert input parameter 'clientId' to type 'System.Guid' from type
'System.String'.
I can change the type of the parameter to string and then parse it into a Guid after the fact, of course, but I'd like to know if it's still possible to do it the aforementioned way.
There are two things:
Why isn't the route constraint taken into account (i.e. why does a conversion need to occur)
I found a related git issue. That doesn't seem to be fixed, though it makes me wonder how you managed to make it work with .NET Core 3.1 :)
Why isn't the input string automatically converted to a Guid
I had a look at the code to understand where the exception is raised.
The model binding is using a list of IConverter to convert between the input type and the binding type. In your case, the input type is string and the binding type is Guid, and there's no built-in converter that can do that. You can't even create your own IConverter, because it's an internal interface.
Note: here's an example of IConverter that converts a string to a byte array: StringToByteConverter
So basically, there's nothing you can do apart from your suggestion to parse the Guid yourself.

Why am I getting javax.xml.bind.UnmarshalException when calling a soap web service

I am trying consume a SOAP web Service and I have written my SOAP client using Spring-ws. This also included a message signing. However when I am trying to trigger a request I am getting the exception. From the server standpoint, the server is sending a successful response but I am not able to unmarshall it.
I followed quite a few suggestion including one from this
UnmarshallingFailureException, unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault")
Following the above link however removed the exception but in turn I am getting a null response object and I could not trace out where the response went missing.
This is my Config class methods:
public WebServiceTemplate accountsInquiryWebServiceTemplate() throws Exception {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
Jaxb2Marshaller accountsInquiryMarshaller = accountsInquiryMarshaller();
webServiceTemplate.setMarshaller(accountsInquiryMarshaller);
webServiceTemplate.setUnmarshaller(accountsInquiryMarshaller);
ClientInterceptor[] clientInterceptors = new ClientInterceptor[1];
clientInterceptors[0] = wsClientSecurityInterceptor();
webServiceTemplate.setInterceptors(clientInterceptors);
webServiceTemplate.setCheckConnectionForFault(true);
webServiceTemplate.setDefaultUri(serviceURL);
return webServiceTemplate;
}
private Jaxb2Marshaller accountsInquiryMarshaller() {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPaths(new String[]{
"com.accounting.integrationservice"
});
return jaxb2Marshaller;
}
private Wss4jSecurityInterceptor wsClientSecurityInterceptor() throws Exception {
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions("Signature");
wss4jSecurityInterceptor.setSecurementUsername(username);
wss4jSecurityInterceptor.setSecurementPassword(password);
wss4jSecurityInterceptor.setSecurementSignatureCrypto(clientCrypto());
wss4jSecurityInterceptor.setValidationActions("Signature");
return wss4jSecurityInterceptor;
}
private Crypto clientCrypto() throws Exception {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
cryptoFactoryBean.setKeyStoreLocation(resourceLoader.getResource("classpath:accountsInquiry/keystore/" + keyStoreLocation));
cryptoFactoryBean.setKeyStorePassword(keyStorePassword);
cryptoFactoryBean.afterPropertiesSet();
return cryptoFactoryBean.getObject();
}
The client calls as below:
Response response = accountsWebServiceTemplate.marshalSendAndReceive(request);
The exception stack that I am getting is as below : Its similar to the referred link above, so not putting the entire exception stack
org.springframework.ws.soap.security.AbstractWsSecurityInterceptor.handleResponse(AbstractWsSecurityInterceptor.java:247)
- Could not validate request: No WS-Security header found
org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault"). Expected elements are http://www.qualityaccounts.com/IntegrationService/schemas/ProductInfo/v1}
at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:911)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:784)
at org.springframework.ws.support.MarshallingUtils.unmarshal(MarshallingUtils.java:62)
at org.springframework.ws.client.core.WebServiceTemplate$3.extractData(WebServiceTemplate.java:413)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:619)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
Ok So, I was trying to use "Signature" to validate the Security Header of the response even though there was no header. But thing is if I didn't specify the ValidationAction it was throwing NullPointerException so it was expecting at least one ValidationAction.
To counter all this I told the Spring security not to validate the response by this piece of code.
wss4jSecurityInterceptor.setValidateResponse(false);
Thanks to this article
Spring Security - Wss4jSecurityInterceptor - Nullpointer

ServiceStack: SerializationException

I am testing the api created using ServiceStack using SoapUI and when I try to send the required DataMember thru headers, the api returns the correct values. When I try to send the required DataMember thru Body, I am getting the below error... Please help
Request sent through the body
<GetProductDetailsReq>
<AToken>ck0b0YYBPkrnVF/j6e16DUPzxLX2SMCXewoR4T</AToken>
</GetProductDetailsReq>
POST http://localhost/ServiceStackAPI/GetProductDetails HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/xml
Accept: application/xml
Content-Length: 777
Host: localhost
Proxy-Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Response Status
Error Code
SerializationException Message
Could not deserialize 'application/xml' request using ServiceModel.DTO.GetProductDetailsReq' Error:
System.Runtime.Serialization.SerializationException: Error in line 1
position 66. Expecting element 'GetProductDetailsReq' from namespace
''.. Encountered 'Element' with name 'GetProductDetailsReq', namespace
'http://schemas.servicestack.net/types'. at
System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator
xmlReader, Boolean verifyObjectName, DataContractResolver
dataContractResolver) at
System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator
reader, Boolean verifyObjectName, DataContractResolver
dataContractResolver) at
System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader
reader) at
System.Runtime.Serialization.XmlObjectSerializer.ReadObject(Stream
stream) at ServiceStack.Text.XmlSerializer.DeserializeFromStream(Type
type, Stream stream) at
ServiceStack.WebHost.Endpoints.Support.EndpointHandlerBase.CreateContentTypeRequest(IHttpRequest
httpReq, Type requestType, String contentType) Stack Trace
at ServiceStack.WebHost.Endpoints.Support.EndpointHandlerBase.CreateContentTypeRequest(IHttpRequest
httpReq, Type requestType, String contentType) at
ServiceStack.WebHost.Endpoints.RestHandler.GetRequest(IHttpRequest
httpReq, IRestPath restPath) at
ServiceStack.WebHost.Endpoints.RestHandler.ProcessRequest(IHttpRequest
httpReq, IHttpResponse httpRes, String operationName)
Check the SOAP Limitations to ensure you're creating Services that can be sent in SOAP, i.e. If the Request DTO is called GetProductDetails then it must return a Response DTO called GetProductDetailsResponse. Also you need to ensure your DTO's have [DataContract] on all types and [DataMember] on all public properties and that your DTO's are in a single namespace.
The other issue with this request is that you're using the SOAP requests to wrong endpoint address. i.e. The SOAP endpoint is either /soap11 or /soap12. In the above example it's attempting to send it to the /GetProductDetails custom HTTP route, when for SOAP it needs to be either /soap11 or soap12.
If you did just want to just send XML over HTTP then you should just send the raw XML payload which you can find out what it looks like by serializing the Request DTO, e.g:
string requestXml = new GetProductDetails { ... }.ToXml();
Which you can easily send with HTTP Utils:
var responseXml = "http://localhost/ServiceStackAPI/GetProductDetails"
.PostXmlToUrl(xmlRequest);
var responseDto = responseXml.FromXml<GetProductDetailsResponse>();
Assuming you have a [Route("/GetProductDetails")] defined on the GetProductDetails Request DTO.

HttpClient response ReadAsAsync() doesn't fully deserialize object

I'm trying to consume a web service with the Web API client library. My problem is that the ReadAsAsync doesn't seem to want to fully deserailize the returned object when the submitting function uses a POST method.
If I get the response as a string and manually deserailize it works. (I get a apmsgMessage with all the fields populated)
HttpClient client = GetClient();
var response = client.PostAsJsonAsync("api/robot/Preview", ad).Result;
var msg = response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<apmsgMessage>(msg.Result);
I originally tried the code below which returns an apmsgMessage Object, but all the fields are null.
HttpClient client = GetClient();
var response = client.PostAsJsonAsync("api/robot/Preview", ad).Result;
var msg = response.Content.ReadAsAsync<apmsgMessage>().Result;
return msg;
My question is why dosn't my orginal (the PostAsJsonAsync) return a apmsgMessage fully populated. Am I doing somethign wrong with the ReadAsAsync?
I just had the same issue, and in my case I solved it by removing the [Serializable] attribute from the class.
I don't know why this attribute conflicts with the deserialization process, but as soon as I took that out, the ReadAsAsync method worked as expected.

How can I get GWT RequestFactory to with in a Gadget?

How can I get GWT RequestFactory to with in a Gadget?
Getting GWT-RPC to work with Gadgets is explained here.
I'm looking for a analogous solution for RequestFactory.
I tried using the GadgetsRequestBuilder, so far I've managed to get the request to the server using:
requestFactory.initialize(eventBus, new DefaultRequestTransport() {
#Override
protected RequestBuilder createRequestBuilder() {
return new GadgetsRequestBuilder(RequestBuilder.POST,
getRequestUrl());
}
#Override
public String getRequestUrl() {
return "http://....com/gadgetRequest";
}
});
But I end up with the following error:
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(String.java:694)
at com.google.gwt.autobean.server.impl.JsonSplittable.create(JsonSplittable.java:35)
at com.google.gwt.autobean.shared.impl.StringQuoter.split(StringQuoter.java:35)
at com.google.gwt.autobean.shared.AutoBeanCodex.decode(AutoBeanCodex.java:520)
at com.google.gwt.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:121)
The general approach for sending a RequestFactory payload should be the same as RPC. You can see the payload that's being received by the server by running it with the JVM flag -Dgwt.rpc.dumpPayload=true. My guess here is that the server is receiving a request with a zero-length payload. What happens if you set up a simple test involving a GadgetsRequestBuilder sending a POST request to your server? Do you still get the same zero-length payload behavior?

Resources