WCF Msmq problem reading messages using netMsmqBinding - wcf

I have a WCF service using netMsmqBinding that I am using to add messages of Msmq<string> to a queue. The messages are added fine and I can see them in the queue via the computer management console.
I have another WCF service that is trying to retrieve the messages from the queue, this is where I'm having a problem. My method in my service is getting called whenever a message is added to the queue (that bit is working fine) but the Msmq<string> message seems to have all null values.
I'm not sure how I can get the message from that Msmq<string>? Here is my service details... any help appreciated..
[ServiceContract]
[ServiceKnownType(typeof(Msmq<string>))]
public interface IMessageListener
{
[OperationContract(IsOneWay = true, Action = "*")]
void ListenForMessage(Msmq<string> msg);
}
public class MessageListener : IMessageListener
{
[OperationBehavior(TransactionScopeRequired = false, TransactionAutoComplete = true)]
public void ListenForMessage(MsmqMessage<string> msg)
{
//this gets called and seems to remove the message from the queue, but message attributes are all null
}
}

I think you're not quite "getting" the idea of WCF over MSMQ.
When using WCF with the netMsmqBinding, the whole idea is that you don't need to deal with the details of MSMQ - let the WCF runtime handle that!
So basically, your approach should be as with any WCF service:
define your service contract and its methods (operation contract)
define your data structures as a [DataContract] and use those in your service methods
implement the service
So your service should be something like:
[DataContract]
public class Customer
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Name { get; set; }
...
}
[ServiceContract]
public interface ICustomerService
{
[OperationContract(IsOneWay=true)]
void SaveCustomer(Customer myCustomer)
[OperationContract(IsOneWay=true)]
void CreateCustomer(int ID, string name);
}
You should have a data contract to describe your data - just your data, no MSMQ details needed here! Then you should have one set of service methods that will deal with the Customer object - you can put it into the queue for storing, create a new one etc.
You would then implement the client and the server side for this service contract, and the WCF runtime will handle all the details of MSMQ transport, putting the payload (the Customer object) into a MSMQ message and getting it back out again and so on... you don't have to deal with that, really.

Related

Calling a Web Service using WCF channel Factory.Is it possible?

In the project I am working on I need to call webservices (asmx).I would like to call them using wcf and using the channelfactory(No adding service Reference).
Some might have an interface(contract)many dont.
Is there an end to end example how to do it?
var service=ChannelFactory<?>... How do I get the webserviceContract.
Surely this must be a common scenario to be able to call a webservice (asmx)
Thanks for your time
To expand upon my comment, you should be able to create an interface that has methods that match the web service methods in the asmx service. For example:
Web Service Methods
string GetMessage()
void SendMessage(string message)
int AddNumbers(int x, int y)
Service Contract
[ServiceContract]
public interface IServiceName
{
[OperationContract]
string GetMessage();
[OperationContract]
void SendMessage(string message);
[OperationContract]
int AddNumbers(int x, int y)
}
ChannelFactory
ChannelFactory<IServiceName> serviceFactory =
new ChannelFactory<IServiceName>(new BasicHttpBinding(),
"http://www.services.com/Service.asmx");
Not 100% sure this will work, but it would be easy to try out. Also, you'd probably want to set the namespace on the service contract ([ServiceContract(Namespace = "somenamespace")]) to match the legacy asmx service, otherwise the messages might not get processed.

Roundtripping DataContracts andDenial Of Service attacks

I am working on a datacontract as follows that uses IExtensiblesDataObject to make it forward compatible with version 02 of this contract, but am worried about possible 'accidental' denial of service via clients passing excessive quantities of data over the wire that needs to be de-serialised, re-serialised and sent back.
Without turning the support off via the ignoreExtensionDataObject in the config file, is there a way of protecting against such an eventuality, i.e. can you cap the quantity somehow ?
[DataContract(Namespace="http://schemas.myComany.com/sample/01")]
public class Sample : IExtensibleDataObject
{
[DataMember]
public int32 sample_ID;
private ExtensionDataObject _data;
public virtual ExtensionDataObject ExtensionData
{
get { return _data; }
set { _data = value; }
}
....
}
Thanks in advance
The way to protect your service is limiting MaxReceivedMessageSize (by default it is 65KB) and reader quotas in your binding.

WCF Ria Services and Cyclic references

