wcf data service format the response as xml - c#

I have created a wcf data service like this
public class Northwind : DataService< SelfServiceEntities >
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("SMS", EntitySetRights.AllRead
| EntitySetRights.WriteMerge
| EntitySetRights.WriteReplace);
}
}
and when I request this url
http://localhost:2242/Northwind.svc/SMS
I got this response
<?xml version="1.0" encoding="utf-8"?><feed xml:base="http://localhost:2242/Northwind.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><id>http://localhost:2242/Northwind.svc/SMS</id><title type="text">SMS</title><updated>2014-02-05T08:33:49Z</updated><link rel="self" title="SMS" href="SMS" /><entry><id>http://localhost:2242/Northwind.svc/SMS(1)</id><category term="SelfServiceModel.SM" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /><link rel="edit" title="SM" href="SMS(1)" /><title /><updated>2014-02-05T08:33:49Z</updated><author><name /></author><content type="application/xml"><m:properties><d:ID m:type="Edm.Int32">1</d:ID><d:number>1</d:number><d:body_ar>1</d:body_ar><d:body_en>1</d:body_en></m:properties></content></entry><entry><id>http://localhost:2242/Northwind.svc/SMS(2)</id><category term="SelfServiceModel.SM" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /><link rel="edit" title="SM" href="SMS(2)" /><title /><updated>2014-02-05T08:33:49Z</updated><author><name /></author><content type="application/xml"><m:properties><d:ID m:type="Edm.Int32">2</d:ID><d:number>55</d:number><d:body_ar>55</d:body_ar><d:body_en>55</d:body_en></m:properties></content></entry></feed>
my question
How can I make the response formatted as xml?
I made a research and I found this link
http://msdn.microsoft.com/en-us/library/cc668794%28v=vs.110%29.aspx
that states
OData builds on standard Internet protocols to make data services interoperable with applications that do not use the .NET Framework. Because you can use standard URIs to address data, your application can access and change data by using the semantics of representational state transfer (REST), specifically the standard HTTP verbs of GET, PUT, POST, and DELETE. This enables you to access these services from any client that can parse and access data that is transmitted over standard HTTP protocols.
OData defines a set of extensions to the Atom Publishing Protocol (AtomPub). It supports HTTP requests and responses in more than one data format to accommodate various client applications and platforms. An OData feed can represent data in Atom, JavaScript Object Notation (JSON), and as plain XML. While Atom is the default format, the format of the feed is specified in the header of the HTTP request. For more information, see OData: Atom Format and OData: JSON Format.

Related

c# Onvif GetSystemDateandTime SOAP not working on UDP

I'm am trying to construct a somewhat complete ONVIF device manager using only UDP. I understand certain features require TCP, but for now I can accept that these features will be unavailable to me. I am struggling to get the system date and time without setting up an HTTPClient. According to Onvif this SOAP does not require authentication and is instead information needed for the complete authentication process.
I am able to send out a probe on UDP and get responses, and even get PTZ settings with basic authentication. When I use the following SOAP provided by the Onvif Applications Programmers Guide, however, I see that the message is sent but no response is received (using wire shark).
According to the Programmers Guide the following....
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
<SOAP-ENV:Body>
<tds:GetSystemDateAndTime/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Should generate the following response....
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:tt="http://www.onvif.org/ver10/schema"
xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
<SOAP-ENV:Body>
<tds:GetSystemDateAndTimeResponse>
<tds:SystemDateAndTime>
<tt:DateTimeType>NTP</tt:DateTimeType>
<tt:DaylightSavings>true</tt:DaylightSavings>
<tt:TimeZone>
<tt:TZ>CET-1CEST,M3.5.0,M10.5.0</tt:TZ>
</tt:TimeZone>
<tt:UTCDateTime>
<tt:Time>
<tt:Hour>15</tt:Hour>
<tt:Minute>52</tt:Minute>
<tt:Second>25</tt:Second>
</tt:Time>
<tt:Date>
<tt:Year>2010</tt:Year>
<tt:Month>10</tt:Month>
<tt:Day>29</tt:Day>
</tt:Date>
</tt:UTCDateTime>
<tt:LocalDateTime>
<tt:Time>
<tt:Hour>17</tt:Hour>
<tt:Minute>52</tt:Minute>
<tt:Second>25</tt:Second>
</tt:Time>
<tt:Date>
<tt:Year>2010</tt:Year>
<tt:Month>10</tt:Month>
<tt:Day>29</tt:Day>
</tt:Date>
</tt:LocalDateTime>
</tds:SystemDateAndTime>
</tds:GetSystemDateAndTimeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is a stripped version of the code I'm using. This approach has worked in all attempts other than the soap listed above.
public static async Task<List<string>> GetSoapRes_Time_and_DateAsync()
{
//Create a variable called result to store returned string. Code omitted for clarity.
using (var client = new UdpClient())
{
var ipEndpoint = new IPEndPoint(IPAddress.Parse("192.168.1.64"), 3702);
client.EnableBroadcast = true;
try
{
var soapMessage = GetBytes(CreateSoapRequest());
await client.SendAsync(soapMessage, soapMessage.Length, ipEndpoint);
//ToDo: check if we have bits back and if we do process and store in result.
}
catch (Exception exception)
{
//Do something
}
}
//Return results
return result;
}
private static string CreateSoapRequest()
{
Guid messageId = Guid.NewGuid();
const string soap = ************Place Soap string here***********
var result = string.Format(soap, messageId);
return result;
}
private static byte[] GetBytes(string text)
{
return Encoding.ASCII.GetBytes(text);
}
Would anyone be familiar enough with Onvif to know what is going wrong? I'm assuming that either
A) I'm missing something obvious
B) Onvif only accepts this soap with a TCP header.
You cannot do that.
From the core specs in section 4.1:
This framework is built upon Web Services standards. All configuration
services defined in the standard are expressed as Web Services
operations and defined in WSDL with HTTP as the underlying transport
mechanism.
By using only UDP, you can only have device discovery and getting streaming if the camera is configured for starting multicast streaming automatically at boot. For any other functionality, at least one TCP connection is required.

