Fileless Restful WCF 在本地 IIS7 中托管时无法正常工作,但可以在本地运行

Posted

技术标签:

【中文标题】Fileless Restful WCF 在本地 IIS7 中托管时无法正常工作,但可以在本地运行【英文标题】:Fileless Restful WCF not working when hosted in local IIS7 but works run locally 【发布时间】:2017-08-28 12:30:42 【问题描述】:

我有一个安静的 .svc-less、无文件服务,它返回 JSon 数据。如果它在本地运行它工作正常,但是当我在本地 IIS7 中托管时,我得到错误

请求错误 服务器在处理请求时遇到错误。有关详细信息,请参阅服务器日志。

这是 IIS 中 Web 主机应用程序的路径。

localhost:8080/AdventureWorksHost/EmployeeService/Employees/GetEmployees

但是当我在我的视觉工作室中运行它时效果很好

localhost:50182/employeeService/Employees/Getemployees

其中 AdventureWorksHost 是 IIS 中默认网站下托管的 ApplicationName。 EmployeeService 是我在 global.asax.cs 中添加的服务的名称,在 webconfig 文件中有标准端点

            RouteTable.Routes.Add(new ServiceRoute("EmployeeService", new WebServiceHostFactory(), typeof(Services.EmployeeService.EmployeeService)));

我在 *** 和其他网站上检查了几个类似问题的建议,但没有一个解决方案适合我。

1)我在 IIS7 中为默认网站(我的项目托管在其下)分配了默认端口号 8080,并确保此端口号未被防火墙或我计算机中的任何防病毒应用程序阻止。 2)我检查 WCF HTTP 和 NON-HTTP 激活,Windows 功能中所有 .Net Framework 的 WCF 服务

Windows features

3)我已为我的应用程序的 WebConfig 添加了 IIS_IUSRS 权限

4)我在 cmd 提示符下运行:aspnet_regiis.exe -iru C:\Windows\Microsoft.NET\Framework\v4.0.30319

5)我从“%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation”目录运行ServiceModelReg.exe -i来注册脚本映射

4) 和 5) 我用 forums.asp.net/t/1807824.aspx?WCF+Service+works+locally+but+returns+404+on+remote+server

6) 根据 ***.com/questions/4793127/404-when-running-net-4-wcf-service-on-iis-no-svc-file 在下面添加

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

我已经尝试了互联网上建议的所有解决方案。在我的本地 IIS7 上没有任何效果

            <?xml version="1.0" encoding="utf-8"?>
        <!--
          For more information on how to configure your ASP.NET application, please visit
          http://go.microsoft.com/fwlink/?LinkId=169433
          -->
        <configuration>
           <configSections>
            <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
            <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
          </configSections>

          <system.diagnostics>  
              <sources>  
                    <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">  
                    <listeners>  
                       <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Users\Julian Luwang\Documents\Visual Studio 2013\Projects\AdventureWorksEntityFramework\AdventureWorksHost\Log\Traces.svclog" />  
                    </listeners>  
                 </source>  
              </sources>  
           </system.diagnostics>  

          <system.web>

            <httpRuntime executionTimeout="1800000000" />
            <compilation debug="true" targetFramework="4.5" />
                <customErrors mode="On">
                </customErrors>
          </system.web>
          <system.serviceModel>
               <standardEndpoints>
              <webHttpEndpoint>
                  <standardEndpoint name="test" helpEnabled="true" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647">
                  <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" />
                      <security mode="None"></security>
               </standardEndpoint>
                </webHttpEndpoint>
            </standardEndpoints>
           <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
        </serviceHostingEnvironment> 
           <behaviors>
              <serviceBehaviors>
                <!--<behavior name="Secured">
                  <serviceMetadata httpsGetEnabled="true" />
                  <serviceDebug includeExceptionDetailInFaults="true" />
                  <dataContractSerializer maxItemsInObjectGraph="2147483647" />
                </behavior>-->
                <behavior>
                <serviceDebug httpHelpPageEnabled="true" httpsHelpPageEnabled="false" />
            </behavior>

                <behavior name="Normal">
                  <serviceMetadata httpGetEnabled="true" />
                  <serviceDebug includeExceptionDetailInFaults="true" />
                  <dataContractSerializer maxItemsInObjectGraph="2147483647" />
                </behavior>
                     </serviceBehaviors>
            </behaviors>
            <bindings>
                 <webHttpBinding>
                 <!-- Binding (non-secured) -->
                <binding name="Normal" transferMode="Streamed" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
                  <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" />
                  <security mode="None" />
                </binding>
              </webHttpBinding>
           </bindings>

             <!--protocol mapping added-->

               <protocolMapping>
              <add scheme="http" binding="webHttpBinding" bindingConfiguration="Normal" />

            </protocolMapping>

              </system.serviceModel>
          <connectionStrings>
            <add name="AdventureWorks2012Entities" connectionString="metadata=res://*/AdventureWorksEDM.csdl|res://*/AdventureWorksEDM.ssdl|res://*/AdventureWorksEDM.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=JULIAN\SQLEXPRESS;initial catalog=AdventureWorks2012;integrated security=True;trusted_connection=yes;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
          </connectionStrings>
          <entityFramework>
            <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
            <providers>
              <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
            </providers>
          </entityFramework>
          <system.webServer>
            <validation validateIntegratedModeConfiguration="false" />
                <modules runAllManagedModulesForAllRequests="true">

                <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
             </modules> 
           <handlers>
            <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" />

            </handlers>
                 <directoryBrowse enabled="true" />
                <defaultDocument enabled="false">
                    <files>
                        <add value="EmployeeService" />
                    </files>
                </defaultDocument>
          </system.webServer>
        </configuration>

