I need to extract a soap Header attribute from a incoming message to my service. I am using service stack and have been looking around and can't find a good answer anywhere. Can anyone tell me how to retrieve a SOAP Header Attribute from a request object?
Here is my service
public class NotificationServices : Service
{
public GetAccountNotificationResponse Any (GetAccountNotification request)
{
//Do Some stuff Here!!!
//Need to retrieve some header here
}
}
Any help will be appreciated. And if you know for a fact it can't be done please let me know as well.
Thank you
In the latest version of ServiceStack v3.9.49 you can access the Request SOAP Message (for SOAP Requests) using the IHttpRequest.GetSoapMessage() extension method, e.g:
public class NotificationServices : Service
{
public GetAccountNotificationResponse Any (GetAccountNotification request)
{
//Do Some stuff Here!!!
var requestSoapMessage = base.Request.GetSoapMessage();
}
}
From the Serialization / Deserialization wiki:
You can access raw WCF Message when accessed with the SOAP endpoints in your Service with IHttpRequest.GetSoapMessage() extension method, e.g:
Message requestMsg = base.Request.GetSoapMessage();
To tell ServiceStack to skip Deserializing the SOAP request entirely, add the IRequiresSoapMessage interface to your Request DTO, e.g:
public class RawWcfMessage : IRequiresSoapMessage {
public Message Message { get; set; }
}
public object Post(RawWcfMessage request) {
request.Message... //Raw WCF SOAP Message
}
Related
First of all, I want to share my scenario what i want to build -
Scenario:
I am building a client app using wpf. In some cases, I need to call a web service to get data from the server. In order to do this, I added a web reference using wsld url. And I created a ServiceManager class that will call service method. For security reason, I need to add some header info at soap xml request for example, UserToken, SAML Token and so on. I can this from my ServiceManager class. But I want to add another class which will be called before sending request to the server. In that class, I will do something like adding security header to soap xml request with request and then send it to the server.
I used SOAP Extension to fulfill my purpose and it works well. But the problem is, every-time I need to add annotation in Reference.cs (for each web service reference) file at top of the service method. I believe that there is some other easiest way to make this working better than SOAP Extension. Is there any way where I can only call the service and a delegate class will be called automatically and I don't need to add any annotation to the reference file? I will share my sample code here.
ServiceManage class:
public class ServiceManager
{
public UserDataService dataService; //web service added at Web Reference
public ServiceManager()
{
dataService = new UserDataService();
getUserServiceRequest rqst = new getUserServiceRequest();
getUserServiceResponse resp = dataService.getUser(rqst);
}
}
Reference.cs
[TraceExtensionAttribute(Name = "First")]
public getUserServiceResponse getUser([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] getUserServiceRequest request) {
object[] results = this.Invoke("getUser", new object[] {
request});
return ((getUserServiceResponse)(results[0]));
}
TraceExtensionAttribute.cs
[AttributeUsage(AttributeTargets.Method)]
public class TraceExtensionAttribute : SoapExtensionAttribute
{
private string mstrName = null;
public override Type ExtensionType
{
get { return typeof(TraceExtension); }
}
public override int Priority
{
get { return 1; }
set { }
}
public string Name
{
get { return mstrName; }
set { mstrName = value; }
}
}
TraceExtension.cs
public class TraceExtension : SoapExtension
{
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attr){//..do something}
public override void Initialize(object initializer){//..do something}
public override Stream ChainStream(Stream stream){//...do something}
public override void ProcessMessage(SoapMessage message) {//..do something}
}
Finally, I found the solution. Just through out Web Reference and add Service Reference instead. Then go to the following link. It works for me.
Problem: As part of a debugging a problem regarding some validation issues I would like to read the XML request of an WCF webservice.
Apparently, this is more difficult than it appears and any help in this regard would be much appreciated. Below are what I've tried already. Much like the answer to a similar question here on StackOverflow (link).
My solution: I've created the client setting the endpoint given by the provider of the webservice. I've added my client credentials as an endpoint behavior. Right before I make the call to service I add another endpoint behavior to write the request and response as XML-files. Alas, to no avail.
The simple call to the webservice:
public SaveAvailabilityAssessmentResponseType SaveAvailabilityAssessment(SaveAvailabilityAssessmentRequestType request)
{
Client.Endpoint.Behaviors.Add(new CustomEndpointBehavior());
return Client.SaveAvailabilityAssessment(_ocesCertHeader, _activeOrganisationHeader, request);
}
And here are the CustomEndpointBehavior class (simplified a bit):
public class CustomEndpointBehavior : IEndpointBehavior
{
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new MessageExpector());
}
}
And here's the MessageExpector class:
internal class MessageExpector : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{
using (var sw = new StreamWriter(#"C:\temp\response.xml"))
{
sw.WriteLine(reply);
}
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
using (var sw = new StreamWriter(#"C:\temp\request.xml"))
{
sw.WriteLine(request);
}
return new object();
}
}
Can anyone tell me what I'm missing?
Edit: Further debugging has showed, that the code in the CustomEndpointBehavior hasn't been activated. It is as if the customendpoint hasn't been added to the client's endpoint behaviors. But how can that be?
You can configure message logging without modifying your code. Here's a link to documentation.
You can use SvcTraceViewer.exe for viewing this logs
I'm working on a legacy ServiceStack application, and I'm trying to add a new endpoint. It's a servicestack 3 application. I created new Response, Request, and Service classes for it, like I've done countless times for other endpoints, but for some reason I can't seem to call it.
I even tried just copying previously existing files and rewriting them to fit my needs, but that didn't work either.
Here's my request:
[Route("/OSTicket/UpdateList", "POST")]
public class OSTicketUpdateListByDBIDRequest
{
public int DatabaseID { get; set; }
}
Here's my response:
public class OSTicketUpdateListResponse : IHasResponseStatus
{
public ResponseStatus ResponseStatus { get; set; }
}
And here's my service endpoint:
public OSTicketUpdateListResponse Post(OSTicketUpdateListByDBIDRequest request)
{
OSTicketUpdateListResponse response = new OSTicketUpdateListResponse();
response.ResponseStatus = new ResponseStatus();
response.ResponseStatus.ErrorCode = "200";
return response;
}
Do I need to register these files somewhere? I don't remember having to do that in the past, but it's very possible that I'm missing something. Whenever I POST to the application using DHC, I get a 404.
Figured it out. In my service declaration:
public class OSTicketService
I forgot to inherit Service.
I am trying to make an echo web service that replies back with the request content, regardless of what that content is. Just an endpoint listening for anything and spitting it back.
So for example if it is called with "hi", the response content is "hi". If it is called with a multi-part message containing a form data, the data comes back. If it is a JSON message then JSON comes back. This is regardless of what the actual content is or what url parameters are provided. Basically I want it to send the same thing back regardless of the mime type, don't try to interpret it, just spit it back.
I'm starting with the following:
[ServiceContract]
private interface IEchoService
{
[OperationContract]
[WebInvoke]
object Echo(object s);
}
private class EchoService : IEchoService
{
public object Echo(object s)
{
return s;
}
}
WebServiceHost host = new WebServiceHost(typeof(EchoService), new Uri("http://localhost:8002/"));
WebHttpBinding binding = new WebHttpBinding();
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IEchoService), binding, "echo");
Any ideas how to make this work? This just returns back a HTTP status code of bad request when called.
It looks like the answer is to use the System.ServiceModel.Channels.Message class.
[ServiceContract]
private interface IEchoService
{
[OperationContract]
[WebInvoke]
Message Echo(Message s);
}
private class EchoService : IEchoService
{
public Message Echo(Message s)
{
return s;
}
}
I'm fairly new to programming an C# and i need to create a web application project. I have been told that a website will navigate to my web application and send an ID. My web application then needs to use this ID within a SOAP request. The responce then needs to be evaluated and if it fits a criteria, the web application can load or else just throws an exception.
I can code all the application except grabbing the initial ID and setting up a SOAP request and recieve. I have all the relevant information, i just don't know how to set up the SOAP request/responce.
Best Regards
Assuming you are using a WCF, it uses SOAP by default, so if you have everything setup correctly, it will automatically serialize and deserialize for you.
[OperationContract]
MyResponse ParseId(MyRequest req);
MyResponse can hold response information
MyRequest can hold request information
Implementation could be like this:
public MyResponse ParseId(MyRequest req)
{
if(req.Id == null)
{
//Error
}
else
{
}
}
If it is really simple, you can do something like this:
[OperationContract]
void ParseId(int id);
Implementation:
public void ParseId(int id)
{
if(id == null)
{
//throw exception;
}
else
{
}
}
Don't forget to decorate your MyResponse class and MyRequest class with DataContract attributes.