Всем привет!
Нашел непонятную багу, понял как исправить, исправил, через два месяца опять появилась, а как исправлять - забыл

. Решил написать как лечить сей непонятный глюк.
Предположим что у нас есть поле привязанное к таблице в Ах:
PHP код:
<dynamics:AxBoundField DataField="ShopId" DataSet="MyDataSet" DataSetView="MyDataSetView" SortExpression="ShopId"/>
Проблема появилась при раскрытии выпадающего списка на портале, который Ах делает сама. Если используется кэширование списка, то страница просто не открывается и пишет непонятные вещи:
Цитата:
Возникла необработанная ошибка.
При выполнении операции произошло исключение типа MetdataException.
mscorlib
Server stack trace:
в System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
в System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
в System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
в System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
в System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
в System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
в Microsoft.Dynamics.AX.Framework.Services.Metadata.Service.IAxMetadataService.GetTableMetadataById(Int32[] tableIds)
в Microsoft.Dynamics.AX.Framework.Services.Client.ServiceClientHelper.InvokeChannelOperation[TResult,TChannel](IServiceClient`1 client, Func`2 operationInvoker, Func`2 exceptionWrapper)
Как лечить.
Делаем шаблонное поле вместо ShopId:
PHP код:
<asp:TemplateField ConvertEmptyStringToNull="False" HeaderText="Магазин"
SortExpression="ShopId">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("ShopId") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"
Columns="<%$ AxDataSet: MyDataSet.MyDataSetView.ShopId.DisplayLength %>"
Enabled="<%$ AxDataSet: MyDataSet.MyDataSetView.ShopId.AllowEdit %>"
MaxLength="<%$ AxDataSet: MyDataSet.MyDataSetView.ShopId.StringSize %>"
Text='<%# Bind("ShopId") %>'></asp:TextBox>
<dynamics:AxLookup ID="AxLookup1" runat="server" DataSetView=" MyDataSetView" OnLookup="test_Lookup" LookupType="Custom"
TargetControlId="TextBox1"
Visible="<%$ AxDataSet: MyDataSet.MyDataSetView.ShopId.AllowEdit %>">
</dynamics:AxLookup>
</EditItemTemplate>
</asp:TemplateField>
Пишем LookUp метод:
PHP код:
protected void test_Lookup(object sender, AxLookupEventArgs e)
{
AxLookup lookup = e.LookupControl;
try
{
// Create the lookup dataset - we will do a lookup in the ContactPerson table
using (Microsoft.Dynamics.Framework.BusinessConnector.Proxy.SysDataSetBuilder sysDataSetBuilder = Microsoft.Dynamics.Framework.BusinessConnector.Proxy.SysDataSetBuilder.constructLookupDataSet(this.AxSession.AxaptaAdapter, Microsoft.Dynamics.AX.Framework.Services.Client.TableMetadata.TableNum(this.AxSession, "InventLocation")))
{
// Set the run time generated data set as the lookup data set
lookup.LookupDataSet = new Microsoft.Dynamics.AX.Framework.Portal.Data.DataSet(this.AxSession, sysDataSetBuilder.toDataSet());
}
// DataSet has to be init'ed before accessing the data sources
lookup.LookupDataSet.Init();
using (Microsoft.Dynamics.Framework.BusinessConnector.Adapter.IAxaptaRecordAdapter record = this.MyDataSet.GetDataSet().DataSetViews[this.MyDataSet.ProviderView].GetCurrent().GetRecord())
{
// Filter the lookup
Microsoft.Dynamics.Framework.BusinessConnector.Proxy.Query query = lookup.LookupDataSet.DataSetViews[0].MasterDataSource.query();
using (Microsoft.Dynamics.Framework.BusinessConnector.Proxy.QueryBuildDataSource qbds = query.dataSourceNo(1))
{
}
}
}
catch (System.Exception ex)
{
AxExceptionCategory exceptionCategory;
// This returns true if the exception can be handled here
if (!AxControlExceptionHandler.TryHandleException(this, ex, out exceptionCategory))
{
// The exception is system fatal - in this case we re-throw.
throw;
}
}
}
Заходим на портал, пробуем выбрать значение и получаем:
Цитата:
Произошла неизвестная ошибка.
Возникло исключение в службе метаданных на клиенте или на сервере. Подробные сведения об исключении см. ниже:
>В службе метаданных возникла ошибка при извлечении нескольких элементов метаданных. См. подробные сведения об исключениях по каждому из элементов ниже:
>>На сервере возникла ошибка при получении отдельного элемента метаданных типа "TableMetadata" с ключом "InventLocation".
Расширенный тип данных "ShopCategoryId" имеет неправильную связь, для связей типа "Normal" необходимы следующие свойства: Table и Field.
Microsoft.Dynamics.AX.Framework.Services.Client.MetadataServiceException
в Microsoft.Dynamics.AX.Framework.Services.Client.ServiceClientHelper.InvokeChannelOperation[TResult,TChannel](IServiceClient`1 client, Func`2 operationInvoker, Func`2 exceptionWrapper)
в Microsoft.Dynamics.AX.Framework.Services.Client.MetadataServiceProxyFactory.<>c__DisplayClass1a.<CreateTableMetadataProxy>b__18()
в Microsoft.Dynamics.AX.Framework.Services.Client.MetadataServiceProxyFactory.CreateTableMetadataProxy(String tableName)
в Microsoft.Dynamics.AX.Framework.Services.Client.MetadataCache.<.cctor>b__30(String alternateKey)
в Microsoft.Dynamics.AX.Framework.Services.Client.CustomMetadataAccessor`4.GetMainKeyFromAlternate(TAlternateKey alternateKey)
в Microsoft.Dynamics.AX.Framework.Services.Metadata.Caching.TripleKeyedItemCache`4.<>c__DisplayClassc.<GetItemInternal>b__a()
в Microsoft.Dynamics.AX.Framework.Services.Metadata.Caching.CacheBase.CacheRead(ICacheReadArgs cacheReadArgs, Action tryReadAction, Action readThroughAction)
в Microsoft.Dynamics.AX.Framework.Services.Metadata.Caching.TripleKeyedItemCache`4.GetItemByAlternateKey(TAlternateKey alternateKey)
в Microsoft.Dynamics.AX.Framework.Services.Client.TableMetadata.TableNum(String tableName)
Хоть стало понятно куда рыть.
Надеюсь кому-нибудь пригодиться.