Canalblog
Suivre ce blog Administration + Créer mon blog

asp.net

Publicité
Archives
19 février 2010

Percussion rhythmyx CMS Web Service and c#

I've been asked by a client to implement a module that request Percussion Rhythmyx CMS Web Service to search for some documents and get their published url.

I had a big issue because the existing Rhythmyx Web Service does not provide the document's published url. They just provide the Assembly url. I had to implement a small algorithm to get the assembly url and build the published url:

1. I call the FindItem service to get services details
2. I call the GetAssemblyUrls service to get the assembly url of the found items
3. For each Item, I call via HTTP the AssemblyUrl with a specific snipet
4. I parse the returned snipet html content to pick the Published uri
5. I concatenete the resulted uri with the server base url to obtain the full publish http url.

Here is the source code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Services.Protocols;
using PROJ.Common.WSRhythmyx;

namespace PROJ.Common.Rhythmyx
{   
    /// <summary>
    /// Wrapper class to access CMS-Rhythmyx web services
    /// </summary>
    public class RhythmyxManager : IDisposable
    {
        #region Properties
       
        /// <summary>
        /// Security service to login and logout
        /// </summary>
        private securitySOAP _svcSecurity;

        /// <summary>
        /// Content service to get content data (search/get items)
        /// </summary>
        private contentSOAP _svcContent;

        /// <summary>
        /// Contains all RhythmyxManager configuration data
        /// </summary>
        private RhythmyxConfig _config;
        #endregion Properties

        #region Constructor
        /// <summary>
        /// Initialize config data
        /// </summary>
        public RhythmyxManager()
        {
            _config = new RhythmyxConfig();
            _svcSecurity = new securitySOAP();
            _svcSecurity.Url = _buildAddress(_svcSecurity.Url);

        }
        #endregion Constructor

        #region Public Methods
        /// <summary>
        /// Calls the login service to get the session ID
        /// and build the proxy header to transmit the sessionID
        /// </summary>
        public void Login()
        {          
            LoginResponse loginResponse = null;
            try
            {
                //Call Service
                loginResponse = _svcSecurity.Login(_getLoginRequest());

            }
            catch (SoapException ex)
            {
                _logException(ex, "login");
                throw new CMSServiceCallException(ex);
            }
            catch (System.Net.WebException ex)
            {
                _logException(ex, "login");
                throw new CMSNotAccessibleException(ex);
            }
            catch (Exception ex)
            {
                _logException(ex, "login");
                throw new UnSpecifiedCMSException(ex);
            }

            //Create ContentService
            _svcContent = _createContentService(loginResponse.PSLogin.sessionId);

        }

        /// <summary>
        /// Logout the Rhythmyx session
        /// </summary>
        public void Logout()
        {
            if (_svcContent != null && _svcSecurity != null)
            {
                LogoutRequest logoutReq = new LogoutRequest();
                logoutReq.SessionId = _svcContent.PSAuthenticationHeaderValue.Session;

                //Call Service
                try
                {
                    _svcSecurity.Logout(logoutReq);
                }
                catch (SoapException ex)
                {
                    _logException(ex, "logout");
                    throw new CMSServiceCallException(ex);
                }
                catch (System.Net.WebException ex)
                {
                    _logException(ex, "logout");
                    throw new CMSNotAccessibleException(ex);
                }
                catch (Exception ex)
                {
                    _logException(ex, "logout");
                    throw new UnSpecifiedCMSException(ex);
                }
            }
        }

      