How to consume SOAP service with custom header

I need to consume a SOAP service from a vendor. I had created a proxy service with the WSDL in visual studio, instantiated the client class, called the action method, and got the response. Everything works fine until the vendor asks for an access token in the soap envelop header. I am able to get the access token from them on another service call but how do I add it to the soap request header?
Here is the structure of the header from the vendor:
<SOAP:Header>
<SOAP-SEC:Security SOAP:mustUnderstand="1">
<wsse:SecuredKey ValueType="..." EncodingType="wsse:Base64Binary">
{ACCESS TOKEN}
</wsse:SecuredKey>
</SOAP-Sec:Security>
</SOAP:Header>
<SOAP:Body/>
</SOAP:Envelop>
By far the easiest way to do this is by using a string replace in a template. Store the message as a resource in your project (e.g. in Resources.resx or save as file and set set build action to embedded resource). The template looks like this:
<SOAP:Header>
<SOAP-SEC:Security SOAP:mustUnderstand="1">
<wsse:SecuredKey ValueType="..." EncodingType="wsse:Base64Binary">
{ACCESS TOKEN}
</wsse:SecuredKey>
</SOAP-Sec:Security>
</SOAP:Header>
<SOAP:Body/>
</SOAP:Envelop>
Load the template as string from your resource, then call the webservice to obtain an access token and do and replace {ACCESS TOKEN} with the actual access token. You can now send the soap message using e.g. System.Net.Http.HttpClient or System.Net.WebClient.
Example using WebClient
using (var client = new WebClient())
{
var result = client.UploadString("http://your.target/endpoint", yourXDocument.ToString(SaveOptions.DisableFormatting));
return XDocument.Parse(result);
}
The SaveOptions.DisableFormatting doesn't try to pretty print the XDocument which can be important when using a signed xml document with WS-Security. Not sure if that applies in your case.

accessing php soapservice from C#

