简体   繁体   English

如何为ASP.NET Web服务配置代理类以灵活地部署到生产环境

[英]How to configure a proxy class for an ASP.NET web service for flexible deployment to production

I inherited a web app at the Visual Studio 2003 level that placed all of its code for accessing SQL server in an ASMX web service. 我在Visual Studio 2003级别继承了一个Web应用程序,该应用程序将用于访问SQL Server的所有代码都放在ASMX Web服务中。 This web project had a web reference to the web service. 该Web项目具有对该Web服务的Web参考。 I needed to bring the whole thing under source control, upgrade it to Vstudio 2008 and make a bunch of fixes and enhancements. 我需要将整个内容置于源代码控制之下,将其升级到Vstudio 2008并进行大量修复和增强。

In doing this, I came across a neat article from Code Magazine emphasizing the advantages of "assembly separation" . 为此,我看到了Code Magazine的一篇整洁的文章,强调了“汇编分离”的优点 It was written for WCF but it "inspired me" to: 它是为WCF编写的,但它“启发了我”以:

  • remove the web reference from my main ASP.NET web application project 从我的主要ASP.NET Web应用程序项目中删除Web参考
  • add a new project as a class library which I called ProxyZipeeeService 添加一个新项目作为类库,我称之为ProxyZipeeeService
  • add a web reference in the ProxyZipeeeService project to point at the ZipeeeService project 在ProxyZipeeeService项目中添加Web引用以指向ZipeeeService项目
  • add a reference in the main web app project to ProxyZipeeeService.DLL produced by building the project of the same name. 在主Web应用程序项目中添加对通过构建同名项目而生成的ProxyZipeeeService.DLL引用

The things work and I guess there are some [performance?] advantages to separating things out like this but having described my structure, I need to get to my question/problem : 一切正常,我想将这些东西分离出来虽然有一些[性能?]优势,但是已经描述了我的结构, 我需要解决我的问题/问题

I run into lots of configuration problems when I deploy this into production that require me to make changes that are quite "awkward" and prone to me screwing things up. 当我将其部署到生产环境中时,我遇到了许多配置问题,这些问题要求我进行相当“笨拙”的更改,并容易使事情搞砸。 Here is my guess about what needs changing but I've searched extensively and cannot understand how: 这是我对需要更改的内容的猜测,但是我进行了广泛搜索,无法理解如何做:

The ProxyZipeeeService project with the web reference in it produces files as follows: 带有Web参考的ProxyZipeeeService项目产生的文件如下:

  • Reference.map.vb, ProxyZipeeeService.disco, ProxyZipeeeService.wsdl and app.config Reference.map.vb,ProxyZipeeeService.disco,ProxyZipeeeService.wsdl和app.config
  • on my development PC, the app.config file produced settings for the URL of localhost (as it should for my PC). 在我的开发PC上, app.config文件为localhost的URL生成了设置(对我的PC来说应该如此)。 Please view this XML entry at: http://pastebin.com/JtQCxT73 请在以下位置查看此XML条目: http : //pastebin.com/JtQCxT73
  • When I publish the web application project to the production web server, the URL for the webservice is "buried" inside the DLL for ProxyZipeeeService (which at this time is in the bin folder of the web app because it is referenced). 当我将Web应用程序项目发布到生产Web服务器时,Web服务的URL被“掩埋”在ProxyZipeeeService的DLL内(由于已被引用,此地址当前在Web应用程序的bin文件夹中)。

  • Because the prod web server is configured to recognize "host header files" [another question someday], the URL with localhost fails with a HTTP 400 Bad Request . 因为prod Web服务器被配置为识别“主机头文件” [某天另一个问题],所以localhost的URL失败,并显示HTTP 400 Bad Request The host header config requires anything related to this default website to use the domain http://www.zipeee.com/ZipeeeWebService/Zipeee.asmx 主机标头配置需要任何与此默认网站相关的内容,才能使用域http://www.zipeee.com/ZipeeeWebService/Zipeee.asmx

  • So to fix this, I have been having to "dismantle" my development project for ProxyZipeeeService - completely deleting the web reference, adding it back but this time make the dialog point to the WS on the production server (instead of letting it find the WS in "this solution" because that results in the problematic "localhost" setting). 因此,要解决此问题,我不得不“撤消”我的ProxyZipeeeService开发项目-完全删除Web参考,将其添加回去,但这一次使对话框指向生产服务器上的WS(而不是让它找到WS)在“此解决方案”中,因为这会导致有问题的“本地主机”设置)。

  • Eventually I am able to push out to the prod server a web project referencing the proxy dll that won't run into this host header issue and it works without throwing the HTTP 400 error. 最终,我能够将引用代理dll的Web项目推送到产品服务器,该代理dll将不会遇到此主机头问题,并且它可以正常工作而不会引发HTTP 400错误。

But there has to be a better way! 但是必须有更好的方法!

In short, the critical proxy dll cannot be configured with regard to the URL it should use the way I'm set up now. 简而言之,关键代理dll无法使用应该使用我现在设置的方式配置的URL。 I've tried putting the applicationSettings entry from the app.config into the web.config of my web application project. 我尝试将app.config中applicationSettings条目放入Web应用程序项目的web.config中。 I've also tried putting a variation on this into the appSettings section. 我也曾尝试在appSettings部分中对此进行修改。 Both of these attempts fail. 这些尝试均失败。

I hope I have been clear and not been too verbose. 我希望我很清楚,不要太冗长。 Please do not suggest major surgery like WCF because I can't bite off on that now for this project. 请不要建议像WCF这样的大手术,因为我现在不能为这个项目而努力。 Thank you for reading and thanks in advance for your help. 感谢您的阅读,并预先感谢您的帮助。

EDIT UPDATE: Changing URL in web app's WEB.CONFIG is not detected! 编辑更新:未检测到Web应用程序的WEB.CONFIG中的URL更改! Problem remains. 问题仍然存在。 Here is what I did: 这是我所做的:

  • Followed exactly what you said to do, lifting the settings from the app.config of the proxy to the web.config of the web app (establishing a new configuration section group that points to my setting from app.config. 完全按照您说的去做,将设置从代理的app.config提升到Web应用程序的web.config(建立一个新的配置部分组,该组指向从app.config指向我的设置。
  • The value in the proxy and now also in web.config reads as: http://localhost/ZipeeeWebService/Zipeee.asmx which is fine for testing on my dev PC 代理中的值以及现在在web.config中的值都读取为: http://localhost/ZipeeeWebService/Zipeee.asmx ,可以在我的开发PC上进行测试
  • Before deploying all this to the production server, I thought I should test a bit. 在将所有这些部署到生产服务器之前,我认为应该进行一些测试。 My first test was with the settings above and I set a breakpoint in the web service project and verified that the proxy had indeed come to localhost as the web.config entry intended and as expected. 我的第一个测试是使用上面的设置,我在Web服务项目中设置了一个断点,并验证了代理确实作为预期的web.config条目进入了本地主机。
    • Next (test case 2) I changed the web.config entry from localhost to www.zipeee.com which is where the production webservice the public facing web app uses. 接下来(测试案例2),我将web.config条目从localhost更改为www.zipeee.com,这是面向公众的Web应用程序使用的生产Web服务的位置。
    • I left the same breakpoint in the first web service call in place (expecting that it would not be hit because the intention was to use the URL specified in the web.config) 我在第一个Web服务调用中保留了相同的断点(希望不会被击中,因为其意图是使用web.config中指定的URL)
    • To my surprise, the breakpoint was hit and when I examined the URL via the Immediate Window, it showed it to be localhost (should have been to www.zipeee.com as desired in web.config). 令我惊讶的是,断点被击中,当我通过“即时窗口”检查URL时,它表明它是本地主机(应按web.config中的说明访问www.zipeee.com)。

Perhaps I have misunderstood what this approach should allow? 也许我误解了这种方法应该允许什么? Is there something I am missing? 我有什么想念的吗? I did NOT rebuild the Proxy DLL (that remains with localhost) which I thought was the whole intent (ie to be able to control the URL in a sort of "late-binding" way via changes to the web.config of the web app). 没有重建代理 DLL(保留在localhost中),我认为这是整个意图(即能够通过对Web应用程序的web.config进行更改以某种“后期绑定”方式控制URL) )。

I remain stumped. 我仍然很沮丧。 Hopefully, you could help me a bit more...Thanks. 希望您能为我提供更多帮助...谢谢。

EDIT UPDATE: 12 Oct 编辑更新:10月12日

Thanks - I read your notes but I'm still confused. 谢谢-我读了你的笔记,但我仍然很困惑。 The ProxyZipeeeService project code is all generated from the web reference. ProxyZipeeeService项目代码都是从Web参考生成的。 Here is a snippet from the reference.vb file ( are you suggesting I modify this generated code? ): 这是reference.vb文件的摘录( 您是否建议我修改此生成的代码? ):

Public Sub New()
        MyBase.New
        Me.Url = Global.ProxyZipeeeService.My.MySettings.Default.ProxyZipeeeService_WSZipeee_Zipeee
        If (Me.IsLocalFileSystemWebService(Me.Url) = true) Then
            Me.UseDefaultCredentials = true
            Me.useDefaultCredentialsSetExplicitly = false
        Else
            Me.useDefaultCredentialsSetExplicitly = true
        End If
    End Sub

    Public Shadows Property Url() As String
        Get
            Return MyBase.Url
        End Get
        Set
            If (((Me.IsLocalFileSystemWebService(MyBase.Url) = true)  _
                        AndAlso (Me.useDefaultCredentialsSetExplicitly = false))  _
                        AndAlso (Me.IsLocalFileSystemWebService(value) = false)) Then
                MyBase.UseDefaultCredentials = false
            End If
            MyBase.Url = value
        End Set
    End Property

By the way, could you comment on whether the whole idea of a separate assembly (proxy) for a web service is even a worthwhile thing. 顺便说一句,您能否评论一下Web服务的单独程序集(代理)的整个想法是否值得呢? There may be some performance benefits (?) but these configuration issues are giving me fits. 可能会有一些性能上的好处(?),但这些配置问题使我很合适。

EDIT-UPDATE 12 Oct - a bit later 编辑更新10月12日 -稍后

After the last posting of the code from the generated file reference.vb, I spotted the problem! 从生成的文件reference.vb中最后一次发布代码后,我发现了问题! The declarations you had me place in the web app's web.config file were named: 您让我放置在Web应用程序的web.config文件中的声明名为:

section name="ProxyZipeeeService.Properties.MySettings"

while the reference.vb file refered to the setting as: 而reference.vb文件将设置引用为:

Me.Url = Global.ProxyZipeeeService.My.MySettings.Default.ProxyZipeeeService_WSZipeee_Zipeee

Changing the web config name to read as section name="ProxyZipeeeService. My .MySettings" has enabled the proxy to find the setting in the web app's web.config and I'm now able to "toggle" the web service URL through configuration parameters. 更改Web配置名称改为段名=“ProxyZipeeeService。 .MySettings”启用了代理发现在Web应用程序的web.config中的设置,现在我能够“开关”的Web服务,通过配置参数网址。

Thank you so much for your help. 非常感谢你的帮助。 I am closing this now. 我现在关闭这个。

ps Do the "professionals" use Proxy classes as wrappers for web services like this? ps“专业人员”是否将代理类用作此类Web服务的包装器?

You should place the configuration in the web.config of you web app, making a section group that references back to your ProxyZipeeeService project. 您应该将配置放置在Web应用程序的web.config中,并创建一个引用回ProxyZipeeeService项目的部分组。 To do so, copy both the sectiongroup and the actual applicationSettings from your ProxyZipeeeService to your web application: 为此,将部分组和实际的applicationSettings从ProxyZipeeeService复制到Web应用程序:

  <configSections>
     <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <section name="ProxyZipeeeService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
     </sectionGroup>
  </configSections>
  <!--other stuff-->
  <applicationSettings>
     <ProxyZipeeeService.Properties.Settings>
        <!--your original appSettings-->
     </ProxyZipeeeService.Properties.Settings>
  </applicationSettings>

Then you can change the settings after your application has been deployed. 然后,可以在部署应用程序后更改设置。

If all else fails, you could also make your ProxyZipeeeService library expose the URL as a public property, so it can be changed at runtime by the web application calling it. 如果所有其他方法均失败,则还可以使ProxyZipeeeService库将URL公开为公共属性,因此可以在运行时通过Web应用程序对其进行更改。

I hope this was helpful. 我希望这可以帮到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM