I have a simple odx that constructs a message of type System.String, then pushes out through a send port.
The content of the output message is good except it's prefixed with:
<?xml version="1.0"?>
<string>
e.g.
<?xml version="1.0"?>
<string>
Good plain text format here
How can I prevent the content being wrapped with the without having to resort to a custom pipeline component?
Write the string directly to the XLANGMessage in a helper library (as if you were writing binary data to a message), and make sure to use a pass through transmit pipeline. I'm not sure if this would work with a System.String message or not, but I know it'd work with an XmlDocument message.
e.g.
public static void LoadXLANGMsgFromString(string source, XLANGMessage dest)
{
var bytes = Encoding.UTF8.GetBytes(source);
using (MemoryStream ms = new MemoryStream(bytes, 0, bytes.Length, false, true))
{
dest[0].LoadFrom(ms);
}
}
You need to use that constructor of MemoryStream to make sure the base data stream is exposed for XLANGs to make use of. Then, in an Orchestration message assignment shape:
msg = new System.Xml.XmlDocument();
Helper.LoadXLANGMsgFromString("Good plain text format here", msg);
Orchestration is expected to work with xml only typed or untyped. With string type, it automatically creates a xml wrapper over it. I think there will not be any way around it, unless you want to use a custom send pipeline component to take out the xml tag before writing.
Related
We are using https://github.com/Azure/amqpnetlite from the Azure team.
The description says we have to use the AmqpContract and AmqpMember attribute classes over the message bus like ActiveMQ.
We also have a lot of classes and we want to migrate to this Amqp library, but is it possible to use the serializer without those attributes and to use our POCO classes directly?
Another workaround could(?) be to serialize or classes into a json and use a wrapper class to send our payload:
[AmqpContract]
public class OurMessage
{
[AmqpMember]
public string JsonPayload {get;set;}
}
or should we avoid this workaround?
The POCO classes as you mentioned are not supported right now. You will need to pick another serializer. Once you have the JSON string or a byte array, you do not need to define a wrapper class. Just directly create an AMQP message with the payload and get it back from the message body on the receiver side.
// sender
var msg = new Message(jsonPayload);
sender.Send(msg);
// receiver
var msg2 = receiver.Receive();
var jsonPayload = msg2.GetBody<string>();
Same thing can be done for byte array.
The AMQP serializer is designed to be simple and everything has to be explicitly annotated. For most cases this is possible and it helps to avoid double encoding and enable easier inter-op with other AMQP clients.
I'd like to create a generic API endpoint that a client can post text or file data to, where we won't know the content/media type of the data. It seems the framework requires a content formatter to be specified for any content-type passed in the HTTP header, or it throws an error. I don't want to have to define a formatter for every possible media type we might accept since we don't know yet what all they could include.
Is there a way to define an endpoint with a generic media type formatter, or not specify one at all? It doesn't seem to mind if I use a generic Object as my method parameter, but the framework keeps getting hung up on not being able to handle the media type without a formatter.
We don't actually need to be able to process this data, just store it (for something like a messaging system).
On a side note, I'd rather receive this data as the raw content of the request body and not use a multipart form request, but if it would make more sense to do it that way, it might be an option.
Or if you want to go even more low level than Youssef's suggestion, you can do..
public Task<HttpResponseMessage> Post(HttpRequestMessage request) {
var stream = await request.Content.ReadAsStreamAsync();
return new HttpResponseMessage(HttpStatusCode.Ok) { RequestMessage = request } ;
}
You can bypass formatters entirely by reading the content yourself. Here's an example:
public async Task Post()
{
string content = await Request.Content.ReadAsStringAsync();
// Store away the content
}
This doesn't require you to use or define any formatters at all.
How to generate xml file which contain all the fields of a component in SDl Tridion?
I have to do this by writing C# code.
I am using the following code:
public class stockcompany : ITemplate
{
private Engine engine;
private Package package;
public void Transform(Engine engine, Package package)
{
this.engine = engine;
this.package = package;
StringBuilder sb = new StringBuilder();
Component component = engine.GetObject(package.GetValue("Component.ID")) as Component;
ItemFields componentfields = new ItemFields(component.Content, component.Schema);
ItemFields compometa = new ItemFields(component.Metadata, component.Schema);
if (compometa.Contains("check"))
{
}
if (componentfields.Contains("companyname"))
{
string company = string.Empty;
company = componentfields["companyname"].ToString();
package.PushItem("xml", package.CreateHtmlItem(company.ToString()));
XDocument myxml = new XDocument (new XDeclaration ("1.0","UTF-8",null ),new XElement ("companies",new XElement ("company",xml)));
}
You are probably re-inventing the wheel here.
Tridion items are XML. The .Content and .Metadata properties of a component return XML, would this be enough?
DD4T uses templates that publish XML to the delivery side, might be worth checking it: http://code.google.com/p/dynamic-delivery-4-tridion/
Given that DD4T is open sourced, you may want to check how they do it as an example.
Another approach to generating XML is to use an XmlSerializer. It works as follows:
Create a POCO
Fill it with values from the component
Use XmlSerializer to deserialize it into an XML string
Store the XML in the Output variable of the package
This is how DD4T does it. As Nuno said, it is worth while to check it out (see his answer).
I've typically resorted to XSLT to get source XML via a component template, but we can definitely do the same with C#.
[TcmTemplateTitle("Show XML Guts")]
public class ShowXmlGuts : ITemplate
{
public void Transform(Engine engine, Package package)
{
Item contentItem = package.GetByType(ContentType.Component);
Component component = engine.GetObject(contentItem.GetAsSource().GetValue("ID")) as Component;
package.PushItem("componentSource", package.CreateHtmlItem(component.Content.OuterXml));
}
}
Pick-and-Choose Fields
If at all possible, I'd start with an intermediate XML format that's not a one-to-one mapping to component source.
We're meant to get and transform fields with the appropriate APIs. Relying on the source component format could be problematic in your next major change, which could include:
schema changes and new keywords
presentation/rendering side or CMS changes
"unexpected" content (rich text, special characters, tcm references, etc)
Alternatives to C#
In terms of technology:
XSLT is great for "XML generation," even if done in a C# template building block.
The XSLT Mediator would a good choice, if allowed in your environment
You could create XML with DWT, simplifying field selection; however, it's easier to create invalid XML this way (XSLT doesn't validate your XML either, but it's slightly harder to break node nesting)
If possible, update your question with the output XML you're trying to achieve or start a new question to get from your raw component XML to desired output.
Your code isn't very clear and contains a lot of problems, but generally you seem to be on the correct track.
1) You need to cast your
componentfields["companyname"].ToString();
I suspect you're working with a TextField here so cast it to a TextField object and then use the objects .value property
2) Here is where you push the value into the package, this will contain whatever you got from your 'companyname' field, it could be xml, it may not be:
package.PushItem("xml", package.CreateHtmlItem(company.ToString()));
..But I think with this information you can find your way to what you need.
Good luck!
I have been writing some Web services to be used by a few different client apps and i was trying to write a web service method that simply outputs an RSS XML Feed.
I can create the XML using an XmlTextWriter Object
Then i have tryed outputing to the Response (like i have done in the past when its an aspx page) but this only works it the return type is void (and still doesnt seem to output properly)
Then i tryed making the return type a string and using a StringWriter to output the xml from the XmlTextWriter but the output is then wrapped in a tag.
How can i do this?
Obviously create the interfaces and rest of the WCF service as normal.
Mark the class with the following attribute
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
And then this function
public Stream GetRSS()
{
string output;
//output = some_text;
MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(output));
WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
return ms;
}
I have some code for this, but it's more than will fit well in an SO post (about 1000 lines). It's really not that hard; the schema is simple enough you can do it yourself, but you don't have to: there are several components you can just plug in to create the xml for you.
You should see this question:
ASP.Net RSS feed
If you must use ASMX, then you can return an XmlDocument. Build the feed XML however you like, but then return the XmlDocument from your web method.
I have one JSON that is coming in a string format. I need to store it in a key-pair value or something like that. I am using asp.net 2.0 and can not use 3rd party DLL like Newtonsoft.Json.dll. I guess last option will be to use regular expression.
Can anybody please help me in this?
If you go to http://www.json.org/ and look towards the bottom of the page there are dozens of json libraries most of them open source, I believe they list 8 for C#. If you can not reference one of these libraries, I think your best bet would be to find one with a permissive license and simply add the code to your project.
Another idea is to look at the diagrams, grammer, and syntax at http://www.json.org/ and just write your own parser, but regex is NOT the way to do it. If you dont know how to write a parser you could look at one of the open source json libraries or start with something less complicated like a good CSV parser, here is a paper that looks pretty good: http://www.boyet.com/Articles/CsvParser.html
It is possible to serialize JSON using JScript in C# into key/value pairs. You need to add a few references to your project. They're part of the .NET framework, you just need to add the references to your project. You'll need:
Microsoft.JSript
Microsoft.Vsa
First, the usings at the top of your class:
using Microsoft.JScript;
using Microsoft.JScript.Vsa;
Then the Engine that will execute the script needs to be initialized somewhere in your 'Page' code-behind:
VsaEngine Engine = VsaEngine.CreateEngine();
Then you just create this method and call it by passing in your JSON object:
object EvalJScript(string JScript)
{
object result = null;
try
{
result = Microsoft.JScript.Eval.JScriptEvaluate(JScript, Engine);
}
catch (Exception ex)
{
return ex.Message;
}
return result;
}
The type of object returned (if JSON is passed in) is a 'JSObject'. You can access its values as key/value pairs. Read the MSDN documentation for more details on this object.
Here's an example of using the code:
string json = "({Name:\"Dan\",Occupation:\"Developer\"})";
JSObject o = EvalJScript(json) as JSObject;
string name = o["Name"] as string; // Value of 'name' will be 'Dan'
Could you use JScript.NET?
If so, should be easy enough with eval() - then just loop through the objects returned and translate into KeyValuePair's or whatever
You will need to use jscript.net as the code behind language, but other pages of your site should be fine to stay as c# if thats what you prefer.
As mentioned in previous comment, you will need to be aware of the security aspects and risks - only use eval if you trust the JSON you're parsing!