well i wanted to make a simple webservice that searches the db and return the data i know i can do it with mysql connector but this is just to learn how to use soaps here is the code for php soap server
require_once ('lib/nusoap.php');
$namespace = "http://localhost/webservice/index.php?wsdl";
$server = new soap_server();
$server->configureWSDL("DBQuery");
$server->wsdl->schemaTargetNamespace = $namespace;
$server->register(
'QueryMsg',
array('name'=>'xsd:string'),
array('return'=>'xsd:string'),
$namespace,
false,
'rpc',
'encoded',
'returns data from database');
function QueryMsg($query)
{
$con=mysqli_connect('localhost','root','','webserivce');
if (mysqli_connect_errno()) {
return "Failed to connect to MySQL: " . mysqli_connect_error();
}
if(!isset($query) or strpos(strtolower($query),'select')<=-1)
{
return "invalid order";
}
else
{
mysqli_real_escape_string($con,$query);
$result = mysqli_query($con,$query);
while($row = mysqli_fetch_array($result)) {
$data[] = $row;}
return json_encode($data);
}
}
// create HTTP listener
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
exit();
?>
it works when i try calling it from a php soap client but when i try adding this http:// localhost /webservice/index.php in visual studio as service refernce to consume it from C# application i get an error here it is
The HTML document does not contain Web service discovery information.
Metadata contains a reference that cannot be resolved: 'http://localhost/webservice/index.php'.
The content type text/xml; charset=ISO-8859-1 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 700 bytes of the response were: '<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><SOAP-ENV:Fault><faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode><faultactor xsi:type="xsd:string"></faultactor><faultstring xsi:type="xsd:string">Operation &apos;&apos; is not defined in the WSDL for this service</faultstring><detail xsi:type="xsd:string"></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>'.
The remote server returned an error: (500) Internal Server Error.
If the service is defined in the current solution, try building the solution and adding the service reference again.
solved : well it was easy actually there is two ways either use WCF and change encoding to ISO-8859-1
or change encoding of the web service itself by adding this line $server->soap_defencoding = 'UTF-8'; after creating the soap server
I would try adding the service WSDL with a tool like SOAP U.I. and see what kind of errors you get back from that. It's a little more agnostic than adding a web reference with C#, and might disclose more details about why at the client level you can't consume this.
I'm happy to help you troubleshoot this with a little more information. Are you running this service on the same machine where you're running the client from? If it's complaining about being unable to correlate the file http://localhost/webservice/index.php to something I wonder if the discovery process is trying to evaluate a file that can't be found. I.E. an import operation in your source WSDL that points to a URL the client can't resolve.

How to consume an MIME response attachment in C#?

I am working with a java-written web service called JasperServer. I would like to obtain a file from the web service and save it on my local.
The web service provides a get() method; it requests a String of XML, and returns a String, and the target file as a MIME attachment:
public string get(string requestXmlString)
Right now I try to use a string to take in the response:
String res2 = webServiceClient.get(xmlInput);
It gives me an Exception:
Client found response content type of 'multipart/related; type="text/xml"; start="<7817FB68F69B037F5A5DEDE2AC105A65>"; boundary="----=_Part_2_1089980294.1393857885100"', but expected 'text/xml'.
The request failed with the error message:
------=_Part_2_1089980294.1393857885100
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <7817FB68F69B037F5A5DEDE2AC105A65>
So my question is how to consume an String response with MIME attachment in C# .Net. And how to save it to my local?
You need a component for parsing MIME format described by RFC 822/2045 and extensions.
.NET framework doesn't include built-in classes for that.
I've good experience with Mime4Net component (it is based on port from Apache mime4j):
Stream mimeMsgStream;
var m = new MimeMessage(mimeMsgStream);
MimeMessage provides DOM for MIME structure and attachment content could be easily extracted. Also note that Mime4Net is free only for non-commercial usage.
I have the same problem with consuming Java WS.
On WCF3 config I only add the messageEncoding propery to binding definition and set it to "Mtom".
Something like this:
...
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="e3" messageEncoding="Mtom">

Web service (asmx) to read in customer's soap message c# - null object error

I am pretty new with web services and WSDLs.
What I want to do is to build a web service to read in a customer's SOAP message and process it.
The soap message sent to me is as follows (note I have trimmed the SOAP message right down)
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope">
<soap2:Header>
<wsa:Action>http://htng.org/PWSWG/2010/12/ReservationSynch_SubmitRequest</wsa:Action>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:ReplyTo>
</soap2:Header>
<Body>
<OTA_HotelResNotifRQ>
<POS>
//More tags
</POS>
<HotelReservations>
<HotelReservation RoomStayReservation="true">
<UniqueID Type="14" ID="59071IC000041" />
</HotelReservation>
</HotelReservations>
</OTA_HotelResNotifRQ>
</Body>
</Envelope>
This is my web service asmx (again I have trimmed it right down)
[WebMethod]
[SoapDocumentMethodAttribute("http://htng.org/PWSWG/2010/12/ReservationSynch_SubmitRequest", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
public OTA_HotelResNotifRS ReservationSynch_SubmitRequest(OTA_HotelResNotifRQ OTA_HotelResNotifRQ)
{
}
Problem: When the message comes in, the method ReservationSynch_SubmitRequest gets fired but OTA_HotelResNotifRQ is null. The customer gave me the WSDL, as far as am concerned the class is correct. Though I notice the <Body> tag and is not <soap2:Body>. Does this make a difference?
I cannot change customer's message, I can only change my web service to read what they have sent to me. Am I missing something in my asmx?
If you are interested, here is their WSDL https://interface.synxis.com/interface/ota2010av2/OTA2010A.svc.wsdl
Found the problem!
I changed the namespace for a couple of the classes, which affected the schema files in the WSDL.

Categories