WCF、MVC2、获取对自动生成的 WSDL 的访问权限并通过默认端点工作未发现问题

发布于 2024-11-04 20:04:08 字数 4624 浏览 4 评论 0原文

我正在尝试在运行 MVC2 应用程序的同一个 IIS7 网站上运行一个非常基本的 Web 服务。这提出了几个不同的问题,我相信这与我的 system.serviceModel 有关,但显然我不确定(或者我会修复它)。 在服务器端,我可以很好地运行我的服务,帮助操作就像一个魅力。我可以执行默认的 WCF 操作 GetData 并通过 FireFox 地址栏提供值。

http://localhost/services/service1/getdata?value=3 (示例

)我遇到的第一个问题是,当我导航到基本服务 URI 时,它将显示以下消息。虽然这并不是世界末日,因为我仍然可以通过操作地址来执行代码;我确实希望能展示其他东西。我期望标准的新 Web 服务消息解释说,通过将“?wsdl”附加到地址,您将收到自动生成的 WSDL。我无法访问自动生成的 WSDL。

“未找到端点。请参阅 构建服务帮助页面 对服务的有效请求。”

第二个问题与连接到我的 Web 服务的客户端应用程序有关。我在单独的 Visual Studio 解决方案中创建了一个控制台应用程序,并向 Service1 添加了 Web 服务引用。在 Visual Studio 工具中,我可以查看并使用服务中存在的两种方法,但是当我运行代码时,出现以下异常。

InvalidOperationException 无法 找到默认端点元素 参考合同 'ServiceReference1.IService1' 在 ServiceModel 客户端配置 部分。这可能是因为没有 已找到您的配置文件 应用程序,或者因为没有端点 与该合同匹配的元素可以 在客户端元素中找到。

在发布我的代码之前(我确信读者已经厌倦了阅读我的挣扎),我确实想提一下,我已经能够在同一解决方案中完美地运行 WCF 服务库和控制台应用程序。解释 WCF、WCF 配置以及使用 MVC 的资源似乎很少。我读过几篇文章,要么它们已经过时,要么太简单,几乎毫无用处(例如,单击按钮接收名为“Service1”的 Web 服务)。

总结一下;为什么我无法访问自动生成的 WSDL?如何成功连接我的客户端并使用 Web 服务?现在是最好的部分;代码。

Global.asax

    //Services section
    routes.Add(new ServiceRoute("services/service1", new WebServiceHostFactory(), typeof(Service1)));

Web.Config

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
      <standardEndpoints>
        <webHttpEndpoint>
          <standardEndpoint name="DefaultEndpoint" helpEnabled="true" automaticFormatSelectionEnabled="true" />
        </webHttpEndpoint>
        <mexEndpoint />
    </standardEndpoints>
    <services>
      <service name="Project.Services.Service1" behaviorConfiguration="MetadataBehavior">
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint endpointConfiguration="DefaultEndpoint" kind="webHttpEndpoint" binding="webHttpBinding" contract="Project.Services.IService1" />
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MetadataBehavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="false" /> <!-- httpGetEnabled="true" does not solve the problem either -->
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True"  />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

IService1

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [WebInvoke(Method = "GET")]
    string GetData(int value);

    [OperationContract]
    CompositeType GetDataUsingDataContract(CompositeType composite);

    // TODO: Add your service operations here
}

Service1

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{

    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }

    public CompositeType GetDataUsingDataContract(CompositeType composite)
    {
        if (composite == null)
        {
            throw new ArgumentNullException("composite");
        }
        if (composite.BoolValue)
        {
            composite.StringValue += "Suffix";
        }
        return composite;
    }
}

客户端程序

class Program
{
    static void Main(string[] args) {
        Service1Client client = new Service1Client();
        client.GetData(2);
    }
}

I’m trying to run a very basic web service on the same IIS7 website that runs a MVC2 application. This is presenting a couple of different issues, and I believe it has to do with my system.serviceModel, but obviously I don’t know for sure (or I would fix it).
On the server side I can run my service just fine, the help operation works like a charm. I can execute the default WCF operation GetData and supply a value through the FireFox address bar.

http://localhost/services/service1/getdata?value=3 (example)

The first problem I’m having is that when I navigate to the base service URI it will display the message below. While this isn’t the end of the world because I can still execute code by manipulating the address; I do expect something else to be displayed. I expect the standard new web service message explaining that by appending “?wsdl” to the address you will receive the auto generated WSDL. I cannot access my auto generated WSDL.

“Endpoint not found. Please see the
service help page for constructing
valid requests to the service.”

Problem number two is in regard to client applications connecting to my web service. I created a console application in separate Visual Studio solution and added a web service reference to Service1. In the Visual Studio tool I can see and use the two methods that exist in my service, but when I run the code I get the following exception.

