Bind XMLDataSource to HTTP handler - asp.net

I have some dynamically generated XML data that will be consumed by a few consumers (An ASPX page, a flash file and maybe another one as well).
I have implemented it as a custom handler. I construct the XML in the handler and output it using response.write.
Now If I set the DataFile property of my XMLDataSource to the handler, it tries to read the ashx file literally and does not call it through HTTP.
Any advice?

Place your XML generation code in a separate class. Have the handler use the class to create the XML and send the results to the client (BTW, don't use Response.Write what XML document tech are you using to build the XML in the first place?).
Make sure the class can expose the completed XML as a string.
In your ASPX page use the same class and assign the XML string to the data property of your XmlDataSource control.
Edit:
Since you are using a XmlTextWriter and from your comment the above is apparently a bit confusing I'll add these details.
You need to take the code that currently generates the XML and place it in a class in the App_Code folder (or possibly in a dll project). This class will have a method that takes as a parameter an XmlTextWriter.
public class XmlCreator
{
public void GenerateXml(XmlTextWriter writer)
{
//All your code that writes the XML
}
}
In your handler you then have this code:-
XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, Encoding.UTF8);
XmlCreator creator = new XmlCreator();
XmlCreator.GenerateXml(writer);
Note no need for Response.Write and this gets the encoding done properly.
In your ASP.NET page you use:-
StringWriter source = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(source, Encoding.Unicode);
XmlCreator creator = new XmlCreator();
XmlCreator.GenerateXml(writer);
yourXmlDataSource.Data = source.ToString();
XmlCreator may not need to be instanced in which case you could use a static class it depends on what other data is need to feed the XM generation.

Related

generating xml containg fields of a component in sdl tridion

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!

how to access application.get from generic handler

I have a global.asax in which I define some variables that I want to be available throughout the application, such as a class to handle certain database requests. In an aspx page, I can access these variables/objects using for example in Visual Basic:
dim dataMan as clsData = application.get("dataGofer")
My question: is it possible to call this from a generic handler (.ashx file)? If so, can you please show me a code snippet? Thanks!
You have Context parameter of ProcessRequest method through which you can access the page objects.
Dim value=context.Application.Get("key")

How to pass data between pages without sessions in ASP.net MVC

I have one application in which I want to pass data between Pages (Views) without sessions. Actually I want to apply some settings to all the pages using query string.
For example if my link is like "http://example.com?data=test1", then I want to append this query string to all the link there after and if there is no query string then normal flow.
I was thinking if there is any way that if we get the query string in any link for the web application then some application level user specific property can be set which can be used for subsequent pages.
Thanks,
Ashwani
You can get the query string using the
Request.Url.Query
and on your links to the other page you can send it.
Here is an idea of how you can find and change your page:
public abstract class BasePage : System.Web.UI.Page
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
// now you render the page on this buffer
base.Render(htmlWriter);
// get the buffer on a string
string html = stringWriter.ToString();
// manipulate your string html, and search all your links (hope full find only the links)
// this is a simple example of replace, THAT PROBABLY not work and need fix
html = html.Replace(".aspx", ".aspx?" + Request.Url.Query);
writer.Write(html);
}
}
I do not suggest it how ever, and I think that you must find some other way to avoid to manipulate all your links...
I don't undestand what kind of data are you trying to pass. Because it sounds weird to me the idea of trapping all links.
Anyway, I believe you may find the class TempData usefull for passing data between redirects.
And a final warning, be carefull about TempData, it has changed a little between MVC 1 and 2:
ASPNET MVC2: TempData Now Persists

Make an ASP.NET Web service output an RSS Feed

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.

Dynamic XML

What's the ideal way of generating XML without creating and saving a file?
I'm thinking of using an ASP.NET page with code behind to generate the markup as XML.
Is this possible? Or would you have an alternative way?
I have a flash component that reads an XML file and I need to dynamically generate this file. I don't have write permission so I won't have the ability to create and save a file.
I was thinking of having an application page that grabs the data and provide property methods to generate the xml on the Settings.xml.aspx page with Settings.xml.aspx.cs codebehind.
Thanks.
The easiest way is to use System.Xml.XmlDocument or System.Xml.Linq.XDocument to build up the document. Both can be streamed out to the Response.OutputStream.
The smoothest approach (especially if you turn off buffering) is simply to create an XmlTextWriter round the Response.OutputStream. This is a forward only approach to generate XML but if the output is large it means you need less memory and content starts to arrive at the client earlier.
System.Xml.XmlDocument ?
In fact there are many ways to do it. It all depends on your needs. Maybe you could have a look at some examples of XDocument (or XmlDocument in .NET 2.0) and XmlWriter, none of these require you to save the XML to a file. You can either keep the object model in memory when using XDocument or write to a MemoryStream when using XmlWriter:
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
{
using (XmlWriter writer = XmlWriter.Create (stream, settings))
{
writer.WriteStartElement ("customer");
writer.WriteElementString ("firstname", "Jim");
writer.WriteElementString ("lastname"," Bo");
writer.WriteEndElement();
}
// do further processing with the stream
}
The difference between the two is basically that the first one gives you access to the DOM whereas the second one simply writes out XML to an underlying stream.
Unfortunately, without knowing more details this question can only be answered vaguely.
Yes, it is perfectly feasible to generate XML "on the fly". Take a look at the XmlDocument class. And more info here.

Resources