How to fix WrongInputException in ASP.NET Core? - asp.net-core

I want to use a SOAP web service prepared by another team, used internally in my new REST API prepared in ASP.NET Core. My web service client code was scaffolded with WCF Web Service Reference Provider Tool. I cleaned up code (e.g. I changed property and method names) according to my team's naming convention.
When I send requests by my new REST API, I received WrongInputException. I checked all the parameters from an example request, all of them are in the same place in my C# code consuming scaffolded client.
I don't know what message exactly is sent by my new REST API.

In my case, the main cause of the described behavior and WrongInputException was premature refactoring. I changed the names of properties in the web service client without knowledge of the consequences.
E.g. if the element in the request body is objectRefNum, then I cannot simply change the related property in the scaffolded service reference class, because - without extra configuration - that name is copied with the same letter case to the request body of the SOAP envelope. The SOAP envelope should be encoded in the case-sensitive mode.
To trace the raw request body send by my new REST API in ASP.NET Core, I followed instructions from this excellent answer.
(Note, BTW, that kind of error (applying inappropriate letter case) could be handled by IDE, at least as a warning, but it is not, so: we need to be careful when we make refactoring, even if we have unit tests covering all the paths, and even if we use semantic renaming supported by IDE.)

Related

Implementing versioning a RESTful API with WCF or ASP.Net Web Api