        /// <summary>
        /// Call FindItems webs service, and get details for each found items
        /// Search is executed on title field OR on sys_contentid field (Item ID)
        /// Search extract only pdf files
        /// </summary>
        /// <param name="searchParams">Search criterias</param>
        /// <param name="getUrls">
        ///     If false, does not extract published url -> to optimize response time
        /// Url can be extracted later with the GetItemUrl method
        /// </param>
        /// <returns>Items found</returns>
        public RhythmyxItems.RhythmyxDataTable FindItems(string title, string id, string fileName, bool getUrls)
        {
            if (string.IsNullOrEmpty(title) && string.IsNullOrEmpty(id) && string.IsNullOrEmpty(fileName)) throw new CMSEmptySearchCriteriaException();

            RhythmyxItems.RhythmyxDataTable res = new RhythmyxItems.RhythmyxDataTable();         

            #region Set search params
            PSSearchField[] searchParams = new PSSearchField[2];
            //Set service method params
            FindItemsRequest req = new FindItemsRequest();
            req.loadOperations = true;
            req.PSSearch = new PSSearch();
            req.PSSearch.PSSearchParams = new PSSearchParams();
            req.PSSearch.useDbCaseSensitivity = false;
            req.PSSearch.PSSearchParams.Parameter = searchParams;

            ///PDF only search
            searchParams[0] = _createParam("sys_suffix", operatorTypes.equal, ".pdf", connectorTypes.and);

            ///Title search criteria
            if (!string.IsNullOrEmpty(title))
            {
                req.PSSearch.PSSearchParams.Title = new PSSearchParamsTitle();
                req.PSSearch.PSSearchParams.Title.Value = "%" + title + "%";
                req.PSSearch.PSSearchParams.Title.Operator = operatorTypes.like;
                req.PSSearch.PSSearchParams.Title.Connector = connectorTypes.and;
            }
            else if (!string.IsNullOrEmpty(id))
            {
                searchParams[1] = _createParam("sys_contentid", operatorTypes.equal, id, connectorTypes.and);
            }
            else
            {
                searchParams[1] = _createParam("filename", operatorTypes.like, "%" + fileName + "%", connectorTypes.and);
            }
            #endregion Set search params

            #region Create returned structure
            req.PSSearch.PSSearchParams.SearchResults = new PSSearchParamsSearchResults();
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField = new PSSearchResultField[10];
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[0] = _setSearchParamField("author");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[1] = _setSearchParamField("displaytitle");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[2] = _setSearchParamField("sys_title");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[3] = _setSearchParamField("filename");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[4] = _setSearchParamField("sys_lang");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[5] = _setSearchParamField("description");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[6] = _setSearchParamField("item_file_attachment_size");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[7] = _setSearchParamField("sys_suffix");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[8] = _setSearchParamField("reference");
            req.PSSearch.PSSearchParams.SearchResults.PSSearchResultField[9] = _setSearchParamField("sys_currentview");
            #endregion

            #region Call Service
            PSSearchResults[] list = null;
            try
            {
                list = _svcContent.FindItems(req);
            }
            catch (SoapException ex)
            {
                _logException(ex, "FindItems");
                throw new CMSServiceCallException(ex);
            }
            catch (System.Net.WebException ex)
            {
                _logException(ex, "FindItems");
                throw new CMSNotAccessibleException(ex);
            }
            catch (Exception ex)
            {
                _logException(ex, "FindItems");
                throw new UnSpecifiedCMSException(ex);
            }
            #endregion Call Service

            #region Extract data from result structure
            foreach (PSSearchResults val in list)
            {
                RhythmyxItems.RhythmyxRow row = res.NewRhythmyxRow();               
                row.Name = val.name;
                row.ContentType = val.ContentType.name;

                              
                foreach (PSSearchResultsFields field in val.Fields)
                {
                    if (!string.IsNullOrEmpty(field.Value))
                    {
                        switch (field.name)
                        {
                            case "sys_contentid": { row.Id = Convert.ToInt64(field.Value); break; }
                            case "author": { row.Author = field.Value; break; }
                            case "displaytitle": { row.DisplayTitle = field.Value; break; }
                            case "sys_title": { row.SystemTitle = field.Value; break; }
                            case "filename": { row.FileName = field.Value; break; }
                            case "sys_lang": { row.Language = field.Value; break; }
                            case "description": { row.Description = field.Value; break; }
                            case "item_file_attachment_size": { row.Size = field.Value; break; }
                            case "sys_suffix": { row.Type = field.Value; break; }
                            case "reference": { row.Reference = field.Value; break; }
                            case "sys_currentview": { row.CurrentView = field.Value; break; }
                        }
                    }
                }
                res.AddRhythmyxRow(row);
            }
            int count = 0;
            long[] ids = new long[res.Count];
            foreach (RhythmyxItems.RhythmyxRow item in res)
            {
                ids[count] = item.Id;
                count++;
            }

            if (getUrls)
            {
                string[] intranetUrls = _getUrls(ids, EnvConf.EEnvironment.INTRANET);
                string[] internetUrls = _getUrls(ids, EnvConf.EEnvironment.INTERNET);

                count = 0;
                foreach (RhythmyxItems.RhythmyxRow item in res)
                {
                    item.IntranetUrl = intranetUrls[count];
                    item.InternetUrl = internetUrls[count];
                    count++;
                }
            }
            #endregion Extract data from result structure

            return res;            
        }

