无法通过WCF数据服务中的浏览器查看动态添加的数据

时间:2014-04-02 09:07:29

标签: c# odata wcf-data-services

我已为动态数据提供程序实现了WCF数据服务。我正在使用内存中的虚拟数据源。我的实现基于Alex D James的精彩系列:http://blogs.msdn.com/b/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx

我的问题是,我能够通过客户端应用程序添加产品对象,响应也显示该对象已添加,但当我尝试通过客户端应用程序或浏览器通过产品密钥获取数据时,我收到错误消息“找不到段'DataSourceRecords'的资源。

我有这样的Initialize方法:

        config.SetEntitySetAccessRule("*", EntitySetRights.All);
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        config.DataServiceBehavior.AcceptCountRequests = true;
        config.DataServiceBehavior.AcceptProjectionRequests = true;

我正在使用动态数据提供程序:OrganizationDataService:DataService,IServiceProvider

其中OrganizationDataServiceProvider扩展了IDataServiceMetadataProvider并使用了我对OrganizationServiceContext的实现:

public class OrganizationServiceContext
{
    private List<DummyDataSource> records = new List<DummyDataSource>();
    private Dictionary<string, ResourceType> resourceTypes = new Dictionary<string, ResourceType>();
    private Dictionary<string, ResourceSet> resourceSets = new Dictionary<string, ResourceSet>();

    public OrganizationServiceContext()
    {
        PopulateMedataData(this);
    }

    private void AddResourceType(ResourceType resourceType)
    {
        //resourceType.SetReadOnly();
        resourceTypes.Add(resourceType.FullName, resourceType);
    }

    private void AddResourceSet(ResourceSet resourceSet)
    {
        resourceSet.SetReadOnly();
        resourceSets.Add(resourceSet.Name, resourceSet);
    }

    private void PopulateMedataData(OrganizationServiceContext orgServiceContext)
    {
        var productType = new ResourceType(
            typeof(DummyDataSource), // CLR type backing this Resource
            ResourceTypeKind.EntityType, // Entity, ComplexType etc
            null, // BaseType
            "Namespace", // Namespace
            "DummyDataSource", // Name
            false // Abstract?
        );
        var prodKey = new ResourceProperty(
           "ProdKey",
           ResourcePropertyKind.Key |
           ResourcePropertyKind.Primitive,
           ResourceType.GetPrimitiveResourceType(typeof(int))
        );
        var prodName = new ResourceProperty(
           "Name",
           ResourcePropertyKind.Primitive,
           ResourceType.GetPrimitiveResourceType(typeof(string))
        );
        var prodPrice = new ResourceProperty(
           "Price",
           ResourcePropertyKind.Primitive,
           ResourceType.GetPrimitiveResourceType(typeof(Decimal))
        );
        productType.AddProperty(prodKey);
        productType.AddProperty(prodName);
        productType.AddProperty(prodPrice);

        orgServiceContext.AddResourceType(productType);
        orgServiceContext.AddResourceSet(new ResourceSet("DataSourceRecords", productType));
    }

    public void PopulateContextData(OrganizationServiceContext orgServiceContext)
    {
        orgServiceContext.Records.Add(
            new DummyDataSource
            {
                ProdKey = 1,
                Name = "Janus",
                Cost = 4.35M,
                Price = 6.49M
            });
        orgServiceContext.Records.Add(
            new DummyDataSource
            {
                ProdKey = 2,
                Name = "Bugger",
                Cost = 4.97M,
                Price = 7.21M
            });
    }

    public Dictionary<string, ResourceType> GetResourceType()
    {
        return this.resourceTypes;
    }

    public Dictionary<string, ResourceSet> GetResourceSet()
    {
        return this.resourceSets;
    }

    public IQueryable GetQueryable(ResourceSet set)
    {
        if (set.Name == "DataSourceRecords")
        {
            return this.Records.AsQueryable();
        }
        else
        {
            throw new NotSupportedException(string.Format("{0} not found", set.Name));
        }
    }

    public List<DummyDataSource> Records
    {
        get
        {
            return this.records;
        }
    }

    public object CreateResource(ResourceType resourceType)
    {
        if (resourceType.InstanceType == typeof(DummyDataSource))
        {                
            Debug.WriteLine(string.Format("OrganizationServiceContext : CreateResource::If. resourceType = {0}, Context.HashCode = {1}", resourceType.InstanceType, this.GetHashCode()));

            return new DummyDataSource();
        }
        else
        {
            Debug.WriteLine(string.Format("OrganizationServiceContext : CreateResource::Else. resourceType = {0}, Context.HashCode = {1}", resourceType.InstanceType, this.GetHashCode()));
            throw new NotSupportedException(string.Format("{0} not found", resourceType.FullName));
        }
    }

    public void AddResource(ResourceType resourceType, object resource)
    {
        if (resourceType.InstanceType == typeof(DummyDataSource))
        {
            DummyDataSource temp = resource as DummyDataSource;
            if (temp != null)
            {
                Debug.WriteLine(string.Format("OrganizationServiceContext : AddResource. resourceType = {0}, resource = {1},  Context.HashCode = {2}", resourceType, resource, this.GetHashCode()));
                this.Records.Add(temp);

                //Below foreach loop is only for debug purpose, will be removed from final code.
                foreach (var pr in Records)
                {
                    Debug.WriteLine(string.Format("Prod Key = {0}, Name = {1}, Price = {2}", pr.ProdKey, pr.Name, pr.Price));
                }

                return;
            }
        }
        else
        {
            throw new NotSupportedException("Type not found");
        }
    }

    public void DeleteResource( object resource)
    {
        if (resource.GetType() == typeof(DummyDataSource))
        {
            this.Records.Remove(resource as DummyDataSource);

            return;
        }
        else
        {
            throw new NotSupportedException("Type not found");
        }
    }

    public void SaveChanges()
    {
        Debug.WriteLine(string.Format("OrganizationServiceContext : SaveChanges.  Context.HashCode = {0}", this.GetHashCode()));
        var prodKey = this.Records.Max(p => p.ProdKey);

        foreach (var prod in this.Records.Where(p => p.ProdKey == 0))
        {
            prod.ProdKey = prodKey+1;
        }

        //Below foreach loop is only for debug purpose, will be removed from final code.
        foreach (var pr in Records)
        {
            Debug.WriteLine(string.Format("Prod Key = {0}, Name = {1}, Price = {2}", pr.ProdKey, pr.Name, pr.Price));
        }
    }
}

任何人都可以帮我吗?

还有其他人遇到过这个问题吗?

1 个答案:

答案 0 :(得分:0)

好的,问题是我的提供商是在每个请求上创建的,所以我把它们改成单身,现在一切都很好。