I am using ABP v4.7.0 (.NET CORE 2.1) with angular client.
I built some custom localization providers. These providers get translation dictionaries from Azure Blob Storage. I add localization sources on startup with these providers.
localizationConfiguration.Sources.Add(
new DictionaryBasedLocalizationSource(InductothermMVPConsts.LocalizationSourceName,
new BlobEmbeddedFileLocalizationDictionaryProvider(
typeof(InductothermMVPLocalizationConfigurer).GetAssembly(),
"InductothermMVP.Core.Localization.SourceFiles"
)
)
);
On StartUp, I call this method and localization dictionaries are built correctly.
Now, I created one api endpoint which will update data in Azure Blob Storage, after files are updated, I am again initializing the dictionaries
public class BlobEmbeddedFileLocalizationDictionaryProvider : LocalizationDictionaryProviderBase
{
#pragma warning disable GCop406 // Mark {0} field as read-only.
private const int Count = 50;
#pragma warning restore GCop406 // Mark {0} field as read-only.
private readonly Assembly _assembly;
private readonly string _rootNamespace;
/// <summary>
/// Creates a new <see cref="BlobEmbeddedFileLocalizationDictionaryProvider"/> object.
/// </summary>
/// <param name="assembly">Assembly that contains embedded xml files</param>
/// <param name="rootNamespace">Namespace of the embedded xml dictionary files</param>
public BlobEmbeddedFileLocalizationDictionaryProvider(Assembly assembly, string rootNamespace)
{
_assembly = assembly;
_rootNamespace = rootNamespace;
InitializeDictionaries();
}
protected void InitializeDictionaries()
{
var sourceName = "XXXXXX";
var allCultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures);
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnection"]);
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("xxxxxx");
var res = container.CreateIfNotExistsAsync().GetAwaiter().GetResult();
var count = BlobEmbeddedFileLocalizationDictionaryProvider.Count;
var listBlobs = container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, count, null, null, null).GetAwaiter().GetResult();
foreach (var item in listBlobs.Results)
{
var blockBlob = container.GetBlockBlobReference(((Microsoft.WindowsAzure.Storage.Blob.CloudBlob)item).Name);
string path = _assembly.Location.Replace("xxxxx", "");
path += ((Microsoft.WindowsAzure.Storage.Blob.CloudBlob)item).Name;
blockBlob.DownloadToFileAsync(path, FileMode.OpenOrCreate).GetAwaiter().GetResult();
using (var stream = File.OpenRead(path))
{
var xmlString = Utf8Helper.ReadStringFromStream(stream);
InitializeDictionary(CreateXmlLocalizationDictionary(xmlString), isDefault: ((CloudBlob)item).Name.EndsWith(sourceName + ".xml"));
}
}
}
protected virtual XmlLocalizationDictionary CreateXmlLocalizationDictionary(string xmlString)
{
return XmlLocalizationDictionary.BuildFomXmlString(xmlString);
}
protected void InitializeDictionary<TDictionary>(TDictionary dictionary, bool isDefault = false)
where TDictionary : ILocalizationDictionary
{
if (Dictionaries.ContainsKey(dictionary.CultureInfo.Name))
{
throw new AbpInitializationException(SourceName + " source contains more than one dictionary for the culture: " + dictionary.CultureInfo.Name);
}
Dictionaries[dictionary.CultureInfo.Name] = dictionary;
if (isDefault)
{
if (DefaultDictionary != null)
{
throw new AbpInitializationException("Only one default localization dictionary can be for source: " + SourceName);
}
DefaultDictionary = dictionary;
}
}
}
internal static class Utf8Helper
{
public static string ReadStringFromStream(Stream stream)
{
var bytes = stream.GetAllBytes();
var skipCount = HasBom(bytes) ? 3 : 0;
return Encoding.UTF8.GetString(bytes, skipCount, bytes.Length - skipCount);
}
private static bool HasBom(byte[] bytes)
{
if (bytes.Length < 3)
{
return false;
}
if (!(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF))
{
return false;
}
return true;
}
}
This Provider is executed as expected.
But When I Refresh my client(Angular) Application, I still see the old Translations.
If I restart my API application, new translations are reflected correctly.
Can someone help me to understand, what am I missing here.
Thanks for the help in advance.
Related
FATAL ERROR: Unhandled Access Violation Reading 0x0008 Exception at 1d8257a5h
Failed missing output
I finally made it work with HostApplicationServices.getRemoteFile in local AutoCAD, then migrated it to Design Automation. It is also working now. The below is the command of .NET plugin.
To have a simple test, I hard-coded the URL in the plugin. you could replace the URL with the workflow at your side (either by an json file, or input argument of Design Automation)
My demo ReadDWG the entities from the remote URL file, then wblock the entities to current drawing (HostDWG), finally save current drawing.
Hope it helps to address the problem at your side.
.NET command
namespace PackageNetPlugin
{
class DumpDwgHostApp: HostApplicationServices
{
public override string FindFile(string fileName,
Database database,
FindFileHint hint)
{
throw new NotImplementedException();
}
public override string GetRemoteFile(Uri url,
bool ignoreCache)
{
//return base.GetRemoteFile(url, ignoreCache);
Database db =
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument.Database;
string localPath = string.Empty;
if (ignoreCache)
{
localPath =
Autodesk.AutoCAD.ApplicationServices.Application.
GetSystemVariable("STARTINFOLDER") as string;
string filename =
System.IO.Path.GetFileName(url.LocalPath);
localPath += filename;
using (var client = new WebClient())
{
client.DownloadFile(url, localPath);
}
}
return localPath;
}
public override bool IsUrl(string filePath)
{
Uri uriResult;
bool result = Uri.TryCreate(filePath,
UriKind.Absolute, out uriResult)
&& (uriResult.Scheme == Uri.UriSchemeHttp ||
uriResult.Scheme == Uri.UriSchemeHttps);
return result;
}
}
public class Class1
{
[CommandMethod("MyPluginCommand")]
public void MyPluginCommand()
{
try {
string drawingPath =
#"https://s3-us-west-2.amazonaws.com/xiaodong-test-da/remoteurl.dwg";
DumpDwgHostApp oDDA = new DumpDwgHostApp();
string localFileStr = "";
if (oDDA.IsUrl(drawingPath)){
localFileStr = oDDA.GetRemoteFile(
new Uri(drawingPath), true);
}
if(!string.IsNullOrEmpty(localFileStr))
{
//source drawing from drawingPath
Database source_db = new Database(false, true);
source_db.ReadDwgFile(localFileStr,
FileOpenMode.OpenTryForReadShare, false, null);
ObjectIdCollection sourceIds =
new ObjectIdCollection();
using (Transaction tr =
source_db.TransactionManager.StartTransaction())
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
SymbolUtilityServices.GetBlockModelSpaceId(source_db),
OpenMode.ForRead);
foreach (ObjectId id in btr)
{
sourceIds.Add(id);
}
tr.Commit();
}
//current drawing (main drawing working with workitem)
Document current_doc =
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument;
Database current_db = current_doc.Database;
Editor ed = current_doc.Editor;
//copy the objects in source db to current db
using (Transaction tr =
current_doc.TransactionManager.StartTransaction())
{
IdMapping mapping = new IdMapping();
source_db.WblockCloneObjects(sourceIds,
SymbolUtilityServices.GetBlockModelSpaceId(current_db),
mapping, DuplicateRecordCloning.Replace, false);
tr.Commit();
}
}
}
catch(Autodesk.AutoCAD.Runtime.Exception ex)
{
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
}
}
}
}
I created some site columns / a content type and a list definition as part of a feature. I want to attach an eventreceiver to the content type. I added code to attach the event receiver to the content type. Using spmanager i can see that the event receiver is attached to the content type however when i create lists from the content type the event reciever is missing. Any ideas. My code is below
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
string asmName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
string itemReceiverName = "xxxxxx.Intranet.SP.xxxxx.PermissionsUpdaterEventReceiver";
////surely a better way to get all lists than this
////re - do
using (SPSite thisSite = (SPSite)properties.Feature.Parent) {
using (SPWeb web = thisSite.RootWeb) {
SPContentType RambollNewsContentType = web.ContentTypes["RambollNewsContentType"];
RambollNewsContentType.EventReceivers.Add(SPEventReceiverType.ItemAdded, asmName, itemReceiverName);
RambollNewsContentType.Update(true);
}
}
}
I am using this successfully. I left in my logging and the logging method.
/// <summary>
/// This method is executed on feature activation.
/// It attaches the event receiver to the content type.
/// </summary>
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
LogMessage("FeatureActivated - Start");
SPSite site = (SPSite)properties.Feature.Parent;
LogMessage("FeatureActivated - 1");
SPWeb web = site.RootWeb;
LogMessage("FeatureActivated - 2");
//ListContentTypes(web);
SPContentType ctype = web.ContentTypes["Wells Project Task List"];
LogMessage("FeatureActivated - 3");
LogMessage("ctype name: " + ctype.Name.ToString());
if (ctype != null)
{
LogMessage("FeatureActivated - I have a content type. Web url: " + web.Url);
SPEventReceiverDefinition er = ctype.EventReceivers.Add();
er.Class = "Wells.SharePoint.ProjectManagementEventReceiver";
er.Assembly = "ProjectManagementEventReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a1cb21c41d80b7ae";
er.Type = SPEventReceiverType.ItemAdded;
er.Name = "ItemAdded";
er.SequenceNumber = 10001;
er.Update();
ctype.Update(false);
LogMessage("FeatureActivated - After ctype.update");
web.Dispose();
}
else
LogMessage("CT not found: " + web.Url);
LogMessage("FeatureActivated - End");
}
static void ListContentTypes(SPWeb web)
{
foreach (SPContentType ct in web.ContentTypes)
{
LogMessage("CT: " + ct.Name.ToString());
}
}
/// <summary>
/// This method is executed on feature deactivation.
/// It removes the event receiver from the content type
/// </summary>
/// <param name="properties"></param>
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
LogMessage("Feature DeActivated - Start");
SPSite site = (SPSite)properties.Feature.Parent;
SPWeb web = site.OpenWeb();
SPContentType contentType = web.ContentTypes["NAME OF CONTENT TYPE"];
if (contentType != null)
{
LogMessage("im have a content type. Web url: " + web.Url);
int i;
//Use the above integer to loop through the event recievers on the first list and delete the above assembly
for (i = 0; i < contentType.EventReceivers.Count; i++)
{
LogMessage("ER Count: " + contentType.EventReceivers.Count);
if (contentType.EventReceivers[i].Assembly.Contains("ProjectManagementEventReceiver"))
{
contentType.EventReceivers[i].Delete();
LogMessage("Deleting event receiver from CT");
}
}
contentType.Update();
}
else
LogMessage("CT not found: " + web.Url);
LogMessage("Feature DeActivated - End");
}
static void LogMessage(string msg)
{
StreamWriter wrtr = null;
try
{
wrtr = new StreamWriter("C:\\Logs\\FeatureActivatedDeactivated.txt", true);
wrtr.WriteLine(msg + "--[" + System.DateTime.Now.ToString() + "]" + Environment.NewLine);
wrtr.WriteLine(Environment.NewLine + "==================================");
}
catch (Exception e)
{
throw e;
}
finally
{
if (wrtr != null)
{
wrtr.Close();
wrtr.Dispose();
}
}
}
I am not sure is this related to your question or not but
but could you try to add the event receiver to the content type before you add the content type to the list.
I think the event receiver has to be added before because when adding a content type to a list the content type is not added directly to the list, rather a copy of it is added to the list. So when you add your content type to the list, there is no event receiver yet.
Correct me if i understand your question wrong?
Thanks
PROBLEM: I have a list and if I create a new Item I would like to do the following:
Create a new AutoIncrement Number in Column [AutoGeneratedID]
Use [Titel] and [AutoGeneratedID] to create a HyperLink in the List and a new subsite
The problem is i cant get the [AutogeneratedID] filled with a value because it is an itemadded event but if i try to put the code together in an ItemAdding event, i get a problem as described in the following link:
http://www.sharepoint-tips.com/2006/09/synchronous-add-list-event-itemadding.html
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using System.Diagnostics;
namespace KuC_Solution.EventReceiver1
{
/// <summary>
/// List Item Events
/// </summary>
public class EventReceiver1 : SPItemEventReceiver
{
/// <summary>
/// An item was added.
/// </summary>
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
// -----------------------------------------------------------
try
{
this.EventFiringEnabled = false;
// Column name AutoGeneratedID
string columnName = "AutoGeneratedID";
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPWeb web = properties.OpenWeb())
{
web.AllowUnsafeUpdates = true;
//get the current list
SPList list = web.Lists[properties.ListId];
int highestValue = 0;
foreach (SPListItem item in list.Items)
{
if (item[columnName] != null && item[columnName].ToString().Trim() != "")
{
string value = item[columnName].ToString();
try
{
int currValue = int.Parse(value);
if (currValue > highestValue)
highestValue = currValue;
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
}
}
SPListItem currItem = list.Items.GetItemById(properties.ListItem.ID);
currItem[columnName] = (highestValue + 1).ToString();
currItem.SystemUpdate(false);
web.AllowUnsafeUpdates = false;
}
});
this.EventFiringEnabled = true;
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
// -----------------------------------------------------------
}
/// <summary>
/// An item is being added.
/// </summary>
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
//-------------------------------------------------------------
// Get the web where the event was raised
SPWeb spCurrentSite = properties.OpenWeb();
//Get the name of the list where the event was raised
String curListName = properties.ListTitle;
//If the list is our list named SubSites the create a new subsite directly below the current site
if (curListName == "TESTautoNumber")
{
//Get the SPListItem object that raised the event
SPListItem curItem = properties.ListItem;
//Get the Title field from this item. This will be the name of our new subsite
String curItemSiteName2 = properties.AfterProperties["Title"].ToString();
//String curItemSiteName3 = properties.AfterProperties["ID"].ToString();
String mia = properties.AfterProperties["AutoGeneratedID"].ToString();
String curItemSiteName = curItemSiteName2 + mia;
//Get the Description field from this item. This will be the description for our new subsite
//String curItemDescription = properties.AfterProperties["Projekt-ID"].ToString();
string curItemDescription = "CREWPOINT";
//String testme = "1";
//Update the SiteUrl field of the item, this is the URL of our new subsite
properties.AfterProperties["tLINK"] = spCurrentSite.Url + "/" + curItemSiteName;
//Create the subsite based on the template from the Solution Gallery
SPWeb newSite = spCurrentSite.Webs.Add(curItemSiteName, curItemSiteName, curItemDescription, Convert.ToUInt16(1033), "{4ADAD620-701D-401E-8DBA-B4772818E270}#myTemplate2012", false, false);
//Set the new subsite to inherit it's top navigation from the parent site, Usefalse if you do not want this.
newSite.Navigation.UseShared = true;
newSite.Close();
}
//---------------------------------------------------------------
}
}
}
I have a List<class> of data. And I want to save it and retrieve it every time my app starts and exits respectively. What is the equivalent of IsolatedStorage (WP7) in Windows 8. How can I save these settings?
In windows 8, you have to use the LocalFolder for your app, which you can access using:
StorageFolder folder = ApplicationData.Current.LocalFolder;
and then reference files saved there by using:
var fileToGet = await folder.GetFileAsync("nameOfFile.fileType");
I am currently in a similar situation in a project I am working on, where I want to store a List of custom objects to my Apps LocalFolder and have it reloaded later.
My solution was to serialize the list to an XML string, and store this in the App Folder. You should be able to adapt my methods:
static public string SerializeListToXml(List<CustomObject> List)
{
try
{
XmlSerializer xmlIzer = new XmlSerializer(typeof(List<CustomObject>));
var writer = new StringWriter();
xmlIzer.Serialize(writer, List);
System.Diagnostics.Debug.WriteLine(writer.ToString());
return writer.ToString();
}
catch (Exception exc)
{
System.Diagnostics.Debug.WriteLine(exc);
return String.Empty;
}
Now that you have the string you can save it a text file and put this in LocalStorage:
//assuming you already have a list with data called myList
await Windows.Storage.FileIO.WriteTextAsync("xmlFile.txt", SerializeListToXml(myList));
Now when you load your app again you can use the loading method mentioned above to get the xmlFile from LocalStorage, and then deserialize it to get your List back.
string listAsXml = await Windows.Storage.FileIO.ReadTextAsync(xmlFile.txt);
List<CustomObject> deserializedList = DeserializeXmlToList(listAsXml);
Again, adapt this to your needs:
public static List<CustomObject> DeserializeXmlToList(string listAsXml)
{
try
{
XmlSerializer xmlIzer = new XmlSerializer(typeof(List<CustomObject>));
XmlReader xmlRead = XmlReader.Create(listAsXml);
List<CustomObject> myList = new List<CustomObject>();
myList = (xmlIzer.Deserialize(xmlRead)) as List<CustomObject>;
return myList;
}
catch (Exception exc)
{
System.Diagnostics.Debug.WriteLine(exc);
List<CustomObject> emptyList = new List<CustomObject>();
return emptyList;
}
}
You can use this class to store and load settings:
public static class ApplicationSettings
{
public static void SetSetting<T>(string key, T value, bool roaming = true)
{
var settings = roaming ? ApplicationData.Current.RoamingSettings : ApplicationData.Current.LocalSettings;
settings.Values[key] = value;
}
public static T GetSetting<T>(string key, bool roaming = true)
{
return GetSetting(key, default(T), roaming);
}
public static T GetSetting<T>(string key, T defaultValue, bool roaming = true)
{
var settings = roaming ? ApplicationData.Current.RoamingSettings : ApplicationData.Current.LocalSettings;
return settings.Values.ContainsKey(key) &&
settings.Values[key] is T ?
(T)settings.Values[key] : defaultValue;
}
public static bool HasSetting<T>(string key, bool roaming = true)
{
var settings = roaming ? ApplicationData.Current.RoamingSettings : ApplicationData.Current.LocalSettings;
return settings.Values.ContainsKey(key) && settings.Values[key] is T;
}
public static bool RemoveSetting(string key, bool roaming = true)
{
var settings = roaming ? ApplicationData.Current.RoamingSettings : ApplicationData.Current.LocalSettings;
if (settings.Values.ContainsKey(key))
return settings.Values.Remove(key);
return false;
}
}
But you can only save and load primitive types (bool, int, string, etc.). This is why you have to serialize your list to XML or another format which can be stored in a string. To serialize and deserialize an object to and from XML you can use these methods:
public static string Serialize(object obj)
{
using (var sw = new StringWriter())
{
var serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(sw, obj);
return sw.ToString();
}
}
public static T Deserialize<T>(string xml)
{
using (var sw = new StringReader(xml))
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(sw);
}
}
See also Is there a way to store instances of own classes in the ApplicationSettings of a Windows Store app?
I have a series of web parts I need to implement in SharePoint 2010. The data provider web part uses an UpdatePanel and asynchronously makes a web service call which can potentially be slow. To keep it simple, I've put a single consumer web part on the page (Chart) which will use the consumer as its data provider.
My problem is that I can't get the consumer to wait for the provider - I get a variety of errors but all basically come back to "There is no data available". This may be because it is a Chart web part but the question also applies to the other custom parts I will be developing as they will pull the same data.
The question is: how do I either push data to my consumers when my provider is ready or somehow let them wait for my provider to have data (via polling or whatever).
Note: this is just a prototype, I haven't added error handling, etc yet.
Code is below:
[ToolboxItem(true)]
public partial class ClarityProjectGeneral : System.Web.UI.WebControls.WebParts.WebPart , IWebPartTable
{
public DataTable ProjectVitals = new DataTable(); For web part communication
// bunch of properties
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
InitializeControl();
// For web part communication
// Initialize our datatable so the chart doesn't barf
DataColumn col = new DataColumn();
col.DataType = typeof(string);
col.ColumnName = "Name";
this.ProjectVitals.Columns.Add(col);
col = new DataColumn();
col.DataType = typeof(DateTime);
col.ColumnName = "Start";
this.ProjectVitals.Columns.Add(col);
col = new DataColumn();
col.DataType = typeof(DateTime);
col.ColumnName = "End";
this.ProjectVitals.Columns.Add(col);
}
protected void Page_Load(object sender, EventArgs e)
{
loading.Visible = true;
content.Visible = false;
}
public ClarityObjectClasses.Projects GetProject(string projectID)
{
Clarity.ClarityAbstractorProject ca = new Clarity.ClarityAbstractorProject(this.Username, this.Password);
Dictionary<string, string> queryParams = new Dictionary<string, string>();
queryParams.Add("projectID", projectID);
// Class for making web service call
ClarityObjectClasses.Projects response = new ClarityObjectClasses.Projects();
response = ca.GetProject(queryParams);
return response;
}
protected void Timer1_Tick(object sender, EventArgs e)
{
if (this.ProjectID == null || this.Username == null || this.Password == null)
{
lblConfigError.Visible = true;
lblConfigError.Text = "One or more required configuration values are not set. Please check the web part configuration.";
panelProjectDetails.Visible = false;
}
else
{
loading.Visible = true;
content.Visible = false;
panelProjectDetails.Visible = true;
ClarityObjectClasses.Projects projects = GetProject(this.ProjectID);
//Assign a bunch of values
// For web part communication
LoadTable(projects.Project[0]);
Timer1.Enabled = false;
loading.Visible = false;
content.Visible = true;
}
}
/* Interface functions for Graph Chart communication */
For web part communication
protected void LoadTable(ClarityObjectClasses.Project project)
{
DataRow row = ProjectVitals.NewRow();
row["Name"] = project.name;
row["Start"] = project.start;
row["End"] = project.finish;
this.ProjectVitals.Rows.Add(row);
}
public PropertyDescriptorCollection Schema
{
get
{
return TypeDescriptor.GetProperties(ProjectVitals.DefaultView[0]);
}
}
public void GetTableData(TableCallback callback)
{
callback(ProjectVitals.Rows);
}
public bool ConnectionPointEnabled
{
get
{
object o = ViewState["ConnectionPointEnabled"];
return (o != null) ? (bool)o : true;
}
set
{
ViewState["ConnectionPointEnabled"] = value;
}
}
[ConnectionProvider("Table", typeof(TableProviderConnectionPoint), AllowsMultipleConnections = true)]
public IWebPartTable GetConnectionInterface()
{
return this;
}
public class TableProviderConnectionPoint : ProviderConnectionPoint
{
public TableProviderConnectionPoint(MethodInfo callbackMethod, Type interfaceType, Type controlType, string name, string id, bool allowsMultipleConnections)
: base(callbackMethod, interfaceType, controlType, name, id, allowsMultipleConnections)
{
}
public override bool GetEnabled(Control control)
{
return ((ClarityProjectGeneral)control).ConnectionPointEnabled;
}
}
}
Do not quite understand, but if it helps
You may not use "connectable" web-parts inside UpdatePanel,
because of lack of corresponding events to bind data on asynchronous callback.
I just stumbled across this. I had exactly the same problem trying to implement a custom webpart just as a proof to myself. I applied filters to both my webpart and a list, and then let a chart consume them. What I found was that my webpart sent the wrong data, but the list webpart worked as expected.
So I reflected the XsltListViewWebPart (or whatever it's exact name is) and I discovered that there is an IConnectionData interface. This allows you to specify the dependencies and get the correct delay binding you need. GetRequiresData indicates that there are still more connections to be consumed before the data can be requested.