2010-07-08 1 views
0

Me и некоторые приятель пытаются начать работу с WCF Data Services, так что позвольте мне сначала описать то, что мы делали до сих пор:службы WCF Data не может обрабатывать UPDATE на записях фидов

  1. Мы создали довольно простую службу данных WCF с источником данных, который реализует интерфейс IUpdatable и предоставляет некоторые данные через некоторые общедоступные атрибуты IQueryable <> (код прилагается внизу). Используя Visual Studio 2010, сначала мы запускали нашу службу в IIS 7, но из-за ошибок, которые мы не могли понять, мы решили запустить ее с Cassini (веб-сервером Webdev).

  2. Мы написали клиента на C#, чтобы использовать эту услугу. Клиент работает так, как предполагалось, со всеми различными операциями данных (создавать, читать, обновлять и удалять). Все идет нормально! При размещении службы на веб-сервере IIS 7 мы должны были использовать туннелирование POST для обновления и удаления работы, но теперь она работает по назначению.

  3. Наша проблема возникает, когда мы пытаемся использовать сервис с нашими клиентами Java (Restlet) и Ruby (ruby_odata): мы не можем обновлять данные с этими клиентами (мы получаем «Внутреннюю ошибку сервера 500» и «Метод Не разрешено "ответ с сервера). Мы использовали два довольно простых учебника [a, b], которые кажутся довольно прямыми, чтобы создать наших клиентов. Поэтому мы считаем, что наши проблемы лежат в пределах нашего обслуживания.

a. ruby_odata: http: //rdoc.info/projects/visoft/ruby_odata
b. restlet: http: //wiki.restlet.org/docs_2.0/13-restlet/28-restlet/287-restlet/288-restlet.html

Оба этих клиента указаны как SDK OData (http://www.odata.org/developers/odata-sdk) и должны работайте отлично, чтобы потреблять фид OData.

Одна вещь, которую мы заметили при мониторинге HTTP-запросов, заключается в том, что клиент C# использует HTTP MERGE-глагол для обновлений (см. Здесь дополнительную информацию: http: //blogs.msdn.com/b/astoriateam/archive/ 2008/05/20/merge-vs-replace-semantics-for-update-operations.aspx), в то время как Java и Ruby использует HTTP PUT для обновлений. Может ли это быть причиной того, что работает только наш клиент C#? Что мы можем сделать для включения обновлений PUT?

Мы только начали с .NET, и был бы признателен, если это можно было бы принять во внимание, когда вы отвечаете

using System; 
using System.Collections.Generic; 
using System.Data.Services; 
using System.Linq; 
using System.Data.Services.Providers; 
using System.Reflection; 
using System.ServiceModel.Web; 
using System.Data.Services.Common; 

namespace WCFDataServiceApp 
{ 

    public class Product 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     public string Color { get; set; } 
     public Category ProductCategory { get; set; } 
    } 

    public class Category 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 


    } 

    public class AWData : IUpdatable 
    { 

     static List<Category> categories; 
     static List<Product> products; 

     static AWData() 
     { 

      categories = new List<Category>() { 
       new Category { ID = 1, Name = "Bikes" }, 
       new Category { ID = 2, Name = "Parts" }, 
       new Category { ID = 3, Name = "Wheels"}, 
      }; 

      products = new List<Product>() { 
       new Product { ID = 1, Name = "Red Bike", Color = "Red", ProductCategory = categories[0] }, 
       new Product { ID = 2, Name = "Blue Bike", Color = "Blue", ProductCategory = categories[0] }, 
       new Product { ID = 3, Name = "Green Bike", Color = "Green", ProductCategory = categories[0] }, 
       new Product { ID = 4, Name = "Yellow Bike", Color = "Yellow", ProductCategory = categories[0] }, 
       new Product { ID = 5, Name = "Pink Bike", Color = "Pink", ProductCategory = categories[0] }, 
       new Product { ID = 6, Name = "Black Bike", Color = "Black", ProductCategory = categories[0] } 
      };   

     } 

     public IQueryable<Category> Categories 
     { 
      get { return categories.AsQueryable(); } 
     } 

     public IQueryable<Product> Products 
     { 
      get { return products.AsQueryable(); } 
     } 




     void IUpdatable.AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded) 
     { 
      System.Diagnostics.Debug.WriteLine("No support for AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)"); 
     } 

     void IUpdatable.ClearChanges() 
     { 
      System.Diagnostics.Debug.WriteLine("ClearChanges()"); 
     } 

     public object CreateResource(string containerName, string fullTypeName) 
     { 
      System.Diagnostics.Debug.WriteLine("CreateResource(string containerName, string fullTypeName)"); 
      Type t = Type.GetType(fullTypeName); 

      // Check if resource exists 
      if (t != null) 
      { 
       object resource = Activator.CreateInstance(t); 
       if (containerName.Equals("Categories")) 
       { 
        categories.Add((Category)resource); 
       } 
       else if (containerName.Equals("Products")) 
       { 
        products.Add((Product)resource); 
       } 
       return resource; 
      } 
      // Current resource does not exist 
      return new Exception("Could not create a resource of type " + containerName); 

     } 

     void IUpdatable.DeleteResource(object targetResource) 
     { 
      // 1. Check object type 

      if (targetResource.GetType().IsInstanceOfType(new Category())) 
      { 
       System.Diagnostics.Debug.WriteLine("Category deleted!"); 
       categories.Remove((Category)targetResource); 
      } 
      else if (targetResource.GetType().IsInstanceOfType(new Product())) 
      { 
       System.Diagnostics.Debug.WriteLine("Product deleted!"); 
       products.Remove((Product)targetResource); 
      } 

     } 

     object IUpdatable.GetResource(IQueryable query, string fullTypeName) 
     { 
      System.Diagnostics.Debug.WriteLine("GetResource(IQueryable query, string fullTypeName)"); 
      object obj = null; 
      foreach (object o in query) 
      { 
       obj = o; 
      } 
      return obj; 

     } 



     object IUpdatable.GetValue(object targetResource, string propertyName) 
     { 
      System.Diagnostics.Debug.WriteLine("GetValue(object targetResource, string propertyName)"); 
      return null; 
     } 

     void IUpdatable.RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved) 
     { 
      System.Diagnostics.Debug.WriteLine("RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)"); 
     } 

     object IUpdatable.ResetResource(object resource) 
     { 

      System.Diagnostics.Debug.WriteLine("ResetResource(object resource)"); 
      return null; 
     } 

     object IUpdatable.ResolveResource(object resource) 
     { 
      return resource; 
     } 

     void IUpdatable.SaveChanges() 
     { 
      System.Diagnostics.Debug.WriteLine("SaveChanges()"); 
     } 

     void IUpdatable.SetReference(object targetResource, string propertyName, object propertyValue) 
     { 
      System.Diagnostics.Debug.WriteLine("SetReference(object targetResource, string propertyName, object propertyValue)"); 
     } 

     void IUpdatable.SetValue(object targetResource, string propertyName, object propertyValue) 
     { 
      PropertyInfo pi = targetResource.GetType().GetProperty(propertyName); 

      if (pi == null) 
       throw new Exception("Can't find property"); 
      pi.SetValue(targetResource, propertyValue, null); 

      System.Diagnostics.Debug.WriteLine("Object " + targetResource + " updated value " + propertyName + " to " + propertyValue); 
     } 

     public void SetConcurrencyValues(object resourceCookie, bool? checkForEquality, IEnumerable<KeyValuePair<string, object>> concurrencyValues) 
     { 
      System.Diagnostics.Debug.WriteLine("SetConcurrencyValues(object resourceCookie, bool? checkForEquality, IEnumerable<KeyValuePair<string, object>> concurrencyValues) was called"); 
      throw new Exception("SetConcurrencyValues(object resourceCookie, bool? checkForEquality, IEnumerable<KeyValuePair<string, object>> concurrencyValues) not implemented"); 
     } 
    } 

    public class aw : DataService<AWData> //, IServiceProvider 
    { 
     // This method is called only once to initialize service-wide policies. 
     public static void InitializeService(DataServiceConfiguration config) 
     { 
      config.SetEntitySetAccessRule("*", EntitySetRights.All); 
      //config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 

     } 
     /* 
     public object GetService(Type serviceType) 
     { 

      System.Diagnostics.Debug.WriteLine(serviceType.ToString()); 
      return this; 
     }*/ 
    } 
} 

ответ

Смежные вопросы