I tried to rename a file before sending the file to an ftp location using the SFTP adapter in BizTalk 2013. Can you help me on this ?
You need to change the FILE.ReceivedFileName property on the message to your new filename.
If you use an orchestration you can do this in an expression within a message assignment shape as follows:
OutboundMessage(FILE.ReceivedFileName) = "NewFileName.csv"
If you aren't using an orchestration you have to use a custom pipeline component.
The code to do this within the component is as follows, which goes in the pipeline component's Execute method:
pInMsg.Context.Write("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", "NewFileName.csv");
Finally in the SFTP adapter set the filename to %SourceFileName%
Hope this helps.
I believe the URL for the context is different per adapter.
The one you need is:
SFTP:
http://schemas.microsoft.com/BizTalk/2012/Adapter/sftp-properties
So in your case it would be :
pInMsg.Context.Write("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2012/Adapter/sftp-properties", "NewFileName.csv");
Thx
Related
I am going to parse and format the flat file input based on the business logic stored in SQL server database tables. I don’t have a document schema for the input. I wrote a C# custom component class for the disassemble. When I use the custom component in Disassemble stage in receive pipeline, I am getting document schema not found error.
Did anyone come across with same situation and handled it differently? .
BizTalk routes messages using the 'MessageType' property (The namespace + the root node name of the XML in the message) in the context portion of the message. You don't have that with your design so it doesn't know what to do with it.
You can:
handle each type of flat file separately by parsing and assigning a unique message type
distill the content into one type of message
wrap the content of the file in an 'envelope'
You'll need to create a schema for any of those choices.
Namespaces and routing are a spiffy way to handle changes to file structure. If you include the version of the file in the namespace BizTalk can route the message to the code that handles that kind of message for you. You can continue to handle old style messages as well as new formats. We handle pilot programs that way.
A while back I set up BizTalk to pick up a file via FTP and drop it into a network directory. It's all passsthru so I didn't use an orchestration.
Now I've been asked to execute a stored procedure once the file is picked up. The procedure contains no parameters and I do not need the contents of the file.
It seems like such a simple request but I can't figure it out. Is there any way to do this without over complicating things?
This can be accomplished through the use of either the WCF-SQL adapter or the WCF_Custom adapter with a SQL binding. You can do this using messaging only with just a SendPort with a filter/map on it thus no orchestration needed.
For the SOAP action header use TypedProcedure/dbo/name_of_your_stored_procedure and in the messages tab you can specify the paramters to the stored procuders as well as add a payload in the following manner:
<name_of_your_stored_procedure xmlns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo">
<parameter1>XXXX</parameter1>
<xml_parameter>
<bts-msg-body xmlns="http://www.microsoft.com/schemas/bts2007" encoding="string"/>
</xml_parameter>
</name_of_your_stored_procedure>
In the above case xml_parameter will have the contents of the message payload passed to it.
The stored procedure should look something like :
CREATE PROCEDURE [dbo].[name_of_your_stored_procedure]
#parameter1 int,
#xml_parameter nvarchar(max)
AS
BEGIN
-- your code goes here
END
More details can be found here
Regards Hasse
This MSDN page describes the process and has this to say: "You must create a BizTalk orchestration to use BizTalk Server for performing an operation on SQL Server."
However if you're really desperate not to use an orchestration I believe you have the option of setting the operation context property in a custom pipeline component. Then you can initialise the message in a map on a port. In theory this should work but I can't guarantee it.
Is it possible to make the send port change output location based on a promoted property?
We have an interface that needs to send it to a different port based on the client. But we add clients on a regular basis, so adding a new send port (both in the administrator and orchestration) will require a lot of maintenance, while the only thing that happens is a directory change
The folders are like this ...
\\server\SO\client1\Out
\\server\SO\client2\Out
\\server\SO\client3\Out
I tried using the SourceFilename to create a file name like client1\Out\filename.xml but this doesn't work.
Is there any way to do this with a single send port?
It is possible to set the OutboundTransportLocation property in context. This property contains the full path/name of the file that will be output by the file adapter. So in your case I guess you could do something along the line (if it had to be done in a pipeline component):
message.Context.Write(
OutboundTransportLocation.Name,
OutboundTransportLocation.Namespace,
string.format(#"\\server\SO\{0}\Out", client));
Of course you can do a similar thing in your orchestration.
No need of a dynamic port...
I have a requirement:
If I get a file, I am putting the content of that file into a database,
If there is any error in that file, I am putting it in an error folder.
Can I do something like this? Suppose I have a folder "processed" and another one "unprocessed". In case of an error, result will go in "unprocessed" and if there is no error it will go into "processed".
I don't know how to achieve that if biztalk processed some file then only put into some folder.
I suppose if I will put filter option BTS.ReceivePortName it will also put the error file into process folder.
It's very easy to create an extra send port that archives all input files.
If there's an error you just find the file, fix the issue, and re-drop it.
Create a send port, set up the filters to select the input you want (like BTS.ReceivePortName as you already know), use a pass through pipeline, then configure it as to write files. Write your files to a backup directory.
If you only want to catch errors then you will have to do extra setup. You must use an orchestration. Put a scope shape around your normal processing in the orchestration. Place an exception to catch errors on the scope shape. In the exception handler use a send shape to construct and write a copy of the original message to a send port. Add an expression to write some helpful message to the event log so you can debug the failure.
Is there any way to set BTS.RetryCount or WCF.Action not in a Message Assignment Shape?
I have a special orchestration for dynamic message sending, its parameters are Message and ServiceName and it has a dynamic port which is easily configured with UDDI service. The thing I can't do in that orchestrations is I can't set WCF.Action for a message, I should create a new one because it's prohibited in BizTalk to modify a message anywhere outside a Construct shape. So it's very inconvenient for me to set this property every time I want to send a message, I thought I would be able to do all the UDDI & routing stuff in a one dedicated orchestration which I later can just call with parameters.
Can you not modify those properties in a pipeline component? You can then execute the pipeline inside the orchestration.
UPDATE
What I mean is you can create a pipeline component to set the context properties of the message as it passes through. Then you can create a pipeline which includes this component and execute it inside your orchestration by passing a message through it. This message will then have those context properties set.
Could you not create a new message in an assignment shape, of the same type as the message you need to modify
NewMessage = OldMessageWithTheDynamicPropertiesSet;
and copy over all the properties
NewMessage(*)* = OldMessageWithTheDynamicPropertiesSet(*);
and then set the properties you need to set. You can also set the WCF action that way.
NewMessage(WCF.Action)=....
NewMessage(BTS.REtryCount)= 666
And then you send this new message out.