views:

168

answers:

4

Has anyone had luck with using a .NET web service to access Sitecore items? I have a number of web applications on my server that are still in Coldfusion. I'd like to be able to call a web service to pull down items, but when I tried to do this I got an exception "Sitecore.Data.Items.Item cannot be serialized because it does not have a parameterless constructor."

+2  A: 

Take a look at Sitecore standard web service, you can find it under /sitecore/shell/WebService folder of your solution. It offers some basic operations with Sitecore items and fields, but it is often enough for pulling or saving data.

Hope this helps.

Yan Sklyarenko
Thanks for the tip. I think I've basically concluded this can't be done though.
Kyle
can you explain further why the standard service won't work for you? based on everything you're saying here, it sounds like the best solution
techphoria414
I'm sure it would work in some way. The key here is that I want to be able to reuse methods I've already written to retrieve a specific set of items that are used inside of a web control on one of my sitecore pages. Basically I don't want to have two different pieces of code to maintain that do essentially the same thing.
Kyle
A: 

If the Sitecore standard web service doesn't give you what you need, why not write a custom HttpHandler or MCF service or, simplest yet, a Sitecore layout to output your Items in a format that can be consumed by ColdFusion? Is there a reason you need to directly serialize the Item?

techphoria414
Well, the main problem with this is I don't need a single item, I need a collection of items. And I want to be able to reuse methods I've already written and am using in web controls, sublayouts, etc. There's a number of "workable" ways to do this. I'm just looking for the cleanest way to do it.
Kyle
sorry your needs are really unclear, can you update your question with more specifics?
techphoria414
read up on some of the other comments
Kyle
A: 

I answered this on the SDN forum as well. You can create your own wrapper object which is filled with a Sitecore item and sets its members. The hard part will be creting your members and assigning them from the real Sitecore item. If you want everything then I think it will be difficult. If you just want some stuff then its doable. E.g.

[Serializable]
public class SitecoreItem {
  public string ID;
  // more members

  SitecoreItem(Sitecore.Data.Items.Item scItem) {
      this.ID = scItem.ID;
      // assign more members from the true Sitecore item
  }

}

Then in your WS method fill a new instance with your actual Sitecore item and return it:

return new SitecoreItem(actualSCItem);
Mark Ursino
Thanks, this makes sense. Any ideas on how to make it more generic though? I'd like to have something that I can use for any item to return all fields. I realize you said this would be more difficult, but do you have any ideas as to how to start going about this?
Kyle
You cannot serialize the Sitecore.Data.Items.Item class so your only way would be to create a wrapper and do the work of assigning the members. This solution is generic though if you take the time to go through all of the properties. The only other option would be to use the built-in WS Yan mentioned
Mark Ursino
Can the Fields class be serialized? This would be the key for me. I need to get all the field information and not every template contains the same fields.
Kyle
Hmm, that's a good point. I'm gonna guess you can't because there are many type of actual fields that can exist and you'd need to serialize those and their properties. The `Fields` property is a `Sitecore.Collections.FieldCollection` so you'd need to serialize that as well.
Mark Ursino
A: 

If both the serialiser and the deserialiser have access to the Sitecore database, then you can very easily create a wrapper that just serialises the ID, database name, version and language. Then upon deserialisation on the other end, you can re-fetch the same Sitecore item from the database using that information.

If the deserialiser doesn't have access to the database at all, then it really depends on what your needs are for using the data. I typically loop over all the fields (remember to use item.Fields.ReadAll() first), and store them in a dictionary for easy access. For serialisation, I convert that into a List<T> of key value pairs and ignore the Dictionary member (since it can't be serialised) and then re-populate it on deserialisation. I keep a few other properties like ID, Language, Version, Template, Path, etc. on the class too.

Alternatively, if you create a whole model class library so that each template is mapped to a class (some people do), you can (probably) serialise those straight off since they're (probably) no longer bound to a Sitecore item.

Matt
The whole class library thing is exactly what we do. Each template has a class and each field is mapped to a property. We made a tool in Sitecore to build these automatically. I recommend that approach but only if you can automate it. If not, then that's just as tedious as creating the wrapper for each member of the Sitecore item.
Mark Ursino