        /// <summary>
        /// Gets the Item's published URL
        /// </summary>
        /// <param name="id"></param>
        /// <param name="siteName"></param>
        /// <param name="environmentBaseUrl"></param>
        /// <returns></returns>
        public string GetItemUrl(long itemID, EnvConf.EEnvironment environment)
        {
            string res = "";

            #region Set services parameters
            GetAssemblyUrlsRequest req = new GetAssemblyUrlsRequest();
            req.Id = new long[] { itemID };
            req.Template = _config.TemplateName;
            req.Context = _config.ContextID;
            req.ItemFilter = _config.ItemFilter;
            req.Site = _config.GetEnvironment(environment).SiteName;
            #endregion Set services parameters

            #region Call Service
            GetAssemblyUrlsResponse resul = null;
            try
            {
                resul = _svcContent.GetAssemblyUrls(req);
            }
            catch (SoapException ex)
            {
                _logException(new CMSServiceCallException(ex), "GetItemUrl");
            }
            catch (System.Net.WebException ex)
            {
                _logException(ex, "GetItemUrl");
                throw new CMSNotAccessibleException(ex);
            }
            catch (Exception ex)
            {
                _logException(ex, "GetItemUrl");
                throw new UnSpecifiedCMSException(ex);
            }
            #endregion Call Service

            #region Get Url
            if (resul != null && resul.Urls != null && resul.Urls.Length > 0)
            {
                string snipetUrl = resul.Urls[0];
                string itemPublishedUri = _extractUrlFromHtml(snipetUrl);
                if (!string.IsNullOrEmpty(itemPublishedUri))
                    res = _config.GetEnvironment(environment).BaseUrl + itemPublishedUri;
            }
            #endregion

            return res;
        }
       
        #endregion Public Methods

        #region Private methods
        /// <summary>
        /// Create the login request iwth config data
        /// </summary>
        /// <returns>Login request containing authentication credentials</returns>
        private LoginRequest _getLoginRequest()
        {
            LoginRequest loginReq = new LoginRequest();
            loginReq.Username = ConfigHelper.RhythmyxUserName;
            loginReq.Password = ConfigHelper.RhythmyxPassword;
            loginReq.Community = ConfigHelper.RhythmyxCommunity;
            return loginReq;
        }

        /// <summary>
        /// Create the ContentService and sets its Authentication header with the session ID
        /// </summary>
        /// <param name="sessionID">Session ID to keep session open</param>
        /// <returns>Content Service</returns>
        private contentSOAP _createContentService(string sessionID)
        {
            contentSOAP svcContent = new contentSOAP();
            svcContent.Url = _buildAddress(svcContent.Url);
            svcContent.PSAuthenticationHeaderValue = new PSAuthenticationHeader();
            svcContent.PSAuthenticationHeaderValue.Session = sessionID;
            return svcContent;
        }

        /// <summary>
        /// Build the WebServiceAdress with the configuration keys
        /// </summary>
        /// <param name="srcAddress">default Service adress to be modified to get the configured address</param>
        /// <returns>Target service address</returns>
        private string _buildAddress(String srcAddress)
        {
            int pathStart = srcAddress.IndexOf("/Rhythmyx/");
            return ConfigHelper.RhythmyxWSUrl.Substring(0, pathStart) + srcAddress.Substring(pathStart);
        }
       
