Re: problem in updating custom field on publishing event of Projec
Several things:
1. You need to use the SSP address in Impersonated applications,
not the PSI Proxy.
a. For example, this means that you should be setting
ws_Project.Url to http://ruh-003-cr-001:56737/<SSPName>/PSI/Project.asmx
<http://ruh-003-cr-001:56737/%3cSSPName%3e/PSI/Project.asmx> , where
<SSPName> is the name of the SSP where your PWA site resides (e.g.
SharedServices1).
2. Why you are converting all your Guids to byte[]s before you
store then in Guid variables? This is unnecessary. Guid() has a
constructor that will take an existing Guid.
3. Why have you derived LoginWindows in here? You cannot
impersonate using LoginWindows. Futhermore, since ContextInfo contains
all the information for the already authenticated user, such an exercise
would be pointless anyway.
4. Final point (and this may be where the exception is coming
from) is that you're causing an infinite recursion through your use of
the CheckIn event. You have a CheckIn event handler, which updates a
project and checks it in, an act which will fire the CheckIn event,
which will call your CheckIn event handler, which updates a project...
ad infinitum. You need to have some sort of test in your code to cancel
execution somehow (e.g. by throwing an exception) so that your code does
not infinitely loop. This mistake is very common in event handlers, and
is something that you really, really need to be careful of. Exceptions,
in addition to being the proper way to handle errors, are useful when
writing custom event handlers because they will automatically cancel the
event handler.
HTH!
--
Stephen Sanderlin
Principal Consultant
MSProjectExperts
For Project Server Consulting: http://www.msprojectexperts.com
For Project Server Training: http://www.projectservertraining.com
Read my blog at: http://www.projectserverhelp.com/
Join the community at: http://forums.epmfaq.com
"M Azeem" wrote in message
news:C7506948-0064-4CE8-9E79-2B925E29E09E@microsoft.com:
> OK, Stephen, I have tried it on CheckIn event here is my code but again,
> exceptions are being raised and strange thing is Exception object is null, so
> I am unable to see what causing the exception please help
>
> using System;
>
> using System.Diagnostics;
>
> using Microsoft.Office.Project.Server.Events;
>
> using System.Collections.Generic;
>
> using System.Text;
>
> using System.Net;
>
> using System.Web.Services.Protocols;
>
> using System.Data;
>
> using System.Threading;
>
> using PSLibrary = Microsoft.Office.Project.Server.Library;
>
> namespace SaveProjectAttribute
>
> {
>
> public class AddAttributeOnSave : ProjectEventReceiver
>
> {
>
> public override void
> OnCheckIn(Microsoft.Office.Project.Server.Library.PSContextInfo contextInfo,
> ProjectPostEventArgs e)
>
> {
>
> base.OnCheckIn(contextInfo, e);
>
> const string ls_projURL = "http://ruh-003-cr-001/pmo/";
>
> const string ls_CustomField = "TestCF";
>
> const string ls_LookupTableValue = "";
>
> bool verbose = true;
>
> const string PROJECT_SERVICE_PATH = "_vti_bin/psi/Project.asmx";
>
> const string LOGIN_SERVICE_PATH = "_vti_bin/psi/LoginWindows.asmx";
>
> bool isWindowsAccount = true;
>
> Guid trackingGuid = new Guid(contextInfo.TrackingGuid.ToByteArray());
>
> string lcid = contextInfo.Lcid;
>
> string userNTAccount = contextInfo.UserName;
>
> Guid resourceGuid = new Guid(contextInfo.UserGuid.ToByteArray());
>
> Guid siteId = new Guid(contextInfo.SiteGuid.ToByteArray());
>
> ProjectDerived ws_Project = new ProjectDerived();
>
> LoginWindowsDerived loginWindows = new LoginWindowsDerived();
>
> LoginWindowsDerived.SetImpersonationContext(isWindowsAccount, userNTAccount,
> resourceGuid, trackingGuid, siteId, lcid);
>
> ProjectDerived.SetImpersonationContext(isWindowsAccount, userNTAccount,
> resourceGuid, trackingGuid, siteId, lcid);
>
> loginWindows.Url = ls_projURL + LOGIN_SERVICE_PATH;
>
> loginWindows.Credentials = CredentialCache.DefaultCredentials;
>
> ws_Project.Url = ls_projURL + PROJECT_SERVICE_PATH;
>
> ws_Project.Credentials = CredentialCache.DefaultCredentials;
>
> WSProject.ProjectDataSet lo_projs = null;
>
> WSProject.ProjectDataSet lo_projDS;
>
> WSProject.ProjectDataSet lo_projDS1;
>
> Guid lo_projGUID;
>
> string ls_projName;
>
> CustomField cf = new CustomField(ls_projURL, ls_CustomField);
>
> LookupTable lt = new LookupTable(ls_projURL, cf.LookupTableGUID);
>
> try
>
> {
>
> // Read all the projects on the server
>
> lo_projs = ws_Project.ReadProjectList();
>
> DataRowCollection lo_projects =
> lo_projs.Tables[lo_projs.Project.TableName].Rows;
>
> lo_projDS = ws_Project.ReadProjectEntities(e.ProjectGuid, 32,
> WSProject.DataStoreEnum.WorkingStore);
>
> lo_projDS1 = ws_Project.ReadProjectEntities(e.ProjectGuid, 1,
> WSProject.DataStoreEnum.WorkingStore);
>
> Guid jobid = Guid.NewGuid();
>
> Guid sessionId = Guid.NewGuid();
>
> foreach (WSProject.ProjectDataSet.ProjectCustomFieldsRow row in
> lo_projDS.ProjectCustomFields)
>
> {
>
> if (row.MD_PROP_UID == cf.CustomFieldGUID)
>
> {
>
> row.TEXT_VALUE = "Finally Got You!";
>
> ws_Project.CheckOutProject(e.ProjectGuid, sessionId, "");
>
> ws_Project.QueueUpdateProject(jobid, sessionId, lo_projDS, false);
>
> ws_Project.QueueCheckInProject(jobid, e.ProjectGuid, false, sessionId, "");
>
> }
>
> }
>
> }
>
> catch (SoapException lo_ex1)
>
> {
>
> if (verbose)
>
> System.Console.WriteLine("Error: " + lo_ex1.Message);
>
> }
>
> catch (WebException lo_ex)
>
> {
>
> if (verbose)
>
> System.Console.WriteLine("Error: " + lo_ex.Message);
>
> }
>
> catch (Exception lo_ex)
>
> {
>
> if (verbose)
>
> System.Console.WriteLine("Unknown Error: " + lo_ex.Message);
>
> }
>
> System.Console.WriteLine("Done!");
>
> }
>
> }
>
> class LoginWindowsDerived : WSLoginWindows.LoginWindows
>
> {
>
> private static String ContextString = String.Empty;
>
> protected override WebRequest GetWebRequest(Uri uri)
>
> {
>
> //here we are overriding the GetWebRequest method and adding the 2 web
> request headers
>
> WebRequest webRequest = base.GetWebRequest(uri);
>
> if (ContextString != String.Empty)
>
> {
>
> webRequest.UseDefaultCredentials = true;
>
> bool isImpersonating =
> (System.Security.Principal.WindowsIdentity.GetCurrent(true) != null);
>
> webRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
>
> webRequest.Headers.Add("PjAuth", ContextString);
>
> webRequest.Headers.Add("ForwardFrom", "/_vti_bin/psi/LoginWindows.asmx");
>
> webRequest.PreAuthenticate = true;
>
> }
>
> return webRequest;
>
> }
>
> public static void SetImpersonationContext(bool isWindowsUser, String
> userNTAccount, Guid userGuid, Guid trackingGuid, Guid siteId, String lcid)
>
> {
>
> ContextString = GetImpersonationContext(isWindowsUser, userNTAccount,
> userGuid, trackingGuid, siteId, lcid);
>
> }
>
> private static String GetImpersonationContext(bool isWindowsUser, String
> userNTAccount, Guid userGuid, Guid trackingGuid, Guid siteId, String lcid)
>
> {
>
> PSLibrary.PSContextInfo contextInfo = new
> PSLibrary.PSContextInfo(isWindowsUser, userNTAccount, userGuid, trackingGuid,
> siteId, lcid);
>
> String contextString = PSLibrary.PSContextInfo.SerializeToString(contextInfo);
>
> return contextString;
>
> }
>
> }
>
> class ProjectDerived : WSProject.Project
>
> {
>
> private static String ContextString = String.Empty;
>
> protected override WebRequest GetWebRequest(Uri uri)
>
> {
>
> //here we are overriding the GetWebRequest method and adding the 2 web
> request headers
>
> WebRequest webRequest = base.GetWebRequest(uri);
>
> if (ContextString != String.Empty)
>
> {
>
> webRequest.UseDefaultCredentials = true;
>
> bool isImpersonating =
> (System.Security.Principal.WindowsIdentity.GetCurrent(true) != null);
>
> webRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
>
> webRequest.Headers.Add("PjAuth", ContextString);
>
> webRequest.Headers.Add("ForwardFrom", "/_vti_bin/psi/project.asmx");
>
> webRequest.PreAuthenticate = true;
>
> }
>
> return webRequest;
>
> }
>
> public static void SetImpersonationContext(bool isWindowsUser, String
> userNTAccount, Guid userGuid, Guid trackingGuid, Guid siteId, String lcid)
>
> {
>
> ContextString = GetImpersonationContext(isWindowsUser, userNTAccount,
> userGuid, trackingGuid, siteId, lcid);
>
> }
>
> private static String GetImpersonationContext(bool isWindowsUser, String
> userNTAccount, Guid userGuid, Guid trackingGuid, Guid siteId, String lcid)
>
> {
>
> PSLibrary.PSContextInfo contextInfo = new
> PSLibrary.PSContextInfo(isWindowsUser, userNTAccount, userGuid, trackingGuid,
> siteId, lcid);
>
> String contextString = PSLibrary.PSContextInfo.SerializeToString(contextInfo);
>
> return contextString;
>
> }
>
> }
>
> }
>
>
>
>
> "Stephen Sanderlin" wrote:
>
>
> > Can you post your new code?
> >
> > As far as WS_Project, you are right -- my apologies. I need a new
> > newsreader.
> >
> > --
> > Stephen Sanderlin
> > Principal Consultant
> > MSProjectExperts
> > For Project Server Consulting: http://www.msprojectexperts.com
> > For Project Server Training: http://www.projectservertraining.com
> >
> > Owner/Founder - EPMFAQ
> > http://www.epmfaq.com/
> > http://forums.epmfaq.com/
> >
> >
> > M Azeem wrote:
> >
>
> > > PROJECT
>
> >
date: Tue, 2 Sep 2008 12:35:26 +0000
author: Stephen Sanderlin stephen NS-DOT sanderlin A-NS-T msprojectexperts DOT-NS com