DNN建立子Portal的bug

本文分析了DNN建立子门户后无法正确访问的问题。详细解释了端口参数导致的错误匹配过程,并提供了修复建议。

今天实验dnn建立子portal的时候,发现建立了子portal后,却没法访问。经过分析源代码后确认是dnn的bug。

在选择建立子portal的时候,如下:

默认情况下dnn会在Portal Alias中把端口也加上去。

当按这种默认方式建立好子portal后,访问localhost:10018/DotNetNuke_Maintenance/Portal2的话会提示找不到服务器。

需要去掉端口,这时候才能访问,但是这时候访问的时候发现访问到的是默认的portal,即Portal0,而不是我刚才建立的Portal2。

这时候的浏览器URL变为:

http://localhost:10018/DotNetNuke_Maintenance/Default.aspx?alias=localhost:10018/DotNetNuke_Maintenance/portal2

发现这时候的alias参数又带有端口参数。

问题分析:

1、在建立子portal的时候,如果加上端口参数,出现找不到服务器或者网页的问题。

在UrlRewriteModule第380行:

 ' parse the Request URL into a Domain Name token
                DomainName = GetDomainName(Request, True)

这里得到的DomainName是不带参数的。

所以稍后,在424行:

 'using the DomainName above will find that alias that is the domainname portion of the Url
                'ie. dotnetnuke.com will be found even if zzz.dotnetnuke.com was entered on the Url
                objPortalAliasInfo = PortalSettings.GetPortalAliasInfo(PortalAlias)
                If Not objPortalAliasInfo Is Nothing Then
                    PortalId = objPortalAliasInfo.PortalID
                End If

中,objPortalAliasInfo将返回空,即根据这个DomainName在数据库中无法找到对应的PortalAlias设置。

所以会出现问题。

 

2、当不添加端口的时候,会显示默认portal。

这时候,我们发现Url中的alias参数是有端口的,说明在将

http://localhost:10018/DotNetNuke_Maintenance/Portal2

解析为:

http://localhost:10018/DotNetNuke_Maintenance/Default.aspx?alias=localhost:10018/DotNetNuke_Maintenance/portal2

时发生了错误。

错误的原因在于多加了端口。