        /// <summary>
        /// Create a search param (search criteria and its value searched for) to provide to the findItem service
        /// </summary>
        /// <param name="name">Field name criteria</param>
        /// <param name="op">Operator</param>
        /// <param name="value">value searched for the specified field</param>
        /// <param name="connector">Connector as "or", "and"</param>
        /// <returns>Param object</returns>
        private PSSearchField _createParam(string name, operatorTypes op, string value, connectorTypes connector)
        {
            PSSearchField param = new PSSearchField();
            param.name = name;
            param.Operator = op;
            param.Value = value;
            param.Connector = connector;
            return param;
        }

        /// <summary>
        /// Logs an exception via LogHelper
        /// </summary>
        /// <param name="ex">Exception to log</param>
        /// <param name="operation">Operation that has aborted</param>
        private void _logException(Exception ex, string operation)
        {
            LogHelper.Log(this, "CMS " + operation + " failed", ex, LogHelper.ELogSeverity.Error);
        }

        /// <summary>
        /// Create search param field
        /// </summary>
        /// <param name="criteriaName"></param>
        private PSSearchResultField _setSearchParamField(string criteriaName)
        {
            PSSearchResultField res = new PSSearchResultField();
            res.name = criteriaName;
            return res;
        }

        /// <summary>
        /// Calls the Assembly URL Snipet and extract the Published URI from it
        /// </summary>
        /// <param name="snipetUrl">Url of the page containing the published URI</param>
        /// <returns>Published URI</returns>
        private string _extractUrlFromHtml(string snipetUrl)
        {
            string snipetContent = "";

            try
            {
                snipetContent = HttpHelper.GetHttpRequest(snipetUrl, ConfigHelper.RhythmyxUserName, ConfigHelper.RhythmyxPassword);
            }
            catch (System.Net.WebException ex)
            {
                _logException(ex, "GetSnipetContent");
                throw new CMSNotAccessibleException(ex);
            }
            catch (Exception ex)
            {
                _logException(ex, "GetSnipetContent");
                throw new UnSpecifiedCMSException(ex);
            }
            if (!string.IsNullOrEmpty(snipetContent))
            {
                string startString = "href=\"";
                snipetContent = snipetContent.Substring(snipetContent.IndexOf(startString) + startString.Length);
                return snipetContent.Substring(0, snipetContent.IndexOf("\""));
            }
            return "";
        }

        /// <summary>
        /// Calls the GetAssemblyUrls service to get the Item's assembly urls and construct the published urls
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="templateName"></param>
        /// <param name="contextID"></param>
        /// <param name="itemfilter"></param>
        /// <param name="siteName"></param>
        /// <param name="environmentBaseUrl"></param>
        /// <returns></returns>
        private string[] _getUrls(long[] ids, EnvConf.EEnvironment environment)
        {
            string[] res = new string[ids.Length];

            #region Set services parameters
            GetAssemblyUrlsRequest req = new GetAssemblyUrlsRequest();
            req.Id = ids;
            req.Template = _config.TemplateName;
            req.Context = _config.ContextID;
            req.ItemFilter = _config.ItemFilter;
            req.Site = _config.GetEnvironment(environment).SiteName;
            //req.FolderPath = "//Sites/intranet/Assets/Docs";//"1394";
            #endregion Set services parameters

            #region Call Service
            GetAssemblyUrlsResponse resul = null;
            try
            {
                resul = _svcContent.GetAssemblyUrls(req);
            }
            catch (SoapException ex)
            {
                _logException(new CMSServiceCallException(ex), "GetItemUrl");
            }
            catch (System.Net.WebException ex)
            {
                _logException(ex, "GetItemUrl");
                throw new CMSNotAccessibleException(ex);
            }
            catch (Exception ex)
            {
                _logException(ex, "GetItemUrl");
                throw new UnSpecifiedCMSException(ex);
            }
            #endregion Call Service

            #region Get Urls
            if (resul != null && resul.Urls != null && resul.Urls.Length > 0)
            {
                for (int i = 0; i < ids.Length; i++)
                {
                    string snipetUrl = resul.Urls[i];
                    string itemPublishedUri = _extractUrlFromHtml(snipetUrl);
                    if(!string.IsNullOrEmpty(itemPublishedUri))
                        res[i] = _config.GetEnvironment(environment).BaseUrl + itemPublishedUri;
                }
            }
            #endregion

            return res;
        }

