我很确定它没有,但是如果已经提出这个问题我会道歉。如果这只是一个愚蠢的问题而另外道歉,但我觉得我要么完全缺少某些东西,要么有正确的想法,只需要为我自己的理智做一些备份。
我一直在我们的应用程序中实现WCF Data Services 5.0,并且对返回实体对象的读取操作没有任何问题。
不幸的是,在服务操作方面存在令人讨厌的限制,他们只能返回基本类型(See MSDN)。鉴于它对实体对象没有任何问题,这非常令人讨厌。
我知道一个解决方法是创建一个“虚拟”复杂类型,因为WCFDS会认识到这一点,但我不想将随机POCO扔到我的数据模型中而实际上不在数据库中。
因此,我遇到的解决方案是为我的对象创建一个扩展方法,可以将它们序列化为服务返回的JSON字符串。 我的问题是; 是否有任何令人信服的论据,为什么我不应该这样做,或者任何人都可以提出更好的选择?
修改:澄清我当前问题的其他信息
我创建了一个非常简单的例子,说明我最初提出这个问题的原因。我的服务类首先遵循:
[JsonpSupportBehavior]
public partial class SchedulingService : DataService<ChronosDataContext>, ISchedulingService
{
public static void InitializeService(DataServiceConfiguration config)
{
#if DEBUG
config.UseVerboseErrors = true;
#endif
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
config.SetServiceOperationAccessRule(
"TestService",
ServiceOperationRights.All);
}
[WebGet]
public SchedulingResult TestService(
string testParam1,
string testParam2)
{
// NOTE: I never use the params, they're just there for this example.
SchedulingResult result = SchedulingResult.Empty;
result.Status = OperationStatus.Success;
result.ResponseID = Guid.NewGuid();
result.AffectedIDs = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7 });
result.RecordsAffected = 10;
return result;
}
}
尝试使用我的浏览器访问此服务时,出现以下请求错误:
The server encountered an error processing the request. The exception message is
'Unable to load metadata for return type
'Chronos.Services.SchedulingResult' of method
'Chronos.Services.SchedulingResult TestService(System.String, System.String)'.'.
See server logs for more details.
The exception stack trace is:
at System.Data.Services.Providers.BaseServiceProvider.AddServiceOperation(MethodInfo method, String protocolMethod)
at System.Data.Services.Providers.BaseServiceProvider.AddOperationsFromType(Type type)
at System.Data.Services.Providers.BaseServiceProvider.LoadMetadata()
at System.Data.Services.DataService`1.CreateMetadataAndQueryProviders(IDataServiceMetadataProvider& metadataProviderInstance, IDataServiceQueryProvider& queryProviderInstance, BaseServiceProvider& builtInProvider, Object& dataSourceInstance)
at System.Data.Services.DataService`1.CreateProvider()
at System.Data.Services.DataService`1.HandleRequest()
at System.Data.Services.DataService`1.ProcessRequestForMessage(Stream messageBody)
at SyncInvokeProcessRequestForMessage(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
以下是构成我正在尝试返回的SchedulingResult的类:
public class SchedulingResult : ServiceInvocationResponse
{
public SchedulingResult()
: base()
{
this.Payload = new object[]
{
new List<int>(),
new List<int>()
};
}
public List<int> AffectedIDs
{
get { return (List<int>)Payload[0]; }
set { Payload[0] = value; }
}
public List<int> FailedIDs
{
get { return (List<int>)Payload[1]; }
set { Payload[1] = value; }
}
public static SchedulingResult Empty
{
get { return new SchedulingResult(); }
}
}
public class ServiceInvocationResponse : AbstractJsonObject<ServiceInvocationResponse>
{
public ServiceInvocationResponse()
{
this.Status = OperationStatus.Unknown;
this.Severity = ErrorSeverity.None;
}
public virtual int RecordsAffected { get; set; }
public virtual Exception ErrorObject { get; set; }
internal virtual object[] Payload { get; set; }
}
public abstract class AbstractJsonObject<TBaseType>
{
public virtual object Deserialize(string source)
{
return JsonConvert.DeserializeObject(source);
}
public virtual T Deserialize<T>(string source)
{
return JsonConvert.DeserializeObject<T>(source);
}
public string Serialize()
{
return JsonConvert.SerializeObject(
this, Formatting.Indented);
}
public override string ToString()
{
return this.Serialize();
}
public static TBaseType FromString(string json)
{
return JsonConvert.DeserializeObject<TBaseType>(json);
}
}
答案 0 :(得分:3)
可以从服务操作返回一个或多个原始,复杂或实体类型。
ID
或[DataServiceKey("<yourkeyhere>")]
属性的属性)例如:
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace Scratch.Web
{
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class ScratchService : DataService<ScratchContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
config.UseVerboseErrors = true;
}
[WebGet]
public string GetPrimitive()
{
return "Success";
}
[WebGet]
public IQueryable<string> GetPrimitives()
{
return new[] { "Success", "Hello World" }.AsQueryable();
}
[WebGet]
public ComplexType GetComplexType()
{
return new ComplexType { Property1 = "Success", Property2 = "Hello World" };
}
[WebGet]
public IQueryable<ComplexType> GetComplexTypes()
{
return new[] {
new ComplexType { Property1 = "Success", Property2 = "Hello World" },
new ComplexType { Property1 = "Success", Property2 = "Hello World" }
}.AsQueryable();
}
[WebGet]
public EntityType GetEntityType()
{
return new EntityType { Property1 = "Success", Property2 = "Hello World" };
}
[WebGet]
public IQueryable<EntityType> GetEntityTypes()
{
return new[] {
new EntityType { Property1 = "Success1", Property2 = "Hello World" },
new EntityType { Property1 = "Success2", Property2 = "Hello World" }
}.AsQueryable();
}
}
public class ScratchContext { }
public class ComplexType
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
[DataServiceKey("Property1")]
public class EntityType
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
}
也许你遇到了其他一些问题?