InvalidOperationException Could not
find default endpoint element that
references contract
'ServiceReference1.IService1' in the
ServiceModel client configuration
section. This might be because no
configuration file was found for your
application, or because no endpoint
element matching this contract could
be found in the client element.

Before I post my code (I’m sure readers are tired of reading about my struggles) I do want to mention that I’ve been able to run a WCF Service Library and Console application in the same solution flawlessly. There seems to be very few resources explaining WCF, WCF configuration, and working with MVC. I’ve read through several articles and either they were out-of-date or they were so simplistic they were nearly useless (e.g. click button receive web service named “Service1”).

To summarize; why am I not able to access the auto generated WSDL and how can I successfully connect my client and use the web service? Now the best part; the code.

Global.asax

    //Services section
    routes.Add(new ServiceRoute("services/service1", new WebServiceHostFactory(), typeof(Service1)));

Web.Config

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
      <standardEndpoints>
        <webHttpEndpoint>
          <standardEndpoint name="DefaultEndpoint" helpEnabled="true" automaticFormatSelectionEnabled="true" />
        </webHttpEndpoint>
        <mexEndpoint />
    </standardEndpoints>
    <services>
      <service name="Project.Services.Service1" behaviorConfiguration="MetadataBehavior">
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint endpointConfiguration="DefaultEndpoint" kind="webHttpEndpoint" binding="webHttpBinding" contract="Project.Services.IService1" />
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MetadataBehavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="false" /> <!-- httpGetEnabled="true" does not solve the problem either -->
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True"  />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

IService1

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [WebInvoke(Method = "GET")]
    string GetData(int value);

    [OperationContract]
    CompositeType GetDataUsingDataContract(CompositeType composite);

    // TODO: Add your service operations here
}

Service1

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{

    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }

    public CompositeType GetDataUsingDataContract(CompositeType composite)
    {
        if (composite == null)
        {
            throw new ArgumentNullException("composite");
        }
        if (composite.BoolValue)
        {
            composite.StringValue += "Suffix";
        }
        return composite;
    }
}

Client Program

class Program
{
    static void Main(string[] args) {
        Service1Client client = new Service1Client();
        client.GetData(2);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘿看小鸭子会跑 2024-11-11 20:04:08

感谢您的帮助!问题出在我的 Global.asax.cs 内部。

原始:

routes.Add(new ServiceRoute("services/service1", new WebServiceHostFactory(), typeof(Service1)));

新:

routes.Add(new ServiceRoute("services/service1", new ServiceHostFactory(), typeof(Service1)));

区别在于将主机工厂从“WebServiceHostFactory”更改为“ServiceHostFactory”。

关于客户端连接的问题的第二部分是因为未生成配置设置。我必须为每个客户手动输入它们。哎呀!

为了避免手动输入客户端配置,我必须更改我的端点

原始

<endpoint endpointConfiguration="DefaultEndpoint" kind="webHttpEndpoint" binding="webHttpBinding" contract="Project.Services.IService1" /> 

<endpoint binding="wsHttpBinding" contract="Project.Services.IService1" />

进行此更改后,服务和客户端可以完美运行。

Thanks for the help! The problem was inside of my Global.asax.cs.

Original:

routes.Add(new ServiceRoute("services/service1", new WebServiceHostFactory(), typeof(Service1)));

New:

routes.Add(new ServiceRoute("services/service1", new ServiceHostFactory(), typeof(Service1)));

The difference was chaing the host factory from "WebServiceHostFactory" to "ServiceHostFactory".

The second part of my question regarding client connections is because configuration settings are not being generated. I have to manually type them for each client. Yikes!

To avoid manually typing client configuration I had to change my endpoint

Original

<endpoint endpointConfiguration="DefaultEndpoint" kind="webHttpEndpoint" binding="webHttpBinding" contract="Project.Services.IService1" /> 

New

<endpoint binding="wsHttpBinding" contract="Project.Services.IService1" />

After making this change the service and client are working flawlessly.

内心旳酸楚 2024-11-11 20:04:08

快速回答您的问题之一:

总结一下;为什么我不能
访问自动生成的 WSDL

<serviceMetadata httpGetEnabled="false" />

...需要

<serviceMetadata httpGetEnabled="true" />

...以便能够通过 http 检索 WSDL。 您必须告诉 WCF 生成服务元数据,并且您已经告诉它不。

A quick answer to one of your questions:

To summarize; why am I not able to
access the auto generated WSDL

<serviceMetadata httpGetEnabled="false" />

...needs to be

<serviceMetadata httpGetEnabled="true" />

...in order to be able to retrieve the WSDL over http. You have to tell WCF to generate service metadata, and you've told it not to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文