问题
I get a "faulted state" error when working with the Core Service in SDL Tridion 2011 SP1. What's wrong with the following?
namespace coreservice1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
using (ChannelFactory<ISessionAwareCoreService> factory =
new ChannelFactory<ISessionAwareCoreService>("wsHttp_2011"))
{
ISessionAwareCoreService client = factory.CreateChannel();
string SCHEMA_URI = "tcm:7-426-8";
var schemaFields = client.ReadSchemaFields(SCHEMA_URI, true, new ReadOptions());
foreach (var field in schemaFields.Fields)
{
Response.Write(string.Format("{0}", field.Name));
}
Response.Write(schemaFields.NamespaceUri);
string NEW_COMPONENT_FOLDER_URI = "tcm:8-15-2";
Tridion.ContentManager.CoreService.Client.ComponentData component = new Tridion.ContentManager.CoreService.Client.ComponentData
{
Schema = new LinkToSchemaData { IdRef = "tcm:8-426-8"},
Title = "Helloworldalll",
Id = "tcm:0-0-0",
LocationInfo = new LocationInfo
{
OrganizationalItem =
new LinkToOrganizationalItemData { IdRef = NEW_COMPONENT_FOLDER_URI}
},
};
string namespaceUri = schemaFields.NamespaceUri;
System.Text.StringBuilder content = new StringBuilder();
string First = "Hello World.This is Fisrt field";
content.AppendFormat("<{0} xmlns=\"{1}\">", schemaFields.RootElementName, namespaceUri);
content.AppendFormat("<{0} xmlns=\"{1}\">{2}</{0}>", "first", namespaceUri, First);
content.AppendFormat("</{0}>", schemaFields.RootElementName);
component.Content = content.ToString();
ComponentData comp = (ComponentData)client.Create(component, new ReadOptions());
string newlyCreatedComponentID = comp.Id;
Response.Write("Hello hai");
Response.Write("Id of newly created component: " + newlyCreatedComponentID);
}
}
catch (Exception ex)
{
Response.Write(ex.StackTrace);
Response.Write("exception is " + ex.Message);
}
}
}
}
“at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelFactory.OnClose(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelFactory.TypedServiceChannelFactory`1.OnClose(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout) at System.ServiceModel.ChannelFactory.OnClose(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout) at System.ServiceModel.ChannelFactory.System.IDisposable.Dispose() at coreservice1._Default.Page_Load(Object sender, EventArgs e) in D:\SampleProjects_Tridion\test\coreservice1\coreservice1\coreservice.aspx.cs:line 73exception is The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.“
回答1:
I think this might be to do with the way you instantiate your client object.
You can add this as Service Reference in Visual Studio:
e.g. Add Service reference to http://{your tridion url}/webservices/CoreService.svc and give it a namespace of TridionCoreService, then you can use it like this:
TridionCoreService.CoreService2010Client client = new TridionCoreService.CoreService2010Client();
Alternatively you can use the method here which allows you to create a Core Service reference without needing a config file.
回答2:
Sending an example I created time ago in case that helps.....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CoreWebService.ServiceReference1;
namespace CoreWebService
{
class CoreWebServiceSamples
{
public static void createComponent()
{
string schemaWebDavUrl = "/webdav/020%20Content/Building%20Blocks/Content/wstest/wstest.xsd";
string folderWebDavUrl = "/webdav/020%20Content/Building%20Blocks/Content/wstest";
CoreServicesUtil coreServicesUtil = new CoreServicesUtil();
FolderData folderData = coreServicesUtil.getFolderData(folderWebDavUrl);
ComponentData componentData = folderData.AddComponentData();
componentData.Title = "This is a Test ..... ";
componentData.Schema = coreServicesUtil.getLinkToSchemaData(schemaWebDavUrl);
SchemaData schemaData = coreServicesUtil.getSchemaData(schemaWebDavUrl);
componentData.Content = xmlUtil.GetNewXmlNode("Content", schemaData.NamespaceUri);
componentData.Metadata = xmlUtil.GetNewXmlNode("Metadata", schemaData.NamespaceUri);
componentData.AddSingleField("singlefield", "singlefield sample", schemaData.NamespaceUri);
componentData = (ComponentData)coreServicesUtil.coreServiceClient.Save(componentData, coreServicesUtil.readOptions);
coreServicesUtil.coreServiceClient.CheckIn(componentData.Id, coreServicesUtil.readOptions);
coreServicesUtil.coreServiceClient.Close();
}
}
}
The CoreServicesUtil.....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CoreWebService.ServiceReference1;
using CoreWebService.Properties;
using System.Xml;
using System.Xml.Serialization;
namespace CoreWebService
{
public class CoreServicesUtil
{
public CoreService2010Client coreServiceClient;
public ReadOptions readOptions;
/// <summary>
///
/// </summary>
public CoreServicesUtil()
{
this.coreServiceClient = new CoreService2010Client("basicHttp_2010");
this.readOptions = new ReadOptions();
}
public FolderData getFolderData(string tcmuri)
{
FolderData folderData = (FolderData)coreServiceClient.Read(tcmuri,ReadOptions);
return folderData;
}
public LinkToSchemaData getLinkToSchemaData(string tcmuri)
{
LinkToSchemaData linkToSchemaData = new ServiceReference1.LinkToSchemaData();
linkToSchemaData.IdRef = getSchemaData(tcmuri).Id;
return linkToSchemaData;
}
public SchemaData getSchemaData(string tcmuri)
{
SchemaData schemaData = (SchemaData)coreServiceClient.Read(tcmuri, readOptions);
return schemaData;
}
}
}
The XMLUtil ....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
namespace CoreWebService
{
public class xmlUtil
{
/**
* <summary>
* Name: enumeration
* </summary>
**/
public enum Scope
{
Content,
Metadata
}
/**
* <summary>
* Name: AddItemLinkFieldGeneric
* Description: basic method for add component links, multimedia links, keyword field to an XmlElement
* </summary>
**/
/**
* <summary>
* Name: getXMLElementData
* Description: adds a single field to an XmlElement
* </summary>
**/
public static XmlElement getXMLElementData(string dataNode)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(dataNode);
return doc.DocumentElement;
}
/**
* <summary>
* Name: GetNewXmlNode
* Description: returns an xml element based on the name and schema
* </summary>
**/
public static string GetNewXmlNode(string Name, string Namespace)
{
XmlDocument doc = new XmlDocument();
XmlElement xmlElem = doc.CreateElement(Name, Namespace);
doc.AppendChild(xmlElem);
return doc.FirstChild.OuterXml;
}
}
}
回答3:
Does it actually create the component? Do you get that far?
I normally write a wrapper class for CoreService, implement IDisposable
and use the following methods in it:
private void InitializeClient()
{
NetTcpBinding binding = new NetTcpBinding { MaxReceivedMessageSize = 2147483647 };
XmlDictionaryReaderQuotas quota = new XmlDictionaryReaderQuotas
{
MaxStringContentLength = 2147483647,
MaxArrayLength = 2147483647
};
binding.ReaderQuotas = quota;
_client = new SessionAwareCoreServiceClient(binding, _endpointAddress);
if (_client != null) _coreServiceVersion = _client.GetApiVersion();
}
and
public void Dispose()
{
if (_client.State == CommunicationState.Faulted)
{
_client.Abort();
}
else
{
_client.Close();
}
}
来源:https://stackoverflow.com/questions/9922827/faulted-state-error-while-creating-component-with-core-service