wcf 4.0 中Rest service 在iis host中不用.svc文件的配置

本文介绍了如何在WCF 4.0中创建一个RESTful服务,无需使用.svc文件。通过在ASP.NET Web应用程序项目中添加一个普通的C#类,并使用WebGet/WebInvoke属性进行装饰,可以实现CRUD操作。通过System.Web.Routing基础设施和WebServiceHostFactory,可以在IIS中托管此类服务。此外,文章提到了在WCF中设置RESTful路由比在MVC中更简单,因为可以直接在方法上应用UriTemplate。通过配置,还可以获得帮助页面和自动格式选择等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Building a RESTful WCF service in this way is quite easy and you don’t need rely on any item templates.  Just start with a blank asp.net web application project in Visual Studio. The web.config file is virtually empty:

   1:  
<
configuration
>
   2:  
    <
system.web
>
   3:  
        <
compilation
 debug
="true"
 targetFramework
="4.0"
 />
   4:  
    </
system.web
>
   5:  
</
configuration
>

Next just add a regular C# class - for this example, I call mine PersonService and it will have basic CRUD operations. Typically we create interfaces in WCF to define our ServiceContract and operations like this:

   1:  
[ServiceContract]
   2:  
interface
 IPersonService
   3:  
{
   4:  
    [OperationContract]
   5:  
    Person GetPerson(string
 id);
   6:  
 
   7:  
    [OperationContract]
   8:  
    Person InsertPerson(Person person);
   9:  
 
  10:  
    [OperationContract]
  11:  
    Person UpdatePerson(string
 id, Person person);
  12:  
 
  13:  
    [OperationContract]
  14:  
    void
 DeletePerson(string
 id);
  15:  
}

Keep in mind, this step is *not* required. You *could* decorate your service class directly with these attributes and not even have the interface at all. However, in this case, it’s a nice convenience to encapsulate all the WCF attributes on the interface rather than your implementation class. The implementation of our PersonService class looks like this (I’ve removed the code that access the data store for brevity):

   1:  
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
   2:  
public
 class
 PersonService : IPersonService
   3:  
{
   4:  
    [WebGet(UriTemplate = "Person({id})"
)]
   5:  
    public
 Person GetPerson(string
 id)
   6:  
    {
   7:  
    }
   8:  
 
   9:  
    [WebInvoke(UriTemplate = "Person"
, Method = "POST"
)]
  10:  
    public
 Person InsertPerson(Person person)
  11:  
    {
  12:  
    }
  13:  
 
  14:  
    [WebInvoke(UriTemplate = "Person({id})"
, Method = "PUT"
)]
  15:  
    public
 Person UpdatePerson(string
 id, Person person)
  16:  
    {
  17:  
    }
  18:  
 
  19:  
    [WebInvoke(UriTemplate = "Person({id})"
, Method = "DELETE"
)]
  20:  
    public
 void
 DeletePerson(string
 id)
  21:  
    {
  22:  
    }
  23:  
}

This is just a normal C# class that implement an interface. It’s also decorated with the typical WebGet/WebInvoke attributes (in the System.ServiceModel.Web namespace) that we use for RESTful services. Also notice that 3 of the 4 methods have the same UriTemplate but they are differentiated by the HTTP method (i.e., GET/PUT/DELETE). Also notice the AspNetCompatibilityRequirements attribute – this is needed for RESTful services that are processed in the ASP.NET pipeline as described here . You also have to add this to the config file (I know, I know – I said “no config” but I meant “no ugly WCF endpoint config”!):

   1:  
<
system.serviceModel
>
   2:  
  <
serviceHostingEnvironment
 aspNetCompatibilityEnabled
="true"
/>
   3:  
</
system.serviceModel
>

So how do we take this regular C# class and make it into a service without an *.svc file?  The System.Web.Routing infrastructure has now been incorporated into WCF 4 to make this possible.  Just add the line of code (line #5) to your global.asax:

   1:  
public
 class
 Global : System.Web.HttpApplication
   2:  
{
   3:  
    protected
 void
 Application_Start(object
 sender, EventArgs e)
   4:  
    {
   5:  
        RouteTable.Routes.Add(new
 ServiceRoute(""
, new
 WebServiceHostFactory(), typeof
(PersonService)));
   6:  
    }
   7:  
}

The WebServiceHostFactory makes RESTful services possible in WCF. The first parameter of my ServiceRoute constructor is an empty string which means that my URI of my service will hang right off of the root – this get combined with the UriTemplate defined in the WebGet/WebInvoke attributes.  So to get a person from my service, a URI would look like this:  http://mydomain.com/Person(21 ).  If I had specified “foo” instead of an empty string in the first parameters of the ServiceRoute constructor, then my URI would look like this:  http://mydomain.cmo/foo/Person(21 ).

That’s it!  You now have a fully functioning RESTful WCF service that you can fully test with Fidder for all HTTP verbs.

One interesting aspect to all this is that you can do all this in MVC as well. In fact, I typically do use MVC to return JSON to views for AJAX calls in my MVC apps. However, if you were building stand-alone services for this, would MVC be easier than the example of above? Keep in mind, we could simplify the example above even further by eliminating the IPersonService interface all together. I daresay that setting up RESTful routes like the ones shown above is easier with WCF than MVC (this, coming from an “MVC guy”) because we can apply the UriTemplates directly to the methods. To accomplish the same in MVC, you have to create custom route constraints to avoid the name of the C# methods from showing up in the URL (and honoring the REST HTTP verbs).  If you are going to do this, I really like the approach shown here . It’s a cool approach, but it’s *more* work than just doing it with RESTful WCF – no svc file and no configuration.

In fact, using the WCF infrastructure gets you even more features for free.  For example, if we add 1 more line of configuration (check out line #5 below) we get a help page and automatic format selection for free! Now our entire configuration just looks like this (and still no WCF endpoint configuration needed):

   1:  
<
system.serviceModel
>
   2:  
  <
serviceHostingEnvironment
 aspNetCompatibilityEnabled
="true"
/>
   3:  
  <
standardEndpoints
>
   4:  
    <
webHttpEndpoint
>
   5:  
      <
standardEndpoint
 name
=""
 helpEnabled
="true"
 automaticFormatSelectionEnabled
="true"
/>
   6:  
    </
webHttpEndpoint
>
   7:  
  </
standardEndpoints
>
   8:  
</
system.serviceModel
>

Notice all we had to do to get the help page was the request “/help”:

wcf help page

The automatic format selection in WCF will honor the Accept header and/or the Content-type header and return XML, JSON, etc. to the caller based on the value specified in the header. Again, that takes custom code in MVC which you get for free in WCF.

 

我按这个配置没有成功,后来在web.config里加上下面这个配置节就好了。

<system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值