        #endregion Private methods

        #region IDisposable Members
        /// <summary>
        /// Dispose all web services proxy and session data
        /// </summary>
        public void Dispose()
        {
            //Dispose resources
            if (_svcSecurity != null)
            {
                _svcSecurity.Dispose();
                _svcSecurity = null;
            }
            if (_svcContent != null)
            {
                _svcContent.Dispose();
                _svcContent = null;
            }
        }

        #endregion
    }
}

Publicité
Publicité
19 novembre 2009

LINQ to Entities and Oracle

On my last project, I had to implement a service layer, accessing Oracle database. The service layer was implemented with WCF. I use to work with LINQ to SQL on other projects, so I wondered if it was possible to access oracle database in the same way as SQL Server with LS... Not at all! I found on the net that LS was not working with Oracle. I should better use LINQ to ENtities...

So I've been creating a new EDMX file in Visual Studio 2008 SP1, and when I tryed to change the data source to Oracle... NOWAY! I could just set some SQL Server data sources...

After requesting my friend google, I figured out that another component, not a Microsoft component, must be installed on my workstation to be able to had some oracle datasource in the EF Designer!

I found these components:

http://www.devart.com/dotconnect/entityframework.html

19 novembre 2009

WCF and LINQ to Entities exposed attributes issue

On my last project, I've been searching for a solution to hide some properties of my EF generated entities to my wcf services clients. The problem is that WCF exposes all the entities members, public, private, or internal.

In fact, all entities properties marked with [DataMember] attribute will be exposed to the WCF client.

The solution remains in removing the [DataMember] attribute on the unwanted properties. And to have a clean solution, the EF code genrator must be customized.

I found the way to customize Entity Framework code generator here:

http://visualstudiomagazine.com/articles/2008/09/01/customize-code-generation-in-ef.aspx?sc_lang=en 

11 juillet 2009

LINQ To SQL Generic methods

In order to avoid too much coding in my DAO layer, I've been creating some generic LINQ to SQL CRUD methods.

Generic Delete method:


/// <summary>

/// Delete an entity

/// </summary>

/// <param name="entity">Entity to be deleted</param>

[System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Delete)]

public void Delete(TEntity entity)

{

    try

    {

TEntity original = GetEntity(_getPrimaryKey().GetValue(entity, null));

DAODataContext.GetTable<TEntity>().DeleteOnSubmit(original);      

    }

    catch (Exception e)

    {

throw new DAOException(DAOException.EError.Delete, e);

    }

} 


Generic Attach method:

The generic attach method is used to attach existing entitie or new entitie, a test is executed to check if the entitie has to be inserted or updated:

/// <summary>

/// Attach an entity to the data context

/// If the entity is allready attached, exception is catched

/// </summary>

/// <param name="entity">Entity to attach</param>

public void Attach(TEntity entity)

{

   

PropertyInfo primaryKey = _getPrimaryKey();

if (_isNullOrEmpty(primaryKey.GetValue(entity, null)))

{

         //new object case

    DAODataContext.GetTable<TEntity>().InsertOnSubmit(entity);

}

else

{

    try

    {

//existing object case

DAODataContext.GetTable<TEntity>().Attach(entity);

    }

    catch (InvalidOperationException)

    {

// Do nothing for exception when object already attached to data context

    }

    catch (Exception e)

    {

throw new DAOException(DAOException.EError.Attach, e);

    }

}

}

Method to get the primary key of an entitie:

