I have a custom site template which activates a feature with an event receiver, the only thing that receiver does is to activate some other features, all in the same receiver.
The first feature I activate is a ListTemplate called "Audits".
In the third feature I activate, I try to use that template via the object model, however it isn't found, so it throws an exception.
I tried to update the site with a web.Update() but that didn´t work either.
The code doesn´t work when its activated via the site template, that means, if I activate my feature from an already created site, it works fine.
Is there a way to access the ListTemplate when the site is created¿?
Thanks in advance
EDIT: This is the main feature
/// <summary>
/// Evento disparado al activar la feature
/// </summary>
/// <param name="properties"></param>
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//Obteniendo el sitio (web) en donde fue activada la feature
SPWeb web = (SPWeb)properties.Feature.Parent;
//Guid a utilizar para instalar las features
Guid g;
//GUID de Feature de list template de auditorías
g = new Guid("{3b91e461-e8c9-49dd-857a-671eb031017c}");
if (web.Features[g] == null)
web.Features.Add(g);
//GUID de Feature Catalogos
g = new Guid("{d102dd61-0aaf-4a18-8bcc-2260e78cc87c}");
if (web.Features[g] == null)
web.Features.Add(g);
//GUID de Feature Content type de auditorías
g = new Guid("{a5c3defb-bcbf-41e5-aefc-2617814d25d6}");
if (web.Features[g] == null)
web.Features.Add(g);
//GUID de Feature CheckList template
g = new Guid("{63fa11ba-e8e2-414d-bb7e-a3cdbce11cfe}");
if (web.Features[g] == null)
web.Features.Add(g);
//GUID de Feature asocia eventos
g = new Guid("{bbc32500-034d-4d9e-a048-558d62edfe53}");
if (web.Features[g] == null)
web.Features.Add(g);
//GUID de Feature para crear preguntas
g = new Guid("{ee66eb41-57a4-400a-9c50-8db0e6beeb80}");
if (web.Features[g] == null)
web.Features.Add(g);
//GUID de Feature para ECB
g = new Guid("{9bbdb06c-4ea1-4328-8b3d-828ea2043d3e}");
if (web.Features[g] == null)
web.Features.Add(g);
//GUID de Feature para hallazgos
g = new Guid("{acfdda27-58d5-4f7e-a6de-0a7fe190bc74}");
if (web.Features[g] == null)
web.Features.Add(g);
//GUID de Feature para resultados
g = new Guid("{a9a804dd-18a3-47a0-80bf-25e785a8cac8}");
if (web.Features[g] == null)
web.Features.Add(g);
}
The first feature is the list template.
The third feature has a receiver in which i look for the template
//Obteniendo el template
SPListTemplate ltAuditorias = sitio.ListTemplates["Auditoria"];
However, I get an Index out of range exception, because it's not found.
As I said, it only happens when the main feature is activated via the site template in the Feature tag.
If I create a Blank site and then activate the main feature, everything works.
Thanks
Your site is probably not fully provisioned at the time your feature receiver is fired. This means not all site elements (e.g. the list templates) are available.
As a workaround you could implement a provisioning provider.
The SPWebProvisioningProvider lets you take control of the SPWeb (Web site) or SPSite (Site Collection) that your are provisioning. Instead of just using a Site Template and the changes that can be applied through a Site Template you can add your own custom code to the solution.
from The mystery that is SPWebProvisioningProvider.
Related
Our customer has a request to record GPS location in Appointments screen when technician starts a drive to the site.
I added a new action to AppointmentEntry graph (basically it is a copy of StartAppointment action with some code removed) and added this action to mobile app. The problem is that fsAppointmentCopy.Mem_GPSLatitudeLongitude is null when my custom action invoked on mobile app, but it has a value when "Start Appointment" action is invoked. What am I missing?
public PXAction<PX.Objects.FS.FSAppointment> StartDrive;
[PXButton]
[PXUIField(DisplayName = "Start Drive", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable startDrive(PXAdapter adapter)
{
List<FSAppointment> list = adapter.Get<FSAppointment>().ToList();
foreach (FSAppointment fsAppointmentRow in list)
{
Base.SaveBeforeApplyAction(Base.AppointmentRecords.Cache, fsAppointmentRow);
FSAppointment fsAppointmentCopy = (FSAppointment)Base.Caches[typeof(FSAppointment)].CreateCopy(fsAppointmentRow);
var fsAppointmentDetRows = Base.AppointmentDetServices.SelectWindowed(0, 1);
if (fsAppointmentDetRows.Count == 0)
{
throw new PXException(TX.Error.APPOINTMENT_START_VALIDATE_SERVICE, PXErrorLevel.Error);
}
using (var ts = new PXTransactionScope())
{
if (Base.IsMobile == true
&& Base.SetupRecord.Current != null
&& Base.SetupRecord.Current.TrackAppointmentLocation == true
&& string.IsNullOrEmpty(fsAppointmentCopy.Mem_GPSLatitudeLongitude) == false)
{
string[] parts = fsAppointmentCopy.Mem_GPSLatitudeLongitude.Split(':');
fsAppointmentCopy.GPSLatitudeStart = decimal.Parse(parts[0]);
fsAppointmentCopy.GPSLongitudeStart = decimal.Parse(parts[1]);
}
Base.ChangeStatusSave(fsAppointmentCopy);
ts.Complete();
}
}
return list;
}
Your sample "Start Drive" action worked for me (with slight modifications to make it work with most recent Acumatica version):
A couple of things worth checking:
Double check that mobile Acumatica app was granted access to location. (on iOS: Settings / Acumatica / Location)
Are you sure your code runs to the point when it reads coordinates from the field? It may fail during record save (some fields are not filled) or when validating that at least one detail line is present
Make sure that mobile screen mapping still contains definition for "OtherInformationSourceInfoLocation#GPSLatitudeLongitude" with special = GpsCoords
I have a problem with updating properties of sharepoint 2010 feature
this is my code :
using (SPSite site = new SPSite("http://vm-pc:2000"))
{
foreach (SPFeatureDefinition def in SPFarm.Local.FeatureDefinitions)
{
if (def.Scope == SPFeatureScope.WebApplication)
{
if (def.GetTitle(System.Threading.Thread.CurrentThread.CurrentCulture) == "Configure Site Settings")
{
((SPFeatureProperty)def.Properties[0]).Value = "5";
def.Properties.Update();
def.Update();
}
}
}
}
The problem with def.Properties.Update();
It throws an exception :
Updating the properties of a feature definition is not supported.
Why dont you use the Property bag?
SPSite site = new SPSite("URL");
SPWeb web = site.RootWeb;
web.Properties.Add("Key", "Value");
web.Properties.Update();
and get value:
web.AllProperties["Key"]
well i am doing a connection... sql server with web service, web service with j2me, but now i am doing one helloworld...i could it, but now than i want to do one "hello world "+nombre...
parameter is not receive in web service, here the web service
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// Para permitir que se llame a este servicio web desde un script, usando ASP.NET AJAX, quite la marca de comentario de la línea siguiente.
// [System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService
{
public Service () {
}
[WebMethod]
public string HelloWorld(String nombre)
{
return "Que onda " + nombre;
}
}
and this is the code for call it with ksoap...
String nombremetodo="HelloWorld";
String url="http://localhost:49175/WebSite1/Service.asmx";
String namespace="http://tempuri.org/";
String SOAP_ACTION=namespace+nombremetodo;
public void traer()
{
SoapObject busqueda =new SoapObject(namespace,nombremetodo);
HttpTransport transportacion = new HttpTransport(url);
busqueda.addProperty(new String("nombre"),new String("Angel"));
System.out.println("parametro agregado");
//busqueda.addProperty(PropertyInfo.OBJECT_TYPE, "Angel");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
transportacion.debug=true;
envelope.bodyOut=busqueda;
System.out.println("todo ok");
try{
System.out.println("comenzando transportacion");
transportacion.call(SOAP_ACTION, envelope);
System.out.println("transportacion ok");
respuesta = envelope.getResponse().toString();
System.out.println("respuesta ok");
}
catch(Exception e)
{
texto.setString("fallo");
System.out.println("falla en el try");
System.out.println(e);
}
}
i get it returns "que onda " with a space, because so i put it in web service, but never it returns "que onda "+nombre ... it is a application for j2me not for
android, i watch for android it is soo...
PropertyInfo p1 = new PropertyInfo();
p1.setName("nombre");
p11.setValue("Angel");
busqueda.addProperty(p1);
but ksoap for j2me doesn't have those methods.. "setName, setValue";
i have downloades this library but i get a ugly bug and application doesn't run...
with this i see parameter is added so..
busqueda.addProperty("nombre","Angel");
but this it doesn't work...
it does run it doesn't have any bug, but web service never receive the parameter...
thank you people of STACKOVERFLOW
my english is not very well sorry
i solved it, it is necesary write
envelope.dotNet=true;
am working on a project where I want to pull data from different lists in SharePoint and have these data imported into a single list. The list has the same attribute everywhere; it is located in different sites.
I have a list which contains all the site names and URL to those sites. The idea is to read from this list all the site names and then go to each one of those sites and try and pull the information from the list under that particular site, in synchronies matter. Data that are pulled from last week’s process do not need to be pulled again.
Can someone guide me in explaining what would be the best way to doing this solution?
Am using SharePoint 2007
You may be better off looking at the Data View Web Part (DVWP) and rollups
A common topic that is asked about in
SharePoint, is how to roll up
information from sub-sites to a top
level site, and just generally how to
show data from one site on another
site.
I have this scenario. I made a webpart that sends the information for my consolidation list, through the sharepoint web services.
I installed the webpart in each sharepoint site, this webpart get the data (when it's outdated) and make a insert in the consolidation list through the lists.asmx webservice. See http://msdn.microsoft.com/en-us/library/lists(v=office.12).aspx. Then a I create a user with permission to write in the consolidation list in my consolidation site, and used this to authenticate my webpart when it will do the insert on the list.
I did something like this, in Visual Studio 2005, with Sharepoint dll referenced.
public void InsertToPainel(string strID, string user, string password)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
try
{
//WSPainel is the WebReference to http://<site>/_vti_bin/Lists.asmx.
using (WSPainel.Lists lstPainel = new webPartSender.WSPainel.Lists())
{
lstPainel.UseDefaultCredentials = true;
lstPainel.Credentials = new System.Net.NetworkCredential(user, password);
#region Make the fields in consolidation list
Dictionary<string, string> fieldsNamesAndValues = new Dictionary<string, string>();
fieldsNamesAndValues.Add("ID", strID);//Recuperar quando for atualizar ou incluir New
fieldsNamesAndValues.Add("URL", SPContext.Current.Web.Url + ", " + splInfGerItems[0]["Title"].ToString()); //The link of the actual site that is sending the information
fieldsNamesAndValues.Add("Comments", splStatusItems[0]["Title"].ToString());//In my case, I just need the last result.
#endregion
//It will make the register in CAML format and updates the lists.
lstPainel.UpdateListItems(_listaPainel, NewCAMLRegister(fieldsNamesAndValues, strID));
}
}
catch (Exception e)
{
//Exception
}
});
}
private XmlNode NewCAMLRegister(Dictionary<string, string> FieldsNamesAndValues, string strID)
{
try
{
XmlDocument xdMensagem = new XmlDocument();
XmlElement xeBatch = xdMensagem.CreateElement("Batch");
XmlNode xnMethod = xdMensagem.CreateElement("Method");
xdMensagem.AppendChild(xeBatch);
xeBatch.AppendChild(xnMethod);
XmlAttribute xaID = xdMensagem.CreateAttribute("ID");
XmlAttribute xaCmd = xdMensagem.CreateAttribute("Cmd");
xaID.Value = "1"; //Id do comando no Batch.
if (strID == "New")
{
xaCmd.Value = "New";
}
else
{
xaCmd.Value = "Update";
}
xnMethod.Attributes.Append(xaID);
xnMethod.Attributes.Append(xaCmd);
foreach (KeyValuePair<string, string> strfieldname in FieldsNamesAndValues)
{
XmlNode xnField = xdMensagem.CreateElement("Field");
XmlAttribute xaName = xdMensagem.CreateAttribute("Name");
xaName.Value = strfieldname.Key;//Nome do Campo
xnField.Attributes.Append(xaName);
xnField.InnerText = strfieldname.Value;//Valor do Campo
xnMethod.AppendChild(xnField);
}
//"<Method ID=\"1\" Cmd=\"New\">" + "<Field Name=\"ID\">New</Field>" + "<Field Name=\"Title\">This is a test</Field>" + "</Method>";
return xdMensagem;
}
catch (Exception e)
{
//Exception
return null;
}
}
I hope it helps.
I have a site as follows:
--SiteA
----Subsite1
----Subsite2
Now whenever i try to access the QuickLaunch Property its always empty e.g
SPNavigation nav = spWeb.Navigation;
if (nav.QuickLaunch.Count == 0)
{
// ALWAYS TRUE
}
However if i go into the Naviation Settings (Through the UI) of SiteA and reorder any site in the list, only then will the QuickLanuch become available. (Other settings are left as default)
Can anyone explain this behaviour? I really need access to the QuickLaunch items.
Thanks
This error occurs if you access quicklaunch while site is being created.Below code causes the feature activated code to wait until the site collection has been created before executing.
using System.Threading;
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//Queues changes until after site exists. For use in provisioning.
SPWeb web = properties.Feature.Parent as SPWeb;
ThreadPool.QueueUserWorkItem(ApplyYourChanges, web.Url);
}
private void ApplyYourChanges(object state)
{
string webUrl = state as string;
Uri uri = new Uri(webUrl);
// additional conditions here -- perhaps check if a feature was activated
while (!SPSite.Exists(uri))
{
Thread.Sleep(5000);
}
using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
//configure the quicklaunch menu
configureQuickLaunch(web);
}
}
}
public static void configureQuickLaunch(SPWeb spWeb)
{
SPNavigationNodeCollection nodeCollection = spWeb.Navigation.QuickLaunch;
SPNavigationNode heading = nodeCollection.Cast<SPNavigationNode>().FirstOrDefault(n => n.Title == headingNode);
SPNavigationNode item = heading.Children.Cast<SPNavigationNode>().FirstOrDefault(n => n.Url == url);
if(item == null)
{
item = new SPNavigationNode(nodeName, url);
item = heading.Children.AddAsLast(item);
}
}
I think, by default, the QuickLaunch uses shared navigation. In other words, the QuickLaunch for a subsite doesn't have its own collection of nodes until you do something with it. If you reorder a site, that gives it its own unique set of nodes.
If you wanted to programmatically set your QuickLaunch to have its own set of nodes programmatically, you should be able to do so this way:
SPNavigation nav = spWeb.Navigation;
nav.UseShared = false;
spWeb.Update();
I think your count should be something other than zero at that point.
I seem to remember reading somewhere that the QuickLaunch collection only stored customisations to the default ordering. Looking around, I can't find that documentation to show you, but it would explain the behavior you see if true.
So your QuickLaunch.Count == 0 is just confirming that default ordering of items is in place.
You can still add nodes, if that's at all helpful;
SPNavigationNodeCollection nodes = web.Navigation.QuickLaunch;
SPNavigationNode node = new SPNavigationNode("Node Name", "Node URL", true);
nodes.AddAsFirst(node);