I'm trying to build a webservice with ASP that will be given three parameters: a string, a date/time and another string. After making the method, the wsdl contains this:
<s:element name="TimesheetAudit">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="employeeNumber" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="periodEndDate" type="s:dateTime"/>
<s:element minOccurs="0" maxOccurs="1" name="timesheet" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
The black box calling my web service is complaining that there is a mismatch in the number of parameters. I am assuming this is because my webmethod is technically taking 1 parameter, a complex type, instead of three.
Is this the problem? If so, what can I do to overcome it?
Edit: The consumer is the black box in this case, I must mold my web service to match the caller.
Adding [SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)] to my method signature gives the following error: ' does not conform to WS-I Basic Profile v1.1. Please examine each of the normative statement violations below. To turn off conformance check set the ConformanceClaims property on corresponding WebServiceBinding attribute to WsiClaims.None.
R2204: A document-literal binding in a DESCRIPTION MUST refer, in each of its soapbind:body element(s), only to wsdl:part element(s) that have been defined using the element attribute.
- Part 'input' of message 'TimesheetAuditSoapIn' from service description with targetNamespace='http://www.netdes.com/'.
- Part 'TimesheetAuditResult' of message 'TimesheetAuditSoapOut' from service description with targetNamespace='http://www.netdes.com/'.
It is difficult to be sure without more information about what exactly the client is expecting, but it could be a parameter style issue.
By default, an ASP.NET web service uses the "Wrapped" parameter style, which means that all of the parameters get wrapped in a single element that is sent inside the SOAP body.
You can change the method declaration to use the "Bare" parameter style, which puts all the parameters directly inside the SOAP body, without a wrapper element. This is achieved via the ParameterStyle property on the SoapDocumentMethodAttribute on the web method.
See this MSDN entry for details.
In response to conformance error: You can disable WS-I conformance checking by putting the following in your web.config:
<configuration>
<system.web>
<webServices>
<conformanceWarnings>
<remove name='BasicProfile1_1'/>
</conformanceWarnings>
</webServices>
</system.web>
</configuration>
Conformance is normally a good thing, but it's not required. Since you aren't in control of the definition in this case, you don't have much of a choice.
It is also possible that the client is expecting an RPC-style web service instead of a document-style web service. (This would be controlled with a SoapRpcMethodAttribute instead of a SoapDocumentMethodAttribute.) If you still have no luck after turning off the conformance warning you might try changing to RPC-style and see if that works.
And if there's any way you can get a definition (either source or, better yet, a WSDL used to produce the source) for the client so that you can tell what exactly it's expecting, it would help. If you can get a WSDL you can have .NET generate the web service method for you in the correct format.
It sounds like you're the one building the web service host, so you get to run the show, right?
If you can launch Visual Studio, click File, New Website, add a web service to it, use the auto-generated WSDL and successfully connect to it from a test harness, then the consumer of that web service ought to be able to read that same WSDL and connect to it as well as you. The important thing is that you have a test harness that works.
If that's the case, then the black box problem lies on their end of the wire, not yours.
Related
I have a service that has references to other services with some of them being references to different environments of the same service (e.g. prod/test).
I am using the #if precompile directive to include different versions of these references with the using statement. Example:
#if Debug
using ServiceTest
#else
using ServiceProd
#endif
In the Web.config file I have two child nodes inside the <client> node. Example:
<client>
<endpoint address="http://test.domain.com/Service"
binding="basicHttpBinding" bindingConfiguration="Service"
contract="ServiceTest" name="Service" />
<endpoint address="http://prod.domain.com/Service"
binding="basicHttpBinding" bindingConfiguration="Service"
contract="ServiceProd" name="Service" />
</client>
Is the above part of the Web.config valid or not? More precisely, can there be any side-effects because of having two endpoints with the same name and binding configurations? The main concern is having a wrong endpoint called (e.g. calling prod endpoint instead of test or the other way around).
Any guidance and advice regarding the above will be really appreciated.
Is the above part of the Web.config valid or not?
Every time when you run your application CLR reads web.config file and deserialize it as an object. To deserialize XML it's uses classes declaration in "configSections" section of your config file.
So, the answer "valid or not" depends on implementation of "client" configuration section. I believe this should be part of your application or code from nuget library. This is why we can't answer you with confidence.
More precisely, can there be any side-effects because of having two endpoints with the same name and binding configurations?
Frankly, I don't understand how this should work. In what manner 3rd library should know that it needs to load first but not second client endpoint?
Possible solutions.
You can use web.config transformation. There are tons of resources about this feature of .NET Framework.
The simplest scenario would be to substitute endpoint address keeping the same endpoint name.
Another common scenario is to give different endpoint names and keep "alive" endpoint name in AppSettings. In this case your code should resolve endpoint name first and then actual endpoint address.
The problem is: I need to connect to a soap web service; generated by java code; using ASP.Net client via C# through MS Visual Studio 2013.
Try 1, The usual way:
I have added a web service reference using the wsdl and by assigning the credentials like:
Credentials.Username.Username = "test";
Credentials.Password.Password = "test";
When executing, the following exception is being encountered:
The login information is missing!
Try 2:
I have searched for similar problems like:
how-to-go-from-wsdl-soap-request-envelope-in-c-sharp
Dynamic-Proxy-Creation-Using-C-Emit
c# - Client to send SOAP request and received response
I had chosen to generate a proxy class using the wsdl tool, then added the
header attribute, but I have found the following note from Microsoft:
Note: If the Web service defines the member variables representing the SOAP headers of type SoapHeader or SoapUnknownHeader instead of a class deriving from SoapHeader, a proxy class will not have any information about that SOAP header.
Try 3:
I have tried to change the service model in the client web.config:
<bindings>
<basicHttpBinding>
<binding name="CallingCardServicePortBinding">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
Then added the credentials like the first try, but the following error appears:
MustUnderstand headers:[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood
So, now I don't know what to do !
I have no control over the web service and I need to build a client that understands it.
Help Please!
The Soap Request template is the following:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="...">
<soapenv:Header>
<credentials>
<userName>someUserName</userName>
<password>somePassword</password>
</credentials>
</soapenv:Header>
<soapenv:Body>
<ser:someRequest>
.......
.......
.......
</ser:someRequest>
If the destination web service uses authentication, then just ASMX won't do, since it is not aware of authentication, encryption etc. You have 2 options:
Use Microsoft WSE: http://www.microsoft.com/en-us/download/details.aspx?id=14089
this is nothing but an extension of ASMX which makes it Security/Encryption aware. (and some other features) technically, you'll be adding a reference to the WSE DLL and your Soap Proxy will extend from the WSE SOAP Client instead of the System one.
once you do that, the proxy class will have additional username/password properties that you can use to authenticate properly.
set the properties and see the outgoing request using fiddler. if the header is not what you want (because of namespaces etc.), then you can write a custom outgoing message inspector and modify the soap request nicely.
The other option (preferred) is to use WCF.
ASMX and WSE are older than WCF. WCF tries to bring all the web service nuances under one roof. if you get a WCF service reference, it (svcutil.exe) will automatically create the proxy class and the right bindings for you. (mostly custom)
once you do that, try setting the user name and password.
if that doesn't work, (i have frequently struggled to generate the right soap header for remote java based services that require username/password authentication), you can define a static header chunk in the web.config/app.config, that'll be sent as part of every request.
e.g.
<client>
<endpoint>
<headers>
<credentials>
<userName>someUserName</userName>
<password>somePassword</password>
</credentials>
</headers>
</endpoint>
</client>
I'm using WCF service (via WebGet attribute).
I'm trying to access Session from WCF service, but HttpContext.Current is null
I added AspNetCompatibilityRequirements and edited web.config but I still cannot access session.
Is it possible to use WebGet and Session together?
Thank you!
Yes, it is possible. If you edit the web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
and add the AspNetCompatiblityRequirements, the HttpContext.Current should be available.
Check everything once again, maybe you've put the attribute in the wrong place (the interface instead of the class?).
A RESTfull service with a session?
See excellent discussion here: Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant"
http://javadialog.blogspot.co.uk/2009/06/common-rest-mistakes.html (point 6)
and
http://www.peej.co.uk/articles/no-sessions.html
Quote from Paul Prescod:
Sessions are irrelevant.
There should be no need for a client to "login" or "start a connection." HTTP authentication is done
automatically on every message. Client applications are consumers of
resources, not services. Therefore there is nothing to log in to!
Let's say that you are booking a flight on a REST web service. You
don't create a new "session" connection to the service. Rather you ask
the "itinerary creator object" to create you a new itinerary. You can
start filling in the blanks but then get some totally different
component elsewhere on the web to fill in some other blanks. There is
no session so there is no problem of migrating session state between
clients. There is also no issue of "session affinity" in the server
(though there are still load balancing issues to continue).
The app splits off into two threads; the main web app and a secondary thread used for asynchronous event handling. The secondary thread receives an event where it needs to send an email with a fully qualified URL of the main app (plus additional route arguments) inside it.
Eg. http://Server.com/App/RouteData?AdditionalArguments
Of course the background thread does not have the luxury of using HttpContext.Current to resolve a Url, because there's no request. No HttpRequest, no HttpContext...
I discovered that most of the methods ASP.NET (even with MVC) uses to build URLs rely on HttpContext. Does there exist a way to build a fully qualified application URL in ASP.NET without using HttpContext or any of it's derivatives?
I'm looking for a thread-safe method like:
UrlHelper.GetApplicationtUrl()
Any Ideas? Your suggestions are much appreciated.
I had this exact problem. I ended up storing the url in the web.config file. I did mine like so:
<appSettings>
<!-- Urls -->
<add key="AppDomain" value="http://localhost:1273/" />
<add key="ConfirmUrl" value="http://localhost:1273/Auth/Confirm/?code={0}" />
</appSettings>
and called it like this in the service layer:
string confirmUrl = string.Format(ConfigurationManager.AppSettings["ConfirmUrl"], confirmCode);
If you can't just use the configuration file, when creating the Thread, use the ThreadStart delegate to provide the base information you need to the new thread.
I've got a asmx service that takes a single int parameter. I can open the URL to the service and see the service description screen. From here I can enter the query parameters into a form and invoke the web service.
Is there any way to invoke a web service directly from a URL/query string?
This doesnt work:
http://localhost:4653/MyService.asmx?op=MyWebMethod&intParameter=1
Any ideas? I'd really like to be able to do this from a standard link due to some deployment issues. Am I going to have to wrap the request in a normal aspx page?
You can decorate your method to allow HTTP GET requests, which should in turn do what you're looking for like so:
[WebMethod]
[ScriptMethod(UseHttpGet=true)]
public string MyNiftyMethod(int myint)
{
// ... code here
}
And edit the web.config :
<system.web>
<webServices>
<protocols>
<add name="HttpGet"/>
</protocols>
Then you'll be able to call this method like so:
http://mysite.com/Service.asmx/MyNiftyMethod?myint=12345
EDIT: Note that this method of performing GET requests does come with some security risks. According to the MSDN documentation for UseHttpGet:
Setting the UseHttpGet property to
true might pose a security risk for
your application if you are working
with sensitive data or transactions.
In GET requests, the message is
encoded by the browser into the URL
and is therefore an easier target for
tampering.
ASMX web services use SOAP. SOAP requests use only POST to invoke methods. You will need to generate a proxy client in your aspx page to invoke the web service. If you really need to use GET verbs to invoke web services you might need to use a different approach such as WCF REST.