/// <summary>

        /// Gets the primary key of the current entity type

        /// </summary>

        /// <returns>Primary key property info</returns>

        private PropertyInfo _getPrimaryKey()

        {

            MetaTable mapping = DAODataContext.Mapping.GetTable(typeof(TEntity));

            MetaDataMember pkfield = mapping.RowType.DataMembers.SingleOrDefault(d => d.IsPrimaryKey);

            int count = mapping.RowType.DataMembers.Count(d => d.IsPrimaryKey);

            if (count < 1) throw new Exception(String.Format("Table {0} does not contain a Primary Key field", mapping.TableName));

            if (count > 1) throw new Exception(String.Format("Table {0} contains a composite primary key field", mapping.TableName));

            return typeof(TEntity).GetProperty(pkfield.MappedName);

        } 

Method to test if a field as a null value:

  /// <summary>

        /// Check if a type object is considered as null value depending on its type

        /// (<1 for int , Guid.Empty for Guid, null or empty for string)

        /// </summary>

        /// <param name="value">Value to be check</param>

        /// <returns>True if value is considered null</returns>

        private bool _isNullOrEmpty(object value)

        {

            if (value is int)

            {

                return (int)value < 1;

            }

            else if (value is Guid)

            {

                return value == null || (Guid)value == Guid.Empty;

            }

            else if (value is string)

            {

                return string.IsNullOrEmpty((string)value);

            }

            return false;

        }

Generic Get an Entitie method:

/// <summary>

        /// Generic search method to get one entity, loading child objects requested by the loadOptionPredicates

        /// </summary>

        /// <param name="loadOptions">Request to load child objects</param>

        /// <param name="predicate">Predicate to search for the entity</param>

        /// <returns>A found entity with child entities or a default value</returns>

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]

        public TEntity FindEntity(DataLoadOptions loadOptions, Expression<Func<TEntity, bool>> predicate)

        {

            TEntity res = null;         

            try

            {

                if (loadOptions != null)

                {

                    if (DAODataContext.DeferredLoadingEnabled == true)

                        DAODataContext.DeferredLoadingEnabled = false;

                    DAODataContext.LoadOptions = loadOptions;

                }

               

                res = DAODataContext.GetTable<TEntity>().FirstOrDefault(predicate);

            }

            catch (Exception e)

            {

                throw new DAOException(DAOException.EError.FindEntitie, e);

            }

            return res;

        }

Generic New method:

/// <summary>

/// Returns a new attached instance the requested Entity with default values

/// </summary>

/// <returns></returns>

public TEntity New()

{

    TEntity newEntity = new TEntity();

    Attach(newEntity);

    return newEntity;

}

26 juin 2009

LINQ To SQL issue when serializing in the viewstate

After having implemented LINQ DTO with relations, using the codeplex L2ST4 templates, I got an error when seriallizing the DTO to the viewstate. The problem was about th serialization of a relation, implemented as an entityset in the DTO. The problem was the ViewState Serializer did not recognise the entityset.

The solution: a workaround to serialize myself the DTO before passing it to the ViewState serializer, and reverse the process for deserialization.

First, create a Serializer Helper

Secondly, create a generic decorator for LINQ To SQL Entities, serializing/deserializing:

[Serializable]
    public class SViewState<T> : System.Runtime.Serialization.ISerializable where T:class 
    {
        public SViewState() { }
        public SViewState(T obj)
        {
            ViewState = (T)obj;
        }
        private String _xml;
      
        public String SObject
        {
            get
            {
                _xml = ViewState.GetType().FullName + "<>" +SerializeHelper.SerializeXml( ViewState) ;
                return _xml;
            }
            set
            {
                int index = value.IndexOf("##");
                string typeName = value.Substring(0, index);
                _xml = value.Substring(index + 2);
                Type typ = Type.GetType(typeName);
                ViewState = (T)SerializeHelper.DeserializeXMl(typeof(T), _xml);
            }
        }
        [NonSerialized]
        private T _viewState = null;
        public T ViewState { get { return _viewState; } set { _viewState = value; } }

        protected SViewState(SerializationInfo info, StreamingContext context)
          {
            ViewState = (T)SerializeHelper.DeserializeXMl(typeof(T), info.GetString("_xml"));
          }
        [SecurityPermission(SecurityAction.Demand,
        SerializationFormatter =true)]

        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
          {
              info.AddValue("_xml", SerializeHelper.SerializeXml(ViewState));
          }

    }

