WCF Service fails to receive soap requests because of xml declaration - c#

I have programmed an WCF Service which acts as an Event Receicer in C#. A Client sending following Soap Request to the Event Receiver:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:sila="http://sila.coop" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ResponseEvent xmlns="http://sila.coop">
<requestId>10</requestId>
<returnValue>
<returnCode>3</returnCode>
<message>command 'Reset' completed successfully</message>
<duration>PT0S</duration>
<deviceClass>8</deviceClass>
</returnValue>
<responseData><?xml version="1.0" encoding="utf-8"?><ResponseData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sila.coop//schemata/ResponseType_1.2.xsd"></ResponseData></responseData>
</ResponseEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This one is rejected and in the Service Trace Viewer I can see that there was an exception throwed:
System.ServiceModel.ProtocolException, System.Xml.XmlException,
system.xml.xmlexception data at the root level is invalid. line 1 position 1
When I start the WCF Test client, I could send a request, which looks the following:
<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ResponseEvent
xmlns="http://sila.coop"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<requestId>1</requestId>
<returnValue>
<returnCode>3</returnCode>
<deviceClass>0</deviceClass>
</returnValue>
</ResponseEvent>
</s:Body>
</s:Envelope>
This one is working, it will go through the service.
Unfortunatley I'm not able to change the client. So how could I configure or change my Service, that it understands the topmost Request with the xml declaration?
I generated the code for the event receiver via the svcutil tool from an existing mock serivce in SoapUi:
Interface:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://sila.coop", ConfigurationName="EventReceiverSoap")]
public interface EventReceiverSoap
{
[System.ServiceModel.OperationContractAttribute(Action="http://sila.coop/ResponseEvent", ReplyAction="*")]
ResponseEventResponse ResponseEvent(ResponseEventRequest request);
}
My web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "EventReceiverSoap.e2e" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="EventReceiverSoap" />
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- Legen Sie die Werte unten vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Metadateninformationen zu vermeiden. -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" externalMetadataLocation="../wsdl/ls.wsdl" />/>
<!-- Damit in Fehlern Ausnahmedetails zum Debuggen angezeigt werden, legen Sie den Wert unten auf "true" fest. Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Ausnahmeinformationen zu vermeiden. -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Implementation:
//[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class EventReceiverSoapClient : System.ServiceModel.ClientBase<EventReceiverSoap>, EventReceiverSoap
{
public EventReceiverSoapClient()
{
}
public EventReceiverSoapClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public EventReceiverSoapClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public EventReceiverSoapClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public EventReceiverSoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
public ResponseEventResponse ResponseEvent(ResponseEventRequest request)
{
return base.Channel.ResponseEvent(request);
}
}

Related

Ajax POST call won't working with WCF

