public Message GetTodayPartnerCallsForPlace(string id) { try { SvcContext ctx = InflateContext(); if (ctx.Invalid) { return(ctx.ContextMessage); } Guid pID = Guid.ParseExact(id, "N"); var calls = pcSvc.GetPlacesGeoDeducTodayPartnerCalls(pID); var dto = new List <PartnerCallDto>(); foreach (var c in calls) { //-- Here we use perf cache instead of Include()/join because it's likely the user will have revisited the same place var place = CfCacheIndex.Get(c.PlaceID); if (place != null) { var user = CfPerfCache.GetClimber(c.UserID); var callDto = new PartnerCallDto(place, c, user); dto.Add(callDto); } } return(ReturnAsJson(dto)); } catch (Exception ex) { CfTrace.Error(ex); return(Failed("Partner search failed : " + ex.Message)); } }
public override void OnException(ExceptionContext context) { CfTrace.Error(context.Exception); if (context.Exception is AccessViolationException) { context.Result = new ViewResult() { ViewName = "Unauthorized" }; (context.Result as ViewResult).ViewBag.Msg = context.Exception.Message; context.ExceptionHandled = true; } else { var ex = getBaseException(context.Exception); var errorDisplayText = ex.Message; if (CfIdentity.IsAuthenticated && CfPrincipal.IsGod()) { errorDisplayText = ex.ToString(); } context.Result = new ViewResult() { ViewName = "Error" }; (context.Result as ViewResult).ViewBag.Msg = errorDisplayText; context.ExceptionHandled = true; } base.OnException(context); }
public override bool OnStart() { CfTrace.InitializeTraceSource(new Instrumentation.CfTraceSource("Cf.CacheServer")); try { var connectionString = ConfigurationManager.ConnectionStrings["CfCloudStorage"].ConnectionString; CfCloudStorage = CloudStorageAccount.Parse(connectionString); //System.Diagnostics.Trace.WriteLine("cf.CacheServer Started: "+DateTime.UtcNow.ToString()); var startTime = DateTime.UtcNow; var stopwatch = new Stopwatch(); stopwatch.Start(); proc = WazMemcachedHelpers.StartMemcachedServer("Memcached", 640); proc.Exited += new EventHandler(MemcachedServer_Crashed); var index = PopuluteCfCacheIndex(); stopwatch.Stop(); //System.Diagnostics.Trace.WriteLine(string.Format("cf.CacheServer index [{0}], Ready after {1}ms", index.Count, stopwatch.ElapsedMilliseconds)); StartServiceHost(); //Listen for manual cache refreshes } catch (Exception ex) { CfTrace.Error(ex); } return(base.OnStart()); }
/// <summary> /// Return all geocode results that are within the specified country /// </summary> /// <param name="country"></param> /// <param name="locality"></param> /// <returns></returns> public List <GeocodeResult> Geocode(Country country, string locality) { List <GeocodeResult> results; //-- Take out special characters from the locality so when we put it in the url our web request works var cleanedLocalityString = locality.Replace("&", "and").Replace("#", "").Trim(); try { //- Get the results from bing against the country specific store results = BingGeocodeCountryRegionQuery(country, cleanedLocalityString); if (results.Count == 0) { //-- Sometimes if it doesn't work when we make a country specific call if we make a general call to bing we get a result //-- e.g. "The Peak District National Park" in the UK results = BingGeocodeSingleQuery(country, cleanedLocalityString); } else { //-- Double check that bing hasn't give us a stupid default result representing just the country and not the locality if (ResultIsDefaultCountry(country, results)) { results = BingGeocodeSingleQuery(country, cleanedLocalityString); if (ResultIsDefaultCountry(country, results)) { //-- We don't want to send back a result of country type results.Clear(); } } else { //-- Sometimes the result we get from the country specific call sucks and we want to give //-- the user access to the second result as well results.AddRange(BingGeocodeSingleQuery(country, cleanedLocalityString)); } } //-- If after all the goes above we still don't have anything from silly Bing, let's use google if (results.Count == 0) { results = GooleGeocodeSingleQuery(country, cleanedLocalityString); } //-- Remove duplicates if (results.Count > 1) { results = results.Distinct(new GeocodeResultEqualityComparer()).ToList(); } } catch (Exception ex) { ex.Data.Add("locality", cleanedLocalityString); CfTrace.Error(ex); throw; } return(results); }
public void Initialize() { var connectionString = ConfigurationManager.ConnectionStrings["CfCloudStorage"].ConnectionString; CfCloudStorage = CloudStorageAccount.Parse(connectionString); blobRepo = new BlobRepository(); CfTrace.InitializeTraceSource(new Instrumentation.CfTraceSource("Cf.CacheServer")); }
public ActionResult RequestProxy(string url) { try { return(new ProxyResult(new Uri(url))); } catch (Exception ex) { CfTrace.Error(ex); return(Json(new { Success = false, Error = ex.Message })); } }
public ActionResult LatestCommunityMediaStrip() { try { var model = mediaSvc.GetLatestMedia(12); return(PartialView(model)); } catch (Exception ex) { CfTrace.Error(ex); return(Content("<p>Failed to load recent media. Refresh the page</p>")); } }
protected void Application_Start(object sender, EventArgs e) { CfTrace.InitializeTraceSource(new Instrumentation.CfTraceSource("Cf.Svc")); CfTrace.Current.Information(TraceCode.AppStart, "Cf.Svc Started {0:MMM dd HH.mm.ss}", DateTime.Now); //-- Setup caching depending on if we're running in the cloud or not //InitializeEnvironmentCacheAndSearchProviders(); RegisterRoutes(); Microsoft.IdentityModel.Web.FederatedAuthentication.ServiceConfigurationCreated += new EventHandler <Microsoft.IdentityModel.Web.Configuration.ServiceConfigurationCreatedEventArgs>(RsaServerfarmSessionCookieTransform.OnServiceConfigurationCreated); CfTrace.Current.Information(TraceCode.AppStartEnd, "Cf.Svc Start ended {0:MMM dd HH.mm.ss}", DateTime.Now); }
//void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e) //{ // var token = e.SessionToken; //} //void SessionAuthenticationModule_SessionSessionSecurityTokenCreated(object sender, SessionSecurityTokenCreatedEventArgs e) //{ // var token = e.SessionToken; //} //void WSFederationAuthenticationModule_SessionSecurityTokenCreated(object sender, SessionSecurityTokenCreatedEventArgs e) //{ // e.WriteSessionCookie = true; // e.SessionToken = FederatedAuthentication.SessionAuthenticationModule.CreateSessionSecurityToken( // e.SessionToken.ClaimsPrincipal, // e.SessionToken.Context, // DateTime.UtcNow, // DateTime.UtcNow.AddDays(300), // true); // var id = e.SessionToken.Id; //} void Application_Error(Object sender, EventArgs e) { try { string relativeUrl = HttpContext.Current.Request.RawUrl.ToLower(); Exception exception = Server.GetLastError().GetBaseException(); if (exception.ShouldRecord(relativeUrl) && !HttpContext.Current.Request.Url.OriginalString.StartsWith("http://cf4")) { CfTrace.Error(exception); } Server.ClearError(); if (SpecialUrls.Cf3Redirect(relativeUrl)) { Response.Status = "301 Moved Permanently"; Response.AddHeader("Location", "http://cf3.climbfind.com" + relativeUrl); Response.Flush(); Response.End(); } else if (SpecialUrls.Instance.PermanentlyMoved.ContainsKey(relativeUrl)) { Response.Status = "301 Moved Permanently"; Response.AddHeader("Location", SpecialUrls.Instance.PermanentlyMoved[relativeUrl]); Response.Flush(); Response.End(); } else if (SpecialUrls.HasBeenRemoved(relativeUrl)) { Response.Status = "410 Gone"; Response.ContentType = "text/html"; Response.WriteFile(Server.MapPath("~/page-not-found.htm")); } else if (exception.Message.Contains("The controller for path") || exception.Message.Contains("A public action method")) { Response.Status = "404 Not Found"; Response.ContentType = "text/html"; Response.WriteFile(Server.MapPath("~/page-not-found.htm")); } } catch (Exception ex) { Response.Write("<span class='note'>GLOBAL ENDPOINT: PLEASE EMAIL [email protected] IMMEDIATELY IF YOU SEE THIS SCREEN!!!!!!!!!!!!</span>" + ex.ToString()); } }
// Create or update a blob. // Return true on success, false if already exists, throw exception on error. public bool PutMessage(string queueName, CloudQueueMessage message) { try { CloudQueue queue = QueueClient.GetQueueReference(queueName); queue.AddMessage(message); return(true); } catch (StorageClientException ex) { CfTrace.Error(ex); return(false); //-- no throw because if this fails, prefer not to break the app for the user //throw; } }
/// <summary> /// /// </summary> public override void Run() { while (true) { try { //var mClient = WazMemcachedHelpers.CreateProtobufferClient(CacheConstants.CacheRole, CacheConstants.CacheEndpoint); //ServerStats stats = mClient.Stats(); //MailMan.SendAppEvent(TraceCode.AppBuildCache, "Hourly cache cache + lucene index", "*****@*****.**", Guid.Empty, "*****@*****.**", false); Thread.Sleep(1000 * 3600); //-- Sleep for an hour and then refresh the index Trace.WriteLine("CacheServer cache refresh", "Information"); PopuluteCfCacheIndex(); } catch (Exception ex) { CfTrace.Error(ex); } } }
/// <summary> /// /// </summary> private void RebuildLuceneIndex() { try { var dir = new Lucene.Net.Store.Azure.AzureDirectory(CfCloudStorage, "SearchCatalog", new Lucene.Net.Store.RAMDirectory()); //-- The magic code... delete all the blobs before rebuilding the index foreach (var b in dir.BlobContainer.ListBlobs()) { dir.BlobContainer.GetBlobReference(b.Uri.ToString()).Delete(); } new cf.Content.Search.SearchManager().BuildIndex(dir); } catch (Exception ex) { CfTrace.Error(ex); } }
void Application_Error(Object sender, EventArgs e) { try { string relativeUrl = HttpContext.Current.Request.RawUrl; Exception exception = Server.GetLastError().GetBaseException(); if (exception.ShouldRecord(relativeUrl)) { CfTrace.Error(exception); Response.Write(exception.ToString()); } Server.ClearError(); } catch (Exception ex) { //TODO: write to text file Response.Write("<span class='note'>GLOBAL ENDPOINT: PLEASE EMAIL [email protected] IMMEDIATELY IF YOU SEE THIS SCREEN!!!!!!!!!!!!</span>" + ex.ToString()); } }
public override bool OnStart() { //-- Wait for the cf.CacheServer to load first System.Threading.Thread.Sleep(100000); try { CfTrace.InitializeTraceSource(new Instrumentation.CfTraceSource("Cf.AlertsServer")); CfCacheIndex.Initialize(new Level2MemcachedCacheIndex()); CfPerfCache.Initialize(new Level2MemcachedPerfCache()); // Set the maximum number of concurrent connections //ServicePointManager.DefaultConnectionLimit = 12; } catch (Exception ex) { CfTrace.Error(ex); } return(base.OnStart()); }
public Message History(string id) { try { SvcContext ctx = InflateContext(); if (ctx.Invalid) { return(ctx.ContextMessage); } Guid uID; if (id == "me") { uID = CfIdentity.UserID; } else { uID = Guid.ParseExact(id, "N"); } //-- TODO: rewrite to use $expand and do single database call var usersCheckIns = visitsSvc.GetUsersHistory(uID).OrderByDescending(c => c.Utc).Take(15); var dto = new List <VisitDto>(); foreach (var ci in usersCheckIns) { //-- Here we use perf cache instead of Include()/join because it's likely the user will //-- have revisited the same place var loc = CfPerfCache.GetLocation(ci.LocationID); var ciDto = new VisitDto(ci, loc, "", ""); dto.Add(ciDto); } return(ReturnAsJson(dto)); } catch (Exception ex) { CfTrace.Error(ex); return(Failed("History query failed : " + ex.Message)); } }
protected void Application_Start() { CfTrace.InitializeTraceSource(new Instrumentation.CfTraceSource("Cf.Web")); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RouteRegistrar.RegisterRoutes(RouteTable.Routes); //-- Setup caching depending on if we're running in the cloud or not if (!RoleEnvironment.IsAvailable) { CfCacheIndex.Initialize(); CfPerfCache.Initialize(); } else { CfCacheIndex.Initialize(new Level2MemcachedCacheIndex()); CfPerfCache.Initialize(new Level2MemcachedPerfCache()); } Microsoft.IdentityModel.Web.FederatedAuthentication.ServiceConfigurationCreated += new EventHandler <Microsoft.IdentityModel.Web.Configuration.ServiceConfigurationCreatedEventArgs>(RsaServerfarmSessionCookieTransform.OnServiceConfigurationCreated); }
public ActionResult RebuildSearchIndex() { try { //-- Refresh our local cache AppLookups.RefreshCacheIndex(); //-- Refresh our remote cache & search index //var url = Stgs.RestSvcsUrl + "v0/search/refresh"; //var requestCookies = HttpContext.Request.Cookies; //var authCookies = new HttpCookieCollection(); //if (requestCookies.AllKeys.Contains("FedAuth")) { authCookies.Add(requestCookies.Get("FedAuth")); } //if (requestCookies.AllKeys.Contains("FedAuth1")) { authCookies.Add(requestCookies.Get("FedAuth1")); } return(Json(new { Success = true, Msg = "Cache refresh notification sent to server" })); } catch (Exception ex) { CfTrace.Error(ex); return(Json(new { Success = false, Error = ex.Message })); } }
/// <summary> /// Delete the specified image /// </summary> /// <param name="filePath"></param> /// <param name="fileName"></param> public override void DeleteImage(string filePath, string key) { DeleteObjectRequest request = new DeleteObjectRequest(); request.WithBucketName("images.climbfind.com" + filePath) .WithKey(key); using (var client = Amazon.AWSClientFactory.CreateAmazonS3Client(Stgs.AWSAccessKey, Stgs.AWSSecretKey, S3Config)) { // simple object put using (DeleteObjectResponse response = client.DeleteObject(request)) { //-- Do a little bit of tracing string headersString = string.Empty; WebHeaderCollection headers = response.Headers; foreach (string h in headers.Keys) { headersString += string.Format("Response Header: {0}, Value: {1}", h, headers.Get(h)); } CfTrace.Information(TraceCode.DeletingImage, headersString); } } }
public void Dispose() { lock (WriterLock) { if (!_disposed) { //Never checking for disposing = true because there are //no managed resources to dispose var writer = _writer; if (writer != null) { try { writer.Commit(); writer.Close(); IndexWriter.Unlock(_directory); } catch (ObjectDisposedException e) { CfTrace.Error(e); } _writer = null; } var analyzer = _analyzer; if (_analyzer != null) { try { analyzer.Close(); } catch (ObjectDisposedException e) { CfTrace.Current.Error(e); } } var directory = _directory; if (directory != null) { try { //var lockFactory = directory.GetLockFactory(); //foreach (var name in directory.ListAll()) { lockFactory.ClearLock(name); } directory.Close(); } catch (ObjectDisposedException e) { CfTrace.Current.Error(e); } } _disposed = true; } } GC.SuppressFinalize(this); }
/// <summary> /// Called from authenticated facebook client 'accounts.climbfind.com' and the mobile app /// </summary> /// <param name="email"></param> /// <param name="fullName"></param> /// <param name="password"></param> /// <param name="nationality"></param> /// <param name="isMale"></param> /// <param name="facebookID"></param> /// <param name="facebookToken"></param> /// <param name="signUpOrigin"></param> /// <returns></returns> public Profile CreateUser(string email, string fullName, string password, byte nationality, bool isMale, long?facebookID, string facebookToken, string signUpOrigin) { try { bool detailsValid = true; //-- todo, perform some sort of validation on incoming details if (detailsValid) { MembershipCreateStatus createStatus; var mUser = Membership.CreateUser(email, password, email, null, null, true, null, out createStatus); if (createStatus != MembershipCreateStatus.Success) { throw new MembershipCreateUserException(createStatus); } else { var userID = new Guid(mUser.ProviderUserKey.ToString()); var user = CreateProfile(new Profile() { ID = userID, CountryID = nationality, Email = email, FullName = fullName, IsMale = isMale, FacebookID = facebookID, FacebookToken = facebookToken, PrivacyAllowNewConversations = true, PrivacyShowFeed = true, PrivacyShowHistory = true, PrivacyPostsDefaultIsPublic = true, PrivacyShowInSearch = true, PrivacyShowOnPartnerSites = true }); var traceMsg = string.Format("{0} created an account via {1}", fullName, signUpOrigin); if (facebookID.HasValue) { traceMsg += " w fbid: " + facebookID.Value.ToString(); } CfTrace.Information(TraceCode.UserCreateAccount, traceMsg); MailMan.SendAppEvent(TraceCode.UserCreateAccount, traceMsg, email, userID, "*****@*****.**", true); try { if (facebookID.HasValue) { var originalImgUrl = string.Format("http://graph.facebook.com/{0}/picture?type=large", facebookID.Value); using (Stream imgStream = new ImageDownloader().DownloadImageAsStream(originalImgUrl)) { //-- Note this function automatically updates the user object in the database SaveProfileAvatarPicFrom3rdPartSource(imgStream, user); } } } catch (Exception ex) { CfTrace.Error(ex); } return(user); } } else { throw new Exception("Sign up detail invalid from origin: " + signUpOrigin); } } catch (Exception ex) //-- extra logging / safety as we really don't want this code to screw up and if it does be better know about it! { if (!ex.Message.Contains("form required for an e-mail address") && !ex.Message.Contains("username is already in use")) { CfTrace.Error(ex); } throw ex; } }
/// <summary> /// Used: /// 1) In the case when the facebook ID does not match a profile, but the user is signed in to facebook (we check if we can connect the accounts) /// 2) When the user logs in with their CF3 email/password to a client (Accounts Server, PG Site, CF4, Mobile App) for the first time /// </summary> public Profile GetUserByEmailAndCreateCf4ProfileIfNotExists(string email) { var profile = profileRepo.GetProfileByEmail(email); if (profile == null) { var cf3Profile = new cf.DataAccess.cf3.ClimberProfileDA().GetClimberProfile(email); if (cf3Profile != default(Cf3Profile)) { var idStr = cf3Profile.ID.ToString(); string userName = idStr.Substring(idStr.Length - 9, 8); profile = new Profile() { ID = cf3Profile.ID, CountryID = byte.Parse(cf3Profile.Nationality.ToString()), DisplayNameTypeID = 0, Email = email, FullName = cf3Profile.FullName, IsMale = cf3Profile.IsMale.Value, NickName = cf3Profile.NickName, UserName = userName, ContactNumber = cf3Profile.ContractPhoneNumber, PrivacyAllowNewConversations = true, PrivacyShowFeed = true, PrivacyShowHistory = true, PrivacyPostsDefaultIsPublic = true, PrivacyShowInSearch = true, PrivacyShowOnPartnerSites = true }; profileRepo.Create(profile); var traceMsg = string.Format("{0} upgraded cf3 account", cf3Profile.FullName); CfTrace.Information(TraceCode.UserCreateAccount, traceMsg); MailMan.SendAppEvent(TraceCode.UserCreateAccount, traceMsg, email, cf3Profile.ID, "*****@*****.**", true); try { var originalImgUrl = GetCf3ProfilePicFullSizeUrl(cf3Profile.ID, cf3Profile.ProfilePictureFile); if (!string.IsNullOrWhiteSpace(originalImgUrl)) { using (Stream imgStream = new ImageDownloader().DownloadImageAsStream(originalImgUrl)) { if (imgStream == null) { throw new ArgumentException("Cf3 image stream is null for: " + originalImgUrl); } if (profile == null) { throw new ArgumentException("Profile is null..."); } //-- Note this function automatically updates the user object in the database SaveProfileAvatarPicFrom3rdPartSource(imgStream, profile); } } } catch (Exception ex) { CfTrace.Error(ex); } } } return(profile); }
/// <summary> /// /// </summary> /// <param name="dto"></param> public void ProcessPartnerCallWorkItem(PartnerCallAlertWorkItem dto) { IfNullThrowArgumentExceptionAndClearMsg(dto, "Cannot process PartnerCallAlertWorkItem, dto object is null.", ""); var pc = pcRepo.GetByID(dto.PartnerCallID); IfNullThrowArgumentExceptionAndClearMsg(pc, "Cannot process PartnerCallAlertWorkItem[{0}], PartnerCall is null.", dto.ToJson()); var post = new PostRepository().GetByID(pc.ID); if (post == null) { pcRepo.Delete(pc.ID); return; } //-- If they've deleted the post, let's not send out anything and delete the original call... var place = AppLookups.GetCacheIndexEntry(pc.PlaceID); //if (place == null) //-- Maybe we tried to read when //{ // //} IfNullThrowArgumentExceptionAndClearMsg(place, "Cannot process PartnerCallAlertWorkItem[{0}] for place[{1}], Place is null.", pc.ID, pc.PlaceID); var by = CfPerfCache.GetClimber(pc.UserID); IfNullThrowArgumentExceptionAndClearMsg(by, "Cannot process PartnerCallAlertWorkItem[{0}] for byUser[{1}], User is null.", pc.ID, pc.UserID); PCNWorkItem pcnWi = new PartnerCallNotificationWorkItem() { ID = Guid.NewGuid(), CreatedUtc = DateTime.UtcNow, CountryID = place.CountryID, OnBehalfOfUserID = by.ID, PartnerCallID = pc.ID, PlaceID = pc.PlaceID }; var alerts = new List <Alert>(); var msg = string.Format("<a href='/climber/{0}'>{1}</a> posted a <a href='/partner-call/{2}'>PartnerCall™</a> for <a href='{3}'>{4}</a>", by.ID, by.DisplayName, pc.ID, place.SlugUrl, place.Name); var deduciblePlaces = CfPerfCache.GetGeoDeduciblePlaces(place); var subscriptionsByUsers = pcsRepo.GetSubscriptionsForPlaces(deduciblePlaces.Select(p => p.ID).ToList()) .Where(s => s.UserID != pc.UserID).GroupBy(s => s.UserID); //-- We only want to create one Alert per user for a single partner call foreach (var subsUserSet in subscriptionsByUsers) { try { var subscribedUser = CfPerfCache.GetClimber(subsUserSet.Key); if (subscribedUser == null) { throw new ArgumentException(string.Format("Cannot process partner call subscription alerts for user[{0}] as user is null", subsUserSet.Key)); } var matchingSubs = new List <PCSubscription>(); foreach (var sub in subsUserSet) { if (sub.PlaceID == place.ID || !sub.ExactMatchOnly) //-- Here we make sure we don't include subscription with ExactMatchOnly chosen { //-- Make sure we match on Indoor/Outdoor preferences if ((sub.ForIndoor && pc.ForIndoor) || (sub.ForOutdoor && pc.ForOutdoor)) { matchingSubs.Add(sub); } } } if (matchingSubs.Count > 0) { var alert = new Alert() { ID = Guid.NewGuid(), Utc = DateTime.UtcNow, TypeID = (byte)AlertType.PartnerCall, PostID = pc.ID, UserID = subscribedUser.ID, Message = msg }; alert.ByFeed = true; //-- Here we always put partner calls in the alert feed (unless at a later date we decide to change this). //-- Default notifications bool sendEmail = false; bool sendMobilePush = false; int count = 1; string subscriptionPlaces = string.Empty; foreach (var sub in matchingSubs) { if (sub.EmailRealTime) { sendEmail = true; } if (sub.MobileRealTime) { sendMobilePush = true; } var p = AppLookups.GetCacheIndexEntry(sub.PlaceID); if (count == 1) { subscriptionPlaces = p.Name; } else if (count == matchingSubs.Count) { alert.Message += string.Format(" & {0}", p.Name); } else { alert.Message += string.Format(", {0}", p.Name); } count++; } if (matchingSubs.Count == 1) { alert.Message += ", <i>matching subscription for " + subscriptionPlaces + ".</i>"; } else { alert.Message += ", <i>matching subscriptions for " + subscriptionPlaces + ".</i>"; } if (sendEmail) { MailMan.SendPartnerCallEmail(subscribedUser, by, place, pc, subscriptionPlaces); alert.ByEmail = true; } //if (sendMobilePush) //{ //SendAlertByMobilePush(alert); // alert.ByMobile = true; //} alerts.Add(alert); } } catch (Exception ex) // Here we have a try catch incase it fails for one user we can try and still process the others { CfTrace.Error(ex); } } pcnWi.NotificationsSent = alerts.Count(); pcnWi.ProcessedUtc = DateTime.UtcNow; pcWRepo.Create(pcnWi); //-- We have to check this again to see if they delete the post while we were processing var postagain = new PostRepository().GetByID(pc.ID); if (postagain != null) { new AlertRepository().Create(alerts); } CfTrace.Information(TraceCode.PartnerCallNofiticatonWorkItemProcess, "Processed {4} <a href='/climber/{0}'>{1}'s</a> <a href='/partner-call/{2}'>PartnerCall™</a> for {3}.", by.ID, by.DisplayName, pc.ID, place.Name, alerts.Count); }