当我们在建立Portal2时,dnn在网站根目录下添加了一个目录Portal2,里面有个Default.aspx文件,这个文件起的就是个重定向的作用,用来将我们这种地址的访问(http://localhost:10018/DotNetNuke_Maintenance/Portal2)转化为对网站目录Default.aspx的访问。并且将alias参数设置好,以便Default.aspx加载相应的Portal的Tab。

分析Portal2/Default.aspx就很容易发现问题:

<%@ Page language="VB" %>
<%@ Import Namespace="DotNetNuke" %>

<script runat="server">

    Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

            Dim DomainName As String
            Dim ServerPath As String
            Dim URL() As String
            Dim intURL As Integer

            ' parse the Request URL into a Domain Name token
            URL = Split(Request.Url.ToString(), "/")
            For intURL = 2 To URL.GetUpperBound(0)
                Select Case URL(intURL).ToLower
                    Case "admin", "desktopmodules", "mobilemodules", "premiummodules"
                        Exit For
                    Case Else
                        ' check if filename
                        If InStr(1, URL(intURL), ".aspx") = 0 Then
                            DomainName = DomainName & IIf(DomainName <> "", "/", "") & URL(intURL)
                        Else
       Exit For
                        End If
                End Select
            Next intURL

            ' format the Request.ApplicationPath
            ServerPath = Request.ApplicationPath
        If Mid(ServerPath, Len(ServerPath), 1) <> "/" Then
            ServerPath = ServerPath & "/"
        End If
        
        
        DomainName = ServerPath & "Default.aspx?alias=" & DomainName
       
        Response.Redirect(DomainName, True)
 
    End Sub

</script>

这里,并没有同样地调用DotNetNuke.Common.Globals.GetDomainName方法,而是自己进行DomainName 的解析,这里的解析并没有解析端口。所以Response.Redirect(DomainName, True)中的的DomainName中的alias参数就是含有端口的。

因此当用带有端口的alias参数传递过去的时候,在UrlRewriteModule处理的时候,使用这个alias查询portal的时候,又失败了。

 ' alias parameter can be used to switch portals
                If Not (Request.QueryString("alias") Is Nothing) Then
                    ' check if the alias is valid
                    If Not PortalSettings.GetPortalAliasInfo(Request.QueryString("alias")) Is Nothing Then
                        ' check if the domain name contains the alias
                        If InStr(1, Request.QueryString("alias"), DomainName, CompareMethod.Text) = 0 Then
                            ' redirect to the url defined in the alias
                            Response.Redirect(GetPortalDomainName(Request.QueryString("alias"), Request), True)
                        Else ' the alias is the same as the current domain
                            PortalAlias = Request.QueryString("alias")
                        End If
                    End If
                End If

 ' parse the Request URL into a Domain Name token
                DomainName = GetDomainName(Request, True)

所以,就又显示了默认网站。

问题的原因在于Portal2/Default.aspx和UrlRewriteModule.vb对DomainName的处理不一致造成的。这种处理在于没有端口的情况下,例如默认80端口时不会有问题,但是如果有端口的时候就会有问题。

所以需要把2边的处理变成相同的,既然已经写了对DomianName处理的共用方法:DotNetNuke.Common.Globals.GetDomainName,在Portal2/Default.aspx中就没有必要再写那么多代码去分析了。直接调用就行了。

改为如下代码即可:

 <%@ Page language="VB" %>
<%@ Import Namespace="DotNetNuke" %>

<script runat="server">

    Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

            Dim DomainName As String
            Dim ServerPath As String


                   ' format the Request.ApplicationPath
            ServerPath = Request.ApplicationPath
        If Mid(ServerPath, Len(ServerPath), 1) <> "/" Then
            ServerPath = ServerPath & "/"
        End If
       
        DomainName = DotNetNuke.Common.Globals.GetDomainName(Request, True)
        DomainName = ServerPath & "Default.aspx?alias=" & DomainName
       
        Response.Redirect(DomainName, True)
 
    End Sub

</script>

### 构建深度神经网络(DNN)模型的步骤 构建深度神经网络(DNN)模型通常包括以下几个关键步骤:数据准备、模型定义、训练过程和评估与预测。以下将以 MNIST 数据集为例,使用 TensorFlow 和 Keras API 来实现一个基本的 DNN 模型。 #### 数据准备 在开始构建模型之前,需要准备好数据集并进行预处理。对于 MNIST 数据集,可以通过 `tf.keras.datasets.mnist.load_data()` 直接加载数据,并对输入数据进行归一化处理,以提高模型的训练效率。 ```python import tensorflow as tf # 加载MNIST数据集 (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() # 归一化数据 x_train = x_train / 255.0 x_test = x_test / 255.0 ``` #### 模型定义 接下来,需要定义 DNN 模型的结构。这通常包括多个全连接层(Dense Layer),以及激活函数(如 ReLU 或 Softmax)。可以使用 `tf.keras.Sequential` 来堆叠这些层[^1]。 ```python model = tf.keras.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), # 将二维图像展平为一维向量 tf.keras.layers.Dense(128, activation='relu'), # 第一层全连接层,包含128个神经元,使用ReLU激活函数 tf.keras.layers.Dense(10, activation='softmax') # 输出层,包含10个神经元,对应数字0-9,使用Softmax激活函数 ]) ``` #### 编译模型 在模型定义完成后,需要通过 `compile` 方法配置优化器、损失函数和评估指标。常用的优化器有 Adam、SGD 等,而分类任务中常用的损失函数是交叉熵损失(`SparseCategoricalCrossentropy`)。 ```python model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) ``` #### 训练模型 完成模型编译后,就可以调用 `fit` 方法开始训练模型了。传入训练数据 `x_train` 和标签 `y_train`,并指定训练轮数(epochs)和批次大小(batch_size)。 ```python model.fit(x_train, y_train, epochs=5, batch_size=32) ``` #### 评估与预测 训练完成后,可以通过 `evaluate` 方法来测试模型在验证集上的表现。如果模型表现良好,则可以使用 `predict` 方法来进行预测。 ```python test_loss, test_acc = model.evaluate(x_test, y_test) print(f'Test accuracy: {test_acc}') predictions = model.predict(x_test) ``` ### 使用 tiny-dnn 实现 DNN 模型 除了 TensorFlow,也可以使用轻量级框架 `tiny-dnn` 来构建 DNN 模型。它特别适合资源受限的环境。以下是使用 `tiny-dnn` 构建 MNIST 分类器的基本流程: 1. **安装 tiny-dnn** 首先,确保已经正确安装了 `tiny-dnn` 库。可以通过 GitHub 获取源码并进行编译: ```bash git clone https://github.com/tiny-dnn/tiny-dnn.git cd tiny-dnn mkdir build && cd build cmake .. make ``` 2. **编写代码** 创建一个 C++ 文件,导入必要的头文件,并定义网络结构。下面是一个简单的示例代码: ```cpp #include <tiny_dnn/tiny_dnn.h> using namespace tiny_dnn; using namespace tiny_dnn::activation; int main() { // 定义网络结构 network<tan_h> net; net << fc_layer<relu>(784, 128) // 输入层到隐藏层 << fc_layer<identity>(128, 10); // 隐藏层到输出层 // 设置优化器 adagrad optimizer; optimizer.alpha = 0.1f; // 加载MNIST数据 std::vector<label_t> labels_train, labels_test; std::vector<vec_t> images_train, images_test; parse_mnist_labels("train-labels.idx1-ubyte", &labels_train); parse_mnist_images("train-images.idx3-ubyte", &images_train); parse_mnist_labels("t10k-labels.idx1-ubyte", &labels_test); parse_mnist_images("t10k-images.idx3-ubyte", &images_test); // 训练模型 for (int i = 0; i < 10; ++i) { net.train<mse>(optimizer, images_train, labels_train, 32, 1); result res = net.test(images_test, labels_test); cout << "Test accuracy: " << res.num_success * 100.0 / res.num_total << "%" << endl; } return 0; } ``` 上述代码展示了如何使用 `tiny-dnn` 构建一个简单的两层全连接网络,并对其进行训练和测试 [^2]。 ### 使用 PyTorch 实现 DNN 模型 PyTorch 是另一个流行的深度学习框架,提供了更灵活的张量操作和动态计算图。以下是使用 PyTorch 构建 DNN 模型的基本步骤: 1. **导入库** ```python import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms ``` 2. **定义网络结构** ```python class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.fc1 = nn.Linear(28*28, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): x = torch.relu(self.fc1(x)) x = self.fc2(x) return x ``` 3. **加载数据** ```python transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))]) trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True) ``` 4. **初始化模型、损失函数和优化器** ```python model = Net() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) ``` 5. **训练模型** ```python for epoch in range(5): # 进行多轮训练 running_loss = 0 for images, labels in trainloader: images = images.view(images.shape[0], -1) # 展平图像 # 前向传播 outputs = model(images) loss = criterion(outputs, labels) # 反向传播 optimizer.zero_grad() loss.backward() optimizer.step() running_loss += loss.item() print(f"Epoch {epoch+1} Loss: {running_loss}") ``` 6. **保存模型** ```python torch.save(model.state_dict(), 'mnist_model.pth') ``` 通过上述方法,可以使用不同的深度学习框架(如 TensorFlow、tiny-dnn 和 PyTorch)来构建 DNN 模型,并应用于 MNIST 手写数字识别任务 [^1][^2][^3]。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值