I'm trying to send data through an Ajax POST call to WCF Service
I send the data with jSON
When I tried to make the call, the WCF Service cannot obtain the data sent
Debugging showed that my input parameter was equal to null
This is my source code :
jQuery side
$.ajax
({
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "http://192.168.0.12:25460/Service1.svc/getPost",
type: 'POST',
data: {"value": "test"},
timeout: 5000,
success: function (data, status, xhr)
{
alert('Success: '+data);
},
error: function(x, e)
{
alert(x.status + " " + x.responseText);
}
});
WCF Side
Iservice1.cs
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle=WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, UriTemplate = "/getPost?value={value}")]
string getPost(string value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
Service1.svc
public class Service1 : IService1
{
public string getPost(string value)
{
return "Reçu :" + value;
}
}
Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxUrlLength="500"/>
</system.web>
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<!-- Service Endpoints -->
<endpoint address="" binding="webHttpBinding" contract="WcfService1.IService1" behaviorConfiguration="webBehavior">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<!-- Pour éviter la divulgation d'informations de métadonnées, définissez les valeurs ci-dessous sur false avant le déploiement -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- Pour recevoir les détails de l'exception dans les erreurs à des fins de débogage, définissez la valeur ci-dessous sur true. Pour éviter la divulgation d'informations d'exception, définissez-la sur false avant le déploiement -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
Pour parcourir le répertoire racine de l'application Web lors du débogage, définissez la valeur ci-dessous sur true.
Définissez-la sur false avant le déploiement pour ne pas divulguer d'informations du dossier de l'application Web.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Thank you for your help !
Try the following changing. May it will work..
jQuery side
$.ajax
({
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "http://192.168.0.12:25460/Service1.svc/getPost/test",//value in url..
type: 'POST',
// data: {"value": "test"}, remove this line.
timeout: 5000,
success: function (data, status, xhr)
{
alert('Success: '+data);
},
error: function(x, e)
{
alert(x.status + " " + x.responseText);
}
});
WCF Side
Iservice1.cs
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle=WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, UriTemplate = "/getPost/{value}")]//change here
string getPost(string value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
I just change your parameter sending approach and put it in URL.

Using WF to send message to Windows Server ServiceBus

I'm trying to send messages to a local Topic created in Windows Server ServiceBus.
I started from examples by Roman Kiss and Paolo salvatori.
I'm stuck with the following exception:
Service namespace cannot be null or empty.
Parameter name: serviceNamespace
This is the service:
[ServiceContract]
public interface INotificationService
{
[OperationContract(Action = "*", IsOneWay = true)]
void Process(string notification);
}
My config file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
</startup>
<system.serviceModel>
<extensions>
<!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
<behaviorExtensions>
<add name="connectionStatusBehavior" type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="serviceRegistrySettings" type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="tcpRelayTransport" type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="httpRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="httpsRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="onewayRelayTransport" type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingElementExtensions>
<bindingExtensions>
<add name="basicHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ws2007HttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netOnewayRelayBinding" type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netEventRelayBinding" type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretCredentials">
<transportClientEndpointBehavior>
<tokenProvider>
<sharedSecret
issuerName="ServiceBusDefaultNamespace"
issuerSecret="--PrimarySymmetricKey retrieved with Get-SBNamespace--" />
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint name="TopicPublisher"
address="sb://[machinename]/ServiceBusDefaultNamespace/NotificationService"
binding="netMessagingBinding"
contract="INotificationService"
behaviorConfiguration="sharedSecretCredentials" />
</client>
</system.serviceModel><appSettings>
<!-- Service Bus specific app setings for messaging connections -->
<!--<add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[your namespace].servicebus.windows.net;SharedSecretIssuer=owner;SharedSecretValue=[your secret]" />-->
</appSettings>
</configuration>
This is my ServiceBus.config file (required to avoid a "The Uri provided [machinename] does not match Service Bus domain: servicebus.windows.net." Exception, look here):
<?xml version="1.0" encoding="utf-8"?> <!-- the root web configuration file -->
<configuration>
<Microsoft.ServiceBus>
<relayHostName>[machinename]</relayHostName>
<stsHostName>[machinename]</stsHostName>
<acmHostName>[machinename]</acmHostName>
</Microsoft.ServiceBus>
</configuration>
This is the very simple workflow:
And finally this is the console:
class Program
{
static void Main(string[] args)
{
Activity publisher = new Publisher();
while (true)
{
Console.WriteLine("Type ctrl+q to exit or enter to insert a notification");
var key = Console.ReadKey();
if (key.Key == ConsoleKey.Q && key.Modifiers == ConsoleModifiers.Control)
{
break;
}
Console.WriteLine();
if (key.Key == ConsoleKey.Enter)
{
Console.WriteLine("Please enter the notification");
}
else
{
Console.WriteLine("Sorry, I didn't understand!");
continue;
}
var notification = Console.ReadLine();
var notificationMessage = new BrokeredMessage(notification);
var inputs = new Dictionary<string, object> { { "Notification", notificationMessage } };
try
{
WorkflowInvoker.Invoke(publisher, inputs);
}
catch (Exception exception)
{
Console.WriteLine("Error: " + exception);
}
}
}
}
I created the NotificationService Topic using Service Bus Explorer 2.1.
The Azure SDK version is 2.1.4 installed via NuGet and I'm using Service Bus for Windows Server 1.1

WCF service relative uri without .svc

I have a solution with 3 projects:
MEProject.WCF.ServiceLayer (Service-Implementation)
MEProject.WCF.HostConsole (Console Application which can host the service)
MEProject.WCF.HostIIS (WCF Service Application)
My goal is that I can switch between the 2 projects without changing the uri (the endpoint configurations) in the client project. Well, the problem is, if I start the console application, the endpoints are
http://localhost:8080/MultipleEndpointService/FirstEndpoint
http://localhost:8080/MultipleEndpointService/SecondEndpoint
But if I start the WCF service application, the endpoints are
http://localhost:8080/MultipleEndpointService.svc/FirstEndpoint
http://localhost:8080/MultipleEndpointService.svc/SecondEndpoint
As you can see, the difference is the ".svc". Now my question: How can I tell the WCF service application to act like the console application and not to have the ".svc" in the uri?
Here is the code I use to get the multiple endpoints in the console application:
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
serviceHostBase.ChannelDispatchers.ToList().ForEach(channelDispatcher =>
{
ChannelDispatcher dispatcher = channelDispatcher as ChannelDispatcher;
if (dispatcher != null)
{
dispatcher.Endpoints.ToList().ForEach(endpoint =>
{
endpoint.DispatchRuntime.InstanceProvider = new CallBackInstanceProvider(serviceDescription.ServiceType, InstanceCreator);
});
}
});
}
And here is the WCF service application web.config:
<system.serviceModel>
<services>
<service name="MEProject.Service.WCF.HostIIS.MultipleEndpointService">
<endpoint name="FirstEndpoint" address="FirstEndpoint" binding="basicHttpBinding" contract="MEProject.Service.WCF.ServiceLayer.IFirstEndpoint"/>
<endpoint name="SecondEndpoint" address="SecondEndpoint" binding="basicHttpBinding" contract="MEProject.Service.WCF.ServiceLayer.ISecondEndpoint"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/MultipleEndpointService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Thanks in advance for your response!
for running a WCF without the SVC extension you will need to use routing
for example i have a service named MultipleEndpointService.svc and i want to get the service like the following:
.../MultipleEndpointService/FirstEndpoint
we can do it like this:
Global.asax:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("MultipleEndpointService/FirstEndpoint", new ServiceHostFactory(), typeof(MultipleEndpointService)));
}
}
MultipleEndpointService.svc.cs:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MultipleEndpointService : IMultipleEndpointService
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
Web.config (for IIS7):
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
<handlers>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd"/>
</handlers>
<directoryBrowse enabled="true"/>
</system.webServer>
source
Try URL ReWriting :
<system.webServer>
<!-- Other stuff here -->
<rewrite>
<rules>
<!-- Rewrite requests to /MultipleEndpointService.svc to /MultipleEndpointService -->
<rule name="MultipleEndpointService" stopProcessing="true">
<match url="MultipleEndpointService.svc(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="/MultipleEndpointService{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>

Calling a local WCF service via Scriptish or Greasemonkey

I'm trying to expose a local WCF service that checks to see if a file exists in my database that can be accessed from a Scriptish script.
Is it possible to call a local URL from Scriptish or Greasemonkey (GET or POST)? I've created a WCF service hosted in IIS on my local machine, and the service is working fine. However, when I try to call the service from Scriptish the Network tab in Chrome/Firefox just says the following:
Request URL: http://localhost/service/service.svc/MatchPartial
Request Method: OPTIONS
Status code: 405 Method Not Allowed
Here is my ajax call:
$.ajax({
url: 'http://localhost/service/service.svc/MatchPartial',
type: 'POST',
contentType: 'application/json; charset=UTF-8',
dataType: 'json',
processData: true,
data: '{ "partialFilename": "testing" }',
success: function (result) {
console.log(result);
}
});
My method is decorated with:
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public int MatchPartial(string partialFilename)
{
...
}
I have the following above my service class:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
I've tried adding the following to my service with no luck:
[WebInvoke(Method = "OPTIONS", UriTemplate = "*")]
public void GetOptions()
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
}
I feel like I've tried everything. Any help would be appreciated!
I figured out how to do it via a GET request thanks to M.Babcock for pushing me in that direction (unimportant parts intentionally left out to save space).
Service.svc:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public bool MatchPartial(string partialFilename)
{
...
}
}
Web.config:
<configuration>
...
...
<system.web>
<compilation debug="true"
targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<!-- IMPORTANT FOR THIS TO WORK USING JQUERY GET OR AJAX -->
<add name="Access-Control-Allow-Origin"
value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
<system.serviceModel>
<services>
<service name="MyNamespace.Services.WCF.Service">
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration=""
contract="MyNamespace.Core.Interfaces.IService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/Service" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<!-- For Debugging --->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
Here's how to do it in Scriptish:
var service = "http://localhost/service/service.svc";
GM_xmlhttpRequest({
method: "GET",
url: service + "/MatchPartial?partialFilename=" + filename,
headers: { "Accept": "application/json" },
onload: function (result) {
if (result != null && result.status == 200 && result.responseJSON == true) {
videoFrame.remove();
}
},
onerror: function (res) {
GM_log("Error!");
}
});
Plain ol' jQuery:
$.get("service", { partialFilename: filename }, function (result) {
if (result == true) {
videoFrame.remove();
}
});