Assume i've read a lot about versioning a restful api, and I decided to not version the the service through the uri, but using mediatypes (format and schema in the request accept header):
What would be the best way to implement a wcf service or a web api service to serve requests defining the requested resource in the uri, the format (eg. application/json) and the schema/version (eg player-v2) in the accept header?
WCF allows me to route based on the uri, but not based on headers. So I cannot route properly.
Web Api allows me to define custom mediatypeformatters, routing for the requested format, but not the schema (eg. return type PlayerV1 or PlayerV2).
I would like to implement a service(either with WCF or Web Api) which, for this request (Pseudo code):
api.myservice.com/players/123 Accept format=application/json; schema=player-v1
returns a PlayerV1 entity, in json format
and for this request:
api.myservice.com/players/123 Accept format=application/json; schema=player-v2
returns a PlayerV2 entity, in json format.
Any tips on how to implement this?
EDIT: To clarify why I want to use content negotiation to deal with versions, see here: REST API Design: Put the “Type” in “Content-Type”.
What you are bringing here does not look to me as versioning but it is is more of content negotiation. Accept header expresses wishes of the client on the format of the resource. Server should grant the wishes or return 406. So if we need more of a concept of Contract (although Web API unline RPC does not define one) then using resource is more solid.
The best practices for versioning have yet to be discussed fully but most REST enthusiast believe using the version in the URL is the way to go (e.g. http://server/api/1.0.3/...). This also makes more sense to me since in your approach using content negotiation server has to keep backward compatibility and I can only imagine the code at the server will get more and more complex. With using URL approach, you can make a clean break: old clients can happily use previous while new clients can enjoy the benefits of new API.
UPDATE
OK, now the question has changed to "Implementing content-negotiation in a RESTful AP".
Type 1: Controller-oblivious
Basically, if content negotiation involves only the format of the resource, implementing or using the right media type formatter is enough. For example, if content negotiation involves returning JSON or XML. In these cases, controller is oblivious to content negotiations.
Type 2: Controller-aware
Controller needs to be aware of the request negotiation. In this case, parameters from the request needs to be extracted from the request and passed in as parameter. For example, let's imagine this action on a controller:
public Player Get(string schemaVersion)
{
...
}
In this case, I would use classic MVC style value providers (See Brad Wilson's post on ValueProviders - this is on MVC but Web API's value provider looks similar):
public Player Get([ValueProvider(typeof(RequestHeadersSchemaValueProviderFactory))]string schemaVersion)
{
...
}

Accessing .NET WCF services from Android

I have a .NET WCF service (not a web service) with many methods, some accepting and returning complex data types. I use these services from my Windows Phone 7 apps. It all works great and it's easy.
Now I'm evaluating the feasibility of porting some of my apps to Android, but I can't figure out how to invoke my WCF services from an Android client.
I have a working example I found in Invoke webservices from Android.
But this looks to be accessing a "Web Service", not a WCF Service.
My service is at http://www.deanblakely.com/Service2.svc, and it contains a simple method named "SimpleTest" that just returns the string "Alive".
Using the code in the linked article, I put http://www.deanblakely.com/Service2.svc in SOAP_ADDRESS and SimpleTest in OPERATION_NAME. But I have no idea what to put in SOAP_ACTION and WSDL_TARGET_NAMESPACE. I don't even know if this approach is valid.
In .NET, Visual Studio builds us a "Service Reference" and everything just works.
I also don't understand the following two lines of code...
httpTransport.call(SOAP_ACTION, envelope);
Object response = envelope.getResponse();
With WCF services, the call is async so we make the call to SimpleTestAsync and leave a callback for the async return. These two lines of code appear to be synchronous, no?
When communicating with WCF services from a non-Windows client, you are basically treating it as an XML Web Service. If you configure your WCF service to use a basicHttp binding, it will act just like any other web service, as far as Java is concerned.
Normally, to call a WCF service from Java, you use wsimport to create a custom set of proxy and data classes, similar to the way a service reference works. Android doesn't have all the libraries needed for those classes, but I did find this URL:
http://code.google.com/p/androidclientgenerator-wsimport/
That is a proxy class generator specifically for Android. Instead of using the code on that web page, you may want to download this proxy generator; you simply have to pass it the URL to your service's WSDL page and it will create typed Java classes for everything. If you have complex types being passed back and forth, this is probably a much better option.
However, if you want to continue with the sample code, you'll need to fill in those variables you've identified. The variables are just the typical parameters for a SOAP envelope. These are defined in the WSDL for your service, and are primarily based on the namespace that you have defined for your service. (They are largely independent of the actual URL that your service lives at, with one exception). You specify the namespace in the WCF service contract:
[ServiceContract(Namespace = "http://namespaces.deanblakely.com/wcf")]
Note that the namespace URL doesn't need to point to a real resource, though frequently they do. It doesn't even need to be a URL (I often use urns); it just needs to be a unique string of characters. For now lets assume you assigned the above namespace to your service.
The WSDL_TARGET_NAMESPACE is just the namespace, exactly as above. The OPERATION_NAME is the name of the method you want to call, for example SimpleTest. The SOAP_ACTION is the combination of namespace an operation; in your case that would be http://namespaces.deanblakely.com/wcf/SimpleTest. In your WSDL you would see this described in an operation tag:
<wsdl:operation name="SimpleTest">
<soap:operation soapAction="http://namespaces.deanblakely.com/wcf/SimpleTest" style="document"/>
The SOAP_ADDRESS is the only one that actually points to your service file, e.g. http://www.deanblakely.com/Service2.svc.
Hopefully that will get you started calling in to your web service; if not feel free to stop back and get more assistance.
EDIT: Missed the part about async calls.
Yes, the method described on that web page is synchronous. WCF service methods are synchronous by default, with the option to include asynchronous calls when generating a service reference in Visual Studio. wsimport generates async-ready proxies, so using the Android client generate may also help you out in this area.

How does WCF Decide which Operation to Dispatch To?

I'm building a WCF SOAP application. The WSDL file has numerous operations of which many have the same argument type. The WSDL file defines all soapAction attributes as "''". When I try to start such a service WCF throw an exception saying that soapActions have to be unique.
After some googling I'm even more puzzled than before. I used SOAPUI to create a mock service with two operations which take the same input type and without the soapActions defined it always chooses the same operation. When the actions are defined it works fine.
My questions are:
Can you make a WCF SOAP service without unique soapActions (actually leaving the soapActions "''" as defined in the original WSDL)?
How can a service choose the right operation without the soapAction defined?
Edited:
I'm not in control of the WSDL. I'm using the WSCF.Blue tool to create a service stub from the WSDL file. I might be able to modify the WSDL, but I want to see if there is some possibility to leave it as it is.
It is not very clear from your question but I suggest you are building service based on some defined WSDL, aren't you? WCF by default uses SOAP action because it is required part of WS-I Basic Profile 1.1 offered by WCF services with BasicHttpBinding. WSDLs with empty SOAP actions are used when the action is defined by root body element.
WCF samples provides example of custom DispatchOperationSelector which is able to route messages to operations by their root body element. This is probably what you need to add to your service so that clients based on provided WSDL can call it.

WCF using Enterprise Library Validation Application Block - how to get hold of invalid messages?

I've got some WCF services (hosted in IIS 6) which use the Enterprise Library (4.0) Validation Application Block. If a client submits a message which fails validation (i.e. gets thrown back in a ValidationFault exception), I'd quite like to be able to log the message XML somewhere (using code, no IIS logs). All the validation happens before the service implementation code kicks in.
I'm sure it's possible to set up some class to get run before the service implementation (presumably this is how the Validation Application Block works), but I can't remember how, or work out exactly what to search for.
Is it possible to create a class and associated configuration that will give me access to either the whole SOAP request message, or at least the message body?
Take a look at using the Policy Injection Application Block...
I'm currently developing an application in which I intercept (using PIAB) all requests incoming to the server and based on the type of request I apply different validation behavior using the VAB.
Here's an article about integrating PIAB with WCF:
http://msdn.microsoft.com/en-us/magazine/cc136759.aspx
You can create different inteception mechanisms such as attributes applied to exposed operations.
You could log the whole WCF Message:
http://msdn.microsoft.com/en-us/library/ms730064.aspx
Or you could combine it with Enterprise Library Logging Application Block.
I found a blog post which seems to do what I want - you create a class that implements IDispatchMessageInspector. In the AfterReceiveRequest method, you have access to the whole incoming message, so can log away. This occurs after authentication, so you also have access to the user name - handy for logging. You can create supporting classes that let you assign this behaviour to services via attributes and/or configuration.
IDispatchMessageInspector also gives you a BeforeSendReply method, so you could log (or alter) your response message.
Now when customers attempt to literally hand-craft SOAP request messages (not even using some kind of DOM object) to our services, we have easy-to-access proof that they are sending rubbish!

View underlying SOAP message using vb.net

I have a VB.NET web service that calls a third party web service. How can I view the SOAP message generated by .NET before it is sent to the third party web service and how can I see the SOAP response before it is serialized by .NET.
When creating a standalone EXE, I see the Reference.vb file that is automatically generated, but don't see a similar file when my project is a web service. I have found lots of C# code to do this, but none in VB.NET.
Edit - Fiddler and TCP loggers are great, but will not work for my purposes. I need to be able to access the raw SOAP messages from within the application so I can log them or modify them. I need to do more than just see the messages going back and forth.
You can use fiddler or a tcp sniffer to filter and identify all outgoing and incoming traffic on your host.
This is if you want to see the xml request and response.
How about using an extension to allow you to examine the SOAP message?
Accessing Raw SOAP Messages in ASP.NET Web Services
http://msdn.microsoft.com/en-us/magazine/cc188761.aspx
I was trying to do the same thing and this seems to work for me:
Dim message As String = OperationContext.Current.RequestContext.RequestMessage.ToString()
I didn't think it would be that easy since most of the time ToString() returns the name of the class, but I tried it out and low and behold.
I know you asked this back in January so if since then you've figured out a better way let me know.
Please note that if you're catching the exception in a class that implements IErrorHandler then you have to perform this operation from within the ProvideFault() method instead of the HandleError() method because the context is closed before it gets to call the HandleError() method.
Hope this helps.