Thirdly, implement a ViewState accessor :

private Contract CurrentContract
        {
            get
            {
                return ((SViewState<Contract>)ViewState["CurrentContract"]).ViewState ;
            }
            set
            {
                ViewState["CurrentContract"] = new SViewState<Contract>( value) ;
            }
        }

And That's it.

Enjoy!

Publicité
Publicité
26 juin 2009

Create a Serializer / Deserializer for LINQ To SQL Entities

using System;
using System.IO;
using System.Xml;
using System.Runtime.Serialization;

namespace JC.Common
{
    /// <summary>
    /// Provides methods to serialize objects
    /// </summary>
    public static class SerializeHelper
    {       
        public static string SerializeXml(object value)
        {
            if (value.GetType() == typeof(string))
                return value.ToString();

            StringWriter stringWriter = new StringWriter();
            using (XmlWriter writer = XmlWriter.Create(stringWriter))
            {
                DataContractSerializer serializer = new
                  DataContractSerializer(value.GetType());
                serializer.WriteObject(writer, value);
            }

            return stringWriter.ToString();
        }
        public static object DeserializeXMl(Type type, string serializedValue)
        {
            if (type == typeof(string))
                return serializedValue;

            using (StringReader stringReader = new StringReader(serializedValue))
            {
                using (XmlReader reader = XmlReader.Create(stringReader))
                {
                    DataContractSerializer serializer =
                     new DataContractSerializer((type));

                    object deserializedValue = serializer.ReadObject(reader);

                    return deserializedValue;
                }
            }
        }
    }
}

24 avril 2009

Problem with Asp.net 2.0 Crystal Reports Deployment

I've developed an applications with asp.net 2.0, containing crytsal reports, working on dev environment, but when I installed it on integration environment, I got this error :

Retrieving the COM class factory for component with CLSID {11BD5260-15B6-412D-80DB-12BB60B8FE50} failed due to the following error: 800736b1. 
Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details:
System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {11BD5260-15B6-412D-80DB-12BB60B8FE50} failed due to the following error: 800736b1.

Source Error:
 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.


Stack Trace:
 


[COMException (0x800736b1): Retrieving the COM class factory for component with CLSID {11BD5260-15B6-412D-80DB-12BB60B8FE50} failed due to the following error: 800736b1.]
CrystalDecisions.CrystalReports.Engine.ReportDocument..cctor() +207

[TypeInitializationException: The type initializer for 'CrystalDecisions.CrystalReports.Engine.ReportDocument' threw an exception.]
CrystalDecisions.CrystalReports.Engine.ReportDocument..ctor() +0

Solution:
1. install Crystal Report redist package
CRRedist2005_x86.msi
2. execute this command "regsvr32 /u C:\Program Files\Common Files\Business Objects\2.7\Bin\sacommlayer.dll"
 
3. execute this command "regsvr32 C:\Program Files\Common Files\Business Objects\2.7\Bin\sacommlayer.dll"
 

The bug is in dll file sacommlayer.dll in C:\Program Files\Common Files\Business Objects\2.7\Bin that appear to be not valid after a wondow 2003 restart.

A practical link to get Crystal Reports patchs

I hade a new error installing it on a new production environment. The difference between the other environment : SQL Server 2005 was not installed on the server hosting the web app.

Error message indicating a problem of db connexion from Crytal reports component:

Server Error in '/' Application.

No error. 
Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details:
System.Runtime.InteropServices.COMException: No error.
Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace: 


[COMException (0x80000000):
No error.]
CrystalDecisions.ReportAppServer.ClientDoc.ReportClientDocumentClass.VerifyDatabase() +0
CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.VerifyDatabase() +40
CrystalDecisions.CrystalReports.Engine.ReportDocument.VerifyDatabase() +53

[LogOnException: Log on failed.]
CrystalDecisions.CrystalReports.Engine.ReportDocument.VerifyDatabase() +143

Solution : Install SQL Server 2005 Connectivity Tools.


Publicité
Publicité
Publicité