I'm using a legacy database that has some cyclic references. When I consume my Ria service from a SL4 client. (generated entities through my ORM mapper) I get the following error:
There was an error while trying to serialize parameter http://tempuri.org/:GetPublicationPagesResult. The InnerException message was 'Object graph for type 'xxx.Entities.TblPublicationPage' contains cycles and cannot be serialized if reference tracking is disabled.
[Query]
public IQueryable<TblPublicationPage> GetPublicationPages(int publicationId)
{
return this.PublicationLogic.Value.GetPublicationPages(publicationId);
}
I know how to enable it for plain WCF through CyclicReferencesAware attribute or IsRefence=true. But I can't figure out how to do this with WCF Ria Services.
I now understand WCF Ria Services better, I just tried to fix it like I would do it in plain WCF and added a metadataclass to my generated entities:
[DataContract(IsReference = true)]
[DataServiceKey("PublicationPageID")]
[DebuggerDisplay("PublicationPageID: {PublicationPageID}")]
[MetadataType(typeof(TblPublicationPageMetadata))]
public partial class TblPublicationPage
{
internal sealed class TblPublicationPageMetadata
{
[DataMember]
public int PublicationPageID { get; set; }
}
}
Only disadvantages at this point is I have to decorate every property in the metadata class with a [DataMember] attribute...
Use [CyclicReferencesAware(true)]

Can i use datacontracts in WCF for streaming

Please can i use datacontracts in WCF for streaming instead of message Contract.
If yes, will it offer any performance improvement?
THanks
Answer depends on binding you use. For TCP or Named pipe transport protocols you can stream any data - including data contracts. If you want to use streaming over HTTP (supported by BasicHttpBinding) you have to some several constraints:
Streaming has to be allowed on binding
Operation has to work with Stream instance or Message contract which contains only single body element of type Stream. Data contracts are allowed only as custom message headers on Message contract.
Only valid operation definitions for streaming over HTTP are:
// StreamedResponse
[OperationContract]
Stream GetData(int id);
// StreamedRequest
[OperationContract]
int PostData(Stream data);
// Streamed
[OperationContract]
Stream WorkWithData(Stream data);
[OperationContract]
DoSomethingResponse DoSomething(DoSomethingReqest request);
[MessageContract]
public class DoSomethingRequest
{
// Custom data and data contract allowed only as SOAP headers which are always buffered
[MessageHeader]
public MyDataContract CustomHeader { get; set; }
// No other member allowed
[MessageBodyMember]
public Stream Data { get; set; }
}
[MessageContract]
public class DoSomethingResponse
{ ... }
If you don't follow these constraints you will end up with two cases:
Operation is not streamed even if you configure binding for streaming - this happens if you don't use Stream instance as message content
Exception - this happens if you use Stream instance + other data / data contract as message content

Problem in consuming WCF service (basicHttpBinding) in Delphi Win32 Client

I am trying to make a Delphi client (Delphi 2006) to communicate with a service written using WCF. Service is damn simple with just one function. Technically like below:
[ServiceContract (Namespace = "http://www.company.com/sample/")]
public interface IService
{
[OperationContract]
string GetNumber (string name);
}
I have hosted this service on IIS and exposed it using basicHttpBinding with mex end point. I am able to use it in .NET clients.
I tried to run WSDLImp.exe and it generated a source code unit (btw, it generates wierd classes to encapsulate string type. Why cant it be same as Delphi string type?). When I try to call this service, I get the exception:
The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
I don't see any way to configure the Delphi Win32 client to changing the binding or security parameters. How can I fix this problem?
I've had the exact same problem. Delphi just has hard time importing the WSDL exposed by WCF. One solution is to add an ASMX wrapper to your service and use that with Delphi clients.
Here's an example:
[ServiceContract (Namespace = "http://www.company.com/sample/")]
public interface IService
{
[OperationContract]
string GetNumber (string name);
}
public class Service : IService
{
public string GetNumber (string name)
{
return Repository.GetNumber(name);
}
}
[WebService(
Namespace = "http://www.company.com/sample/",
Name = "wstest",
Description = "description")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AsmxService : WebService
{
[WebMethod]
public string GetNumber(string name)
{
return Repository.GetNumber(name);
}
}
You need to look at the network traffic between the client and service to see what's going on. Alternatively, turn on WCF tracing on the service, possibly including message tracing. You should be able to see what's going on, in great detail.