Format ApplicationData in Service Trace Viewer as XML

I'm using TraceSource to log information to a XmlWriterTraceListener. The message I'm logging is a XML, however, when I view the message in Service Trace Viewer, it's not displayed as a XML, it's displayed as a string. Is there a way to do this?
Here is my app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="system.framework.db.utility" switchName="switchInformation">
<listeners>
<remove name="Default" />
<add name="arquivoXml" />
</listeners>
</source>
</sources>
<switches>
<add name="switchErro" value="Error"/>
<add name="switchInformation" value="Information"/>
</switches>
<sharedListeners>
<add name="arquivoXml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\Temp\trace.svclog">
</add>
</sharedListeners>
</system.diagnostics>
</configuration>
Below is my code:
namespace system.framework.db.utility.sqlserver
{
internal class SqlDBTransManager : IDBManagerConnection
{
private static readonly TraceSource ts = new TraceSource("system.framework.db.utility");
private void RunSqlInternal(String pSql, DBManagerParams pDBManagerParams, DBManagerConnection pTransac)
{
//Lots of code, and below is the log
StringBuilder sb = new StringBuilder(1000);
XmlWriterSettings settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Document;
using (XmlWriter xml = XmlWriter.Create(sb, settings))
{
xml.WriteStartDocument(true);
xml.WriteStartElement("log");
xml.WriteAttributeString("Método", "RunSql");
xml.WriteString(pSql);
xml.WriteEndElement();
xml.WriteEndDocument();
xml.Flush();
}
ts.TraceEvent(TraceEventType.Information, 1, sb.ToString());
oCommand.ExecuteNonQuery();
}
}
}
And below is how it's showing in Service Trace Viewer
Is there anyway so that what's under the <ApplicationData> tag is formatted as a XML?
EDIT
I opened the svcfile, and I saw that the string is not encoded properly. Why isn't it?
<ApplicationData><log Método="RunSql">drop procedure dbo.spfwug_in_controle_versao</log></ApplicationData>
No need to clutter your code with the enterprise library; just use the TraceData() method of the TraceSource passing an XPathNavigator as the object argument:
TextReader reader = new StringReader(message);
var xml = new XPathDocument(reader).CreateNavigator();
this.traceSource.TraceData(TraceEventType.Information, -2, xml);
I was able to do this dumping the TraceSource, and using the Enterprise Library 5.0. It was a XmlLogEntry that solved my problem. Below is the code:
internal class SqlDBTransManager : IDBManagerConnection
{
private void RunSqlInternal(String pSql, DBManagerParams pDBManagerParams, DBManagerConnection pTransac)
{
////Lots of code, and below is the log
XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
using (XmlWriter xml = nav.AppendChild())
{
xml.WriteStartElement("log");
xml.WriteAttributeString("Método", "RunSql");
xml.WriteString(pSql);
xml.WriteEndElement();
xml.Flush();
}
XmlLogEntry entry = new XmlLogEntry();
entry.Xml = nav;
entry.Priority = 1;
entry.Categories = new String[] { "DB" };
entry.Severity = TraceEventType.Information;
Logger.Write(entry);
oCommand.ExecuteNonQuery();
}
}
After that, I configure a XML Trace Listener in the web.config:
<configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
</configSections>
<loggingConfiguration name="Logging Application Block" tracingEnabled="true"
defaultCategory="System.ServiceModel" logWarningsWhenNoCategoriesMatch="true">
<listeners>
<add name="XML Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.XmlTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.XmlTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging"
fileName="c:\\temp\\trace_framework.svclog" traceOutputOptions="DateTime, Timestamp, ProcessId, ThreadId" />
</listeners>
<categorySources>
<add switchValue="All" name="System.ServiceModel">
<listeners>
<add name="XML Trace Listener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events">
<listeners>
<add name="XML Trace Listener" />
</listeners>
</allEvents>
<notProcessed switchValue="All" name="Unprocessed Category">
<listeners>
<add name="XML Trace Listener" />
</listeners>
</notProcessed>
<errors switchValue="All" name="Logging Errors & Warnings">
<listeners>
<add name="XML Trace Listener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
After this, the XML that I send is correctly formatted as a XML in the svclog format.

Categories