服务

            namespace AdventureWorksHost.Services.EmployeeService
        

            [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
            public class EmployeeService : IEmployeeService
            

                [WebGet(UriTemplate = "Employees/GetEmployees", ResponseFormat = WebMessageFormat.Json)]
                public List<EmployeeItem> GetEmployee()
                
                      try
                    
                        List<EmployeeItem> tReturn = new List<EmployeeItem>();
                       using (AdventureWorks2012Entities tClienEntities = new AdventureWorks2012Entities())
                        
                             var tEmployees = (from es in tClienEntities.Employees
                                             orderby es.JobTitle
                                              select new
                                              
                                                  es.rowguid,
                                                  es.BirthDate,
                                                  es.BusinessEntityID,
                                                  es.JobTitle,
                                                  es.NationalIDNumber,
                                                  es.MaritalStatus,
                                                  es.LoginID,
                                              ).ToList();


                            foreach (var tEmployee in tEmployees)
                            
                                EmployeeItem tEmployeeItem = new EmployeeItem();
                                tEmployeeItem.rowguid = tEmployee.rowguid;
                                tEmployeeItem.BusinessEntityId = tEmployee.BusinessEntityID;
                                tEmployeeItem.JobTitle = tEmployee.JobTitle;
                                tEmployeeItem.MaritalStatus = tEmployee.MaritalStatus.ToString();
                                tEmployeeItem.NationalIDNumber = Int32.Parse(tEmployee.NationalIDNumber.ToString());
                                tEmployeeItem.BirthDate = tEmployee.BirthDate;
                                tEmployeeItem.LoginID = tEmployee.LoginID.ToString();
                                List<Person> Persons = new List<Person>();

                                foreach (var tPersons in (from esp in tClienEntities.People
                                                          where esp.BusinessEntityID == tEmployeeItem.BusinessEntityId
                                                          orderby esp.FirstName
                                                          select new
                                                          
                                                              esp.rowguid,
                                                              esp.FirstName,
                                                              esp.MiddleName,
                                                              esp.LastName,
                                                              esp.PersonType,
                                                              esp.Demographics

                                                          ))
                                

                                   Persons.Add(new Person()
                                     
                                        rowguid = tPersons.rowguid,
                                        FirstName = tPersons.FirstName,
                                        MiddleName = tPersons.MiddleName,
                                        LastName = tPersons.LastName,
                                        PersonType = tPersons.PersonType,
                                        Demographics = tPersons.Demographics
                                    );
                                 
                                tEmployeeItem.Persons = Persons;
                                tReturn.Add(tEmployeeItem);
                            
                        

                        return tReturn;

                     

                    catch (FaultException ex)
                    
                        throw (ex);
                    

                 
            

        

我的应用 AdventureWorkHost 在我的本地 IIS7 中看起来像这样

Application in IIS7

【问题讨论】:

是不是因为数据库在本地SQL Server?我在某处读到,如果我的 IIS7 的 root 帐户与我用于 sql 服务器的管理员帐户相同(没有密码),那么不应该有任何数据库问题。 【参考方案1】:

已解决: 我检查了 SQL Server Management Studio 的服务器日志中的错误。错误是

消息 用户“NT AUTHORITY\NETWORK SERVICE”登录失败。原因:无法打开明确指定的数据库“AdventureWorks2012”。 [客户:]

所以,我尝试了一些方法。

1) 在安全访问文件夹 C:\inetpub\wwwroot 中添加 NT AUTHORITY\NETWORK SERVICE

2)在本地 IIS 中,将托管应用程序使用的应用程序池的标识从 applicationPoolIdentity 更改为网络服务

3)在SQL MGMT STUDIO 的安全中添加新登录NT AUTHORITY\NETWORK SERVICE,指定新登录的属性。 4)将默认数据库设置为您的数据库 5) 为新登录选择数据库和角色成员身份为 db_datareader、db_datawriter 和 db_owner 和 public 6)设置服务器角色public和sysadmin 7)选择数据库->安全->用户(新创建的登录名)。打开它 8) 将拥有的模式设置为 db_datareader、db_datawriter 和 db_owner 9) 将角色成员设置为 db_datareader、db_datawriter 和 db_owner

重启本地sql server,然后运行。

【讨论】:

以上是关于Fileless Restful WCF 在本地 IIS7 中托管时无法正常工作,但可以在本地运行的主要内容,如果未能解决你的问题,请参考以下文章

Restful WCF 服务和 LINQ

Restful风格wcf调用4——权限认证

Restful风格wcf调用3——Stream

WCF 改成 restful api

Restful风格wcf调用

Restful风格wcf调用