Cannot send message to SQL Server 2008 Service Broker: The message type '<message type>' is not part of the service contract

StackOverflow https://stackoverflow.com/questions/22722338

Question

I'm trying to learn the basics of Service Broker, and have created an application originally based on the SSMS template. However I can't send a message to my queue. It just says the message type is not part of the service contract.

The absolute bare minimum I need to recreate this is the following batch:

USE [test_db]
GO

CREATE MESSAGE TYPE [test_message] 
AUTHORIZATION [dbo] 
VALIDATION = WELL_FORMED_XML
GO

CREATE CONTRACT [test_contract] 
AUTHORIZATION [dbo] (
    [test_message] SENT BY ANY
)
GO

CREATE QUEUE [dbo].[test_queue] 
WITH STATUS = ON 
    ,RETENTION = OFF
    --,ACTIVATION (
    --   STATUS = ON 
    --  ,PROCEDURE_NAME = [dbo].[test_activator]
    --  ,MAX_QUEUE_READERS = 1
    --  ,EXECUTE AS N'dbo'  
    --) 
ON [PRIMARY] 
GO

CREATE SERVICE [test_service]  
AUTHORIZATION [dbo] 
ON QUEUE [dbo].[test_queue] (
    [test_contract]
)
GO

BEGIN TRANSACTION

    DECLARE @dialog_handle UNIQUEIDENTIFIER

    BEGIN DIALOG @dialog_handle
    FROM SERVICE test_service
    TO SERVICE N'test_service';

        SEND ON CONVERSATION @dialog_handle
        MESSAGE TYPE test_message (N'<test />');

    END CONVERSATION @dialog_handle;

COMMIT TRANSACTION
GO

...which yields:

Msg 8431, Level 16, State 1, Line 10
The message type 'test_message' is not part of the service contract.

I only need to be able to send asynchronous messages within the same database. There are no remote connections to consider, and I don't strictly even need to handle a reply.

I've checked and double-checked that the message type, contract, queue and service all exist and the properties of the contract says that the message type is included

What am I missing?

Was it helpful?

Solution 2

Try this:

BEGIN DIALOG @dialog_handle
FROM SERVICE test_service
TO SERVICE N'test_service'
ON CONTRACT test_contract;

OTHER TIPS

As Denis already answered, you're missing the ON CONTRACT test_contract.

If you omit it then the DEFAULT contract is used. Every database has a contract named DEFAULT which has one message type, also named DEFAULT. The DEFAULT contract is used when you omit any contract in BEGIN DIALOG and the DEFAULT message type is used when you omit the message type in SEND:

BEGIN DIALOG @dialog_handle
    FROM SERVICE test_service
    TO SERVICE N'test_service'; <-- will use the DEFAULT contract

SEND ON CONVERSATION @dialog_handle 
    (N'<test />'); <-- will use the DEFAULT message type

DEFAULT message type has no validation. The DEFAULT contract binds the DEFAULT message type to both initiator and target (both can send the message in this contract, ie. SENT BY ANY). Contract and message type names are always case sensitive, irrelevant of database collation, so the name DEFAULT is case sensitive.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top