在.NET 3.5到.NET 4.0升级之后,ASP.NET Generic Handler不会被调用

时间:2013-07-22 02:38:41

标签: asp.net extjs proxy generic-handler ext-direct

这个旧标题描述了可见问题,但新标题更好地描述了根本原因问题。我仍然不确定为什么ASHX没有被调用,所以我仍在寻找答案。我现在通过硬编码API描述符(Ext.app.REMOTING_API变量)来解决方法。我从运行.NET 3.5的原始代码中获取了DirectProxy“provider”返回变量的JSON对象(Ext.app.REMOTING_API变量)。我只是使用在线JavaScript美化器使它看起来很漂亮(所以你可以阅读它,而不是在一行上)。

旧标题:ExtJS 3 Ext.Direct proxy error: Uncaught TypeError: Cannot read property 'events' of undefined

我刚刚将extdirect4dotnet项目从.NET 3.5升级到.NET 4.0。该项目和示例项目可以在https://code.google.com/p/extdirect4dotnet/找到。当我这样做时,我不得不在更改项目版本时临时复制Web.Config文件。我修复了两个覆盖方法的参数列表,这些方法是由于在http://json.codeplex.com/SourceControl/latest#readme.txt找到的JSON.NET中继承了一个类。我还修复了两个项目中DLL引用的方式。然后我在Web.Config中将所有出现的“3.5”替换为“4.0”。

不幸的是,这个项目使用的是ExtJs 3.0.0,而不是ExtJs 4.2。*,这是我用这个.NET服务器端堆栈(extdirect4dotnet)实现Ext.Direct代理的框架版本。所以它仍然使用一些旧的语法。下面我试图找出如何在.NET升级后修复特定错误。它仍在使用ExtJs 3.0.0。请参阅“addProvider”函数中的“查看此行”以查看其失败的行。当我从JavaScript调试它时,“提供者”是未定义的。我想在将其升级到.NET 4.0之后,它不知道如何获取提供程序Ext.app.REMOTING_API

JavaScript错误:

Uncaught TypeError: Cannot read property 'events' of undefined 

ExtJs代码:

/*!
 * Ext JS Library 3.0.0
 * Copyright(c) 2006-2009 Ext JS, LLC
 * licensing@extjs.com
 * http://www.extjs.com/license
 */

...

 * </code></pre>
 * @param {Object/Array} provider Accepts either an Array of Provider descriptions (an instance
 * or config object for a Provider) or any number of Provider descriptions as arguments.  Each
 * Provider description instructs Ext.Direct how to create client-side stub methods.
 */
addProvider : function(provider){        
    var a = arguments;
    if(a.length > 1){
        for(var i = 0, len = a.length; i < len; i++){
            this.addProvider(a[i]);
        }
        return;
    }

    // if provider has not already been instantiated
    if(!provider.events){  // <========================= see this line
        provider = new Ext.Direct.PROVIDERS[provider.type](provider);
    }
    provider.id = provider.id || Ext.id();
    this.providers[provider.id] = provider;

    provider.on('data', this.onProviderData, this);
    provider.on('exception', this.onProviderException, this);


    if(!provider.isConnected()){
        provider.connect();
    }

    return provider;
},

示例项目JavaScript代码:

Ext.Direct.addProvider(Ext.app.REMOTING_API); 

使用.NET 3.5实现的“provider”对象上的JavaScript调试器的屏幕截图(在.NET升级之前)

(在新窗口中打开以查看大图)

enter image description here

作为一种解决方法,我已经对我的js文件进行了以下操作,并对提供程序进行了硬编码(Ext.app.REMOTING_API变量)。这本质上是一个JSON对象,它是我的API描述符。当使用.NET 3.5配置示例项目时,我从下面继承的ASHX代码中捕获了变量“provider”。出于某些奇怪的原因,ASP.NET中的Generic Handler没有被调用。 Generic Handler继承的类对我来说似乎是普通的.NET 4.0 Generic Handler(ASHX)代码。我已粘贴HTML,ASHX并继承了ASHX。

