gpt4 book ai didi

json - WCF 数据服务 5.0 返回 POCO 的解决方法?

转载 作者:行者123 更新时间:2023-12-04 05:39:36 24 4
gpt4 key购买 nike

我很确定它没有,但如果已经问过这个问题,我很抱歉。如果这只是一个愚蠢的问题,我会额外道歉,但我觉得我要么完全错过了某些东西,要么有正确的想法,只需要一些备份来保持理智。

我一直在我们的应用程序中实现 WCF 数据服务 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);
}
}

最佳答案

可以从服务操作中返回一种或多种原始、复杂或实体类型。

  • 原始类型是您所期望的:string、int、bool 等。
  • 复杂类型是没有唯一键的类(名为 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; }
    }
    }

    也许您遇到了其他问题?

    关于json - WCF 数据服务 5.0 返回 POCO 的解决方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11421648/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com