【问题标题】:WCF REST WebServiceHostFactory using linq to sqlWCF REST WebServiceHostFactory 使用 linq to sql
【发布时间】:2011-07-09 20:14:21
【问题描述】:

我正在尝试使用 WCF 实现 REST 服务,该服务将获取参数 P1、P2、P3、P4 并将它们传递给将执行查询并返回结果的存储过程。

我在 C# 中有此服务代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.ServiceModel.Activation;
using System.Data;

namespace RestServicePublishing
{
  [System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
  [ServiceContract]
  public class RestService
  {
    [OperationContract]
    [WebGet]
    public List<Simulated_service_State> GetState(decimal P1, decimal P2, decimal P3,  decimal P4)
    {
       using (ServiceDataContext db = new ServiceDataContext())
       {
           List<Simulated_service_State> states = 
              db.GetStateByLongLat(P1, P2, P3, P4).ToList();
           db.SubmitChanges();
           return states;
       }
    }
  }
}

Simulated_Service_State 是一个临时表,我将存储过程调用的结果存储到其中。当我通过浏览器调用网络服务时,出现以下错误:

请求错误

服务器遇到错误 处理请求。例外 消息是'未设置对象引用 到一个对象的实例。看 服务器日志以获取更多详细信息。这 异常堆栈跟踪是:

在 RestServicePublishing.ServiceDataContext..ctor() 在 C:....\RestServicePublishing\Service.designer.cs:line 39 在 RestServicePublishing.RestService.GetState(十进制 P1,十进制 P2,十进制 P3,十进制 P4) 在 C:....\RestServicePublishing\RestService.svc.cs:line 42 在 SyncInvokeGetState(对象, 对象 [] ,对象 [] )在 System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象 实例,Object[] 输入,Object[]& 输出)在 System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.MessageRpc.Process(布尔 isOperationContextSet)

!!!

我调用的网址如下:

http://localhost/RestServicePublishing/RestService.svc/GetState?P1=14&P2=13&P3=22&P4=55

谁能帮助我了解如何使用存储过程和 REST WCF 服务?如何将临时表中的值返回给客户端?

更新

我无法将所有这些数据发布到 cmets 部分,所以我将其发布在这里。 这是我现在使用的代码,但它给了我 0 作为结果,这意味着我的查询没有从表中选择任何内容:

public class RestService
{        
    [OperationContract]
    [WebGet (ResponseFormat = WebMessageFormat.Xml)]
    public string GetState(decimal P1, decimal P2, decimal P3, decimal P4)
    {
        IList<Simulated_service_State> query = new List<Simulated_service_State>();
        IList<string> Mac = new List<string>();
        int j;
        int jj;

        using (ServiceDataContext db = new ServiceDataContext())
        {
            query = db.GetStateByLongLat1(P1, P2, P3, P4).ToList();
            db.SubmitChanges();
            var query2 = from Simulated_service_State state in db.Simulated_service_States
                         select state.MAC;
            Mac = query2.ToList();
            jj = Mac.Count;
            j = query.Count;
        }
        return j.ToString() + "," + jj.ToString();
    }
}

如果我使用此代码(不是存储过程),我会从表中获取结果,因此我假设 linq to sql 工作正常(ServiceDataContext):

public class RestService
{

    [OperationContract]
    [WebGet (ResponseFormat = WebMessageFormat.Xml)]
    public string GetState(decimal P1, decimal P2, decimal P3, decimal P4)
    {
        IList<Simulated_service_State> query = new List<Simulated_service_State>();
        IList<string> Mac = new List<string>();
        int j;
        int jj;
        using (ServiceDataContext db = new ServiceDataContext())
        {
            var query3 = from SimulatedNode node in db.SimulatedNodes
                        select node.MAC;
            Mac = query3.ToList();
            j = (Mac.Count);
        }
        return j.ToString();

我得到的结果是 4,表示列表中的条目数。

知道如何进行吗?

【问题讨论】:

  • 你能调试到GetState方法看看什么是NULL吗??
  • 我假设您的 ServiceDataContext 出于某种原因无法创建(不确定该原因是什么) - 这就是错误消息似乎指向的内容......
  • 不幸的是,我无法使用调试器进入代码。我已经根据此处的说明设置了 web.config 文件:msdn.microsoft.com/en-us/library/bb157687.aspx 但我仍然无法调试代码。关于如何进入代码的任何想法?
  • btw:当我设置 WCF SOAP 服务时,相同的代码(使用 linq-to-sql sproc 进行查询)工作。但这次我需要设置 REST。
  • @Mark:您应该能够通过在 Visual Studio 中按 F5 来运行您的 WCF 服务,然后通过在浏览器中键入 URL 来向您的服务发出请求。您应该能够在您的代码(被调用的方法)中有一个断点,并且当您从浏览器发出该请求时就会被带到那里......

标签: c# wcf linq-to-sql rest


【解决方案1】:

我在想 GetStateByLongLat() 正在返回 null。然后 ToList() 将抛出“未设置对象实例的对象引用”。错误。

【讨论】:

  • 我已经在一个基于 SOAP 的服务中测试了这个存储过程,它在那里返回了结果。此外,我已经将它作为基于控制台的客户端应用程序进行了测试(没有通过 Web 服务公开结果)并且它工作正常。我怀疑 GetStateByLongLat() 的结果没有正确地将结果传递给列表。但这只是一个疯狂的猜测,因为我无法进入代码来查看那里到底发生了什么。
  • 旧式调试:明确地做事:将结果放入变量中,检查是否为空,迭代它并将其添加到新列表中,返回列表
  • 我不再收到错误消息(我认为它与 linq to sql 身份验证问题有关)。这是我正在使用的当前代码,但它正在返回 0 作为值。
【解决方案2】:

我放弃了使用存储过程进行查询,所以我使用了标准的 sql 查询函数,它可以工作并提供结果。这是最终代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.ServiceModel.Activation;
using System.Data;

namespace RestServicePublishing
{
[AspNetCompatibilityRequirements(RequirementsMode =     AspNetCompatibilityRequirementsMode.Allowed)]
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[ServiceContract]

public class RestService
{

    [OperationContract]
    [WebGet (ResponseFormat = WebMessageFormat.Json)]
    public List<Last_status_by_LongLat> GetState(decimal P1, decimal P2, decimal P3, decimal P4)
    {
        List<Last_status_by_LongLat> Mac = new List<Last_status_by_LongLat>();

        using (ServiceDataContext db = new ServiceDataContext())
        {
            var query = from view node in db.views
                         where table.param > P1 && table.param2 < P2 && table.param2 > P3 && table.param < P4
                         select table;
            Mac = query.ToList();


        }
        return Mac;

    }
}
}

我将 P1 - P4 参数传递给 sql 调用的“where”语句,然后将变量查询传递给“List Mac”,它将 SQL 视图表示为 linq to sql。最后,我将列表内容返回到 GetState WebGet 调用。

【讨论】:

  • 如果有人有适用于存储过程的解决方案,请分享。存储过程的编码更简单更干净,数据检索逻辑在SQL服务器端完成(我个人意见和个人喜好)。
猜你喜欢
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-23
相关资源
最近更新 更多