Ext.onReady(function () {

    Ext.app.REMOTING_API = {
        "type": "remoting",
        "id": "1",
        "url": "../directRouter.ashx",
        "actions": {
            "CallTypes": [{
                "name": "Echo",
                "len": 1,
                "formHandler": false
            }, {
                "name": "GetTime",
                "len": 0,
                "formHandler": false
            }, {
                "name": "UploadHttpRequestParam",
                "len": 1,
                "formHandler": true
            }, {
                "name": "UploadNamedParameter",
                "len": 1,
                "formHandler": true
            }, {
                "name": "SaveMethod",
                "len": 3,
                "formHandler": false
            }, {
                "name": "SaveMethod_Form",
                "len": 1,
                "formHandler": true
            }, {
                "name": "DateSample",
                "len": 2,
                "formHandler": false
            }],
            "TreeAction": [{
                "name": "getChildNodes",
                "len": 2,
                "formHandler": false
            }],
            "CRUDSampleMethods": [{
                "name": "create",
                "len": 1,
                "formHandler": false
            }, {
                "name": "read",
                "len": 1,
                "formHandler": false
            }, {
                "name": "update",
                "len": 2,
                "formHandler": false
            }, {
                "name": "destroy",
                "len": 1,
                "formHandler": false
            }, {
                "name": "reset",
                "len": 0,
                "formHandler": false
            }]
        }
    };


    Ext.Direct.addProvider(Ext.app.REMOTING_API);
    //Ext.Direct.addProvider();

    var Employee = Ext.data.Record.create([
        { name: 'firstname' },                  // map the Record's "firstname" field to the row object's key of the same name
        {name: 'job', mapping: 'occupation'}  // map the Record's "job" field to the row object's "occupation" key
    ]);

    var reader = new Ext.data.JsonReader({
        totalProperty: 'results',
        successProperty: 'success',
        idProperty: 'id',
        root: 'data'
    }, [
            { name: 'id' },
            { name: 'email', allowBlank: false },
            { name: 'first', allowBlank: false },
            { name: 'last', allowBlank: false }
        ]
    );
    var writer = new Ext.data.JsonWriter({
        returnJson: false,
        writeAllFields: true
    });

    var store = new Ext.data.DirectStore({
        api: {
            read: CRUDSampleMethods.read,
            create: CRUDSampleMethods.create,
            update: CRUDSampleMethods.update,
            destroy: CRUDSampleMethods.destroy
        },
        reader: reader,
        baseParams: { dummy: 'blubb' },
        writer: writer,     // <-- plug a DataWriter into the store just as you would a Reader
        paramsAsHash: true,
        batchSave: false,
        batch: false,
        prettyUrls: false,
        remoteSort: true,
        listeners: {
            load: function (result) {
            },
            loadexception: function () {

            },
            scope: this
        }
    });
    //

    var myPageSize = 10;

    var userColumns = [
        { header: "ID", width: 40, sortable: true, dataIndex: 'id' },
        { header: "Email", width: 100, sortable: true, dataIndex: 'email', editor: new Ext.form.TextField({}) },
        { header: "First", width: 50, sortable: true, dataIndex: 'first', editor: new Ext.form.TextField({}) },
        { header: "Last", width: 50, sortable: true, dataIndex: 'last', editor: new Ext.form.TextField({}) }
    ];
    Ext.onReady(function () {
        Ext.QuickTips.init();

        var userForm = new App.user.Form({
            renderTo: 'user-form',
            listeners: {
                create: function (fpanel, data) {   // <-- custom "create" event defined in App.user.Form class
                    var rec = new userGrid.store.recordType(data);
                    userGrid.store.insert(0, rec);
                }
            }
        });

        // create user.Grid instance (@see UserGrid.js)
        var userGrid = new App.user.Grid({
            renderTo: 'user-grid',
            store: store,
            columns: userColumns,
            bbar: new Ext.PagingToolbar({
                store: store,       // grid and PagingToolbar using same store
                displayInfo: true,
                pageSize: myPageSize,
                prependButtons: true,
                items: [
                    'text 1'
                ]
            }),
            listeners: {
                rowclick: function (g, index, ev) {
                    var rec = g.store.getAt(index);
                    userForm.loadRecord(rec);
                },
                destroy: function () {
                    userForm.getForm().reset();
                }
            }
        });
        setTimeout(function () {
            Ext.get('loading').remove();
            Ext.fly('loading-mask').fadeOut({
                remove: true
            });
            store.load({ params: {
                start: 0,          // specify params for the first page load if using paging
                limit: myPageSize,
                foo: 'bar'
            }
            });

        }, 250);
    });

});   // onready

HTML code:

...

<link rel="stylesheet" type="text/css" href="../ext/resources/css/ext-all.css" />    
<script type="text/javascript" src="../ext/ext-base-debug.js"></script>     
<script type="text/javascript" src="../ext/ext-all-debug.js"></script>
<!-- directProxy.rfc was registred in the web.config -->
<script type="text/javascript" src="../directProxy.ashx"></script>

...

ASHX:

使用System;

using System.Collections;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using ExtDirect4DotNet;

namespace WebApplication1
{
   /// <summary>
    /// Zusammenfassungsbeschreibung für $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class directProxy : DirectProxy
    {
        public directProxy()
        {
            DirectProxy.routerUrl = "../directRouter.ashx";
        }

    }
}

在ExtDirect4DotNet中找到的继承的ASHX(在.NET 4.0升级期间代码没有改变):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Configuration;
using System.Web.Configuration;
using ExtDirect4DotNet;
using ExtDirect4DotNet.helper;

namespace ExtDirect4DotNet
{
    /// <summary>
    /// Represents the Proxy For Ext.Direct Comunication.
    /// Tha ProccessRequest Methode scanns all the available Assembly for Classes and Methods with the 
    /// Direct Attribute.
    /// </summary>
    public class DirectProxy : IHttpHandler
    {
        private static string url = "";
        public static string routerUrl {
            get { return url; }
            set { url = value; }
        }

        public static DirectProvider getDirectProviderCache(string apiNameSpace)
        {

            string routerUrl = (DirectProxy.routerUrl == "") ? ConfigurationCache.getRouterUrl() : DirectProxy.routerUrl;

            // set default namspace for the remoting API
            string apiNamespace = (apiNameSpace == null || apiNameSpace == "") ? "Ext.app.REMOTING_API" : apiNameSpace;


            DirectProviderCache cache = DirectProviderCache.GetInstance();
            DirectProvider provider;

            //After being configured, the provider should be cached.
            if (!cache.ContainsKey(apiNamespace + "/" + routerUrl))
            {
                provider = new DirectProvider(apiNamespace, routerUrl);
                provider.Configure(AppDomain.CurrentDomain.GetAssemblies());
                if (!cache.ContainsKey(apiNamespace + "/" + routerUrl))
                    cache.Add(apiNamespace + "/" + routerUrl, provider);
            }
            else
            {
                provider = cache[apiNamespace + "/" + routerUrl];
            }
            return provider;
        }

        public void ProcessRequest(HttpContext context)
        {


            // set default namspace for the remoting API
            string apiNamespace = "Ext.app.REMOTING_API";
            if (context.Request.Form["ns"] != null)
            {
                // if there is an namespace parameter, use it...
                apiNamespace = context.Request.Form["ns"].ToString();
            }
            DirectProvider provider = getDirectProviderCache(apiNamespace);

            context.Response.Write(provider.ToString());

            /*
            old code..


            // set the Response typ to javascript since the responce gets Parsed into an Script Tag
            context.Response.ContentType = "text/JavaScript";

            string rem = "{";
            rem += "url: \""+routerUrl+"\",";
            rem += "type:\"remoting\",";


            //string json = DirectProxyGenerator.generateDirectApi();
           //rem += json;
            rem += "};";

            rem = apiNamespace + ".REMOTING_API =" + rem;
            rem = "(function(){" + rem + "})();";

            context.Response.Write(rem);
           */
        }

        public bool IsReusable
        {
            get { return false; }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

在IIS 7中重现问题之后,最终解决了IIS 6和IIS 7的问题!!

HTTP处理程序适用于带有.NET 3.5和.NET 4.0的IIS 6。但是,当您将框架升级到.NET 4.0时,HTTP处理程序会在IIS 7上中断。为了修复,您必须执行4项操作。

1。)将应用程序池.NET版本从v2.0更改为v4.0

2.)将应用程序池从Integrated更改为Classic

3.)将应用程序池从64位更改为32位

4。)替换Web.Config中的XML标记。如果不这样做,并且用“4.0.0.0”替换这些行的“3.5.0.0”版本,则可能会损坏IIS并抛出此错误。

Configuration file is not well-formed XML #2

.NET版本3.5 Web.Config配置:

(注意“PublicKeyToken”属性值中的小写字母和大写字母)

  <!--<configSections>
    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
          <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        </sectionGroup>
      </sectionGroup>
    </sectionGroup>
  </configSections>-->

.NET 4.0版Web.Config配置:

  <configSections>
    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
      <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
        <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
        <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions,  Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
          <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere"/>
          <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
        </sectionGroup>
      </sectionGroup>
    </sectionGroup>
  </configSections>

与:

相关

https://serverfault.com/questions/525443/how-to-uninstall-iis-from-windows-server-2008/525496#525496

Configuration file is not well-formed XML #2