记得有时在刚装完IIS访问localhost网页时会提示输入用户名和密码,我直到现在还没有输入成功过,不知道是否可以通过“我的电脑”中的“管理”菜单中的用户那里设置用户名和密码,然后将相应的用户名和密码输入才会成功,没有试过。另一个解决方法是添加匿名用户访问:IIS属性的“目录安全”页的“编辑”按钮。勾选“匿名访问”的checkbox。这样一般都能直接访问了,包括自己创佳的虚拟目录网站。
但是这样在访问:iisstart.asp(localstart.asp)的时候还是会给出如下的提示错误:
错误类型:
Microsoft VBScript 运行时错误 (0x800A0046)
没有权限: 'GetObject'
/localstart.asp, 第 40 行
在这里的现象有时也会是直接直接打开
http://localhost时出现,这是因为你(或是系统默认)在IIS属性的“文档”页中的“启动默认文档”组中添加了iisstart.asp。这个在输入
http://localhost就会自动转到iisstart.asp文件的执行,然后是转到localstart.asp页面中。要解决这个问题的方法是把这两个文件的匿名用户设置为ASPNET用户(有人说可以用Administrator,但是我试了好像是不可以的,不知道为什么),这个的设置方法是匿名访问的页面中的“预览”->“高级”->“查找”中找到ASPNET用户,然后添加上去,即可。
这样,问题就解决了。
但是随之我们可以做一些思考:在我们登陆网站一个网站时,我们是没有输入用户名和密码的,其实是我们在登录的时候,服务器默认给了我们一个guest的账号,然后我们才可以访问页面。这个也就可以解释为什么刚开始我们需要输入用户名和密码的原因了。另外在FTP中有时我们也需要用户名和密码我们也是这个原理所在。
posted @ 2009-03-29 22:12 江湖飘 阅读(296) 评论(0)
编辑
记得刚开始学WCF的时候就尝试过去在IIS中部署部署WCF,但是找了很多网上的资料,都没有部署成功,按照网上的说法是做下来,不知是不是人品的问题,总是成功不了,呵呵。那时候也实在是太菜了,IIS刚接触,甚至连.NET也是刚接触,因为公司用的是直接用SOAP TCP传输的,没有涉及到IIS的部署,所以同事中也都没有试过在IIS中部署,后来就不了了之了。
今天因为同住的学长在弄这个东西,然后就帮忙查了一下。也是在网上查了N久,自己遇到的问题他们就是没有提到,后来终于是在MSDN的论坛上找到了我问题的所在。下面列一下自己遇到的问题,防止自己以后忘掉,也是给后来者一个指导吧。
当然先是要安装IIS和ASP.NET,关于ASP.NET的安装需要运行"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -i ”命令,这个我在已经在前面的文章中提及过。就不再多述了。然后需要在IIS中配置.svc扩展名,这个可以通过命令"C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe -i”来完成。也可以“ Internet信息服务->主目录->配置...->映射->添加”
中,在可执行文件中填入:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll,扩展名填入:.svc 如果需要可以填写动作,这样一般就可以成功了。
然后创建虚拟目录,把编写好的代码放入App_Code文件夹中,或是把编译好的dll文件放入Bin文件夹中即可,填写.svc后缀文件,如:
<%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceApp.Service1" %>
这样一般都是能成功的。至少我在网上找到的是这样的。但是我自己偏偏成功不了,总是有下面的提示:
[InvalidOperationException: 未找到 URI“http://192.168.100/GetDataService”的兼容 TransportManager。这可能是因为使用了指向虚拟应用程序外部的绝对地址。请使用相对地址。]
System.ServiceModel.Channels.TransportChannelListener.ThrowTransportManagersNotFound() +248
System.ServiceModel.Channels.TransportChannelListener.SelectTransportManagers() +4492816
System.ServiceModel.Channels.TransportManagerContainer.Open(SelectTransportManagersCallback selectTransportManagerCallback) +55
System.ServiceModel.Channels.TransportChannelListener.OnOpen(TimeSpan timeout) +75
System.ServiceModel.Channels.HttpChannelListener.OnOpen(TimeSpan timeout) +67
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +268
System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +61
[InvalidOperationException: “http://192.168.100/GetDataService”处带有协定“"IGetData"”的 ChannelDispatcher 无法打开其 IchannelListener。]
System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +107
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +268
System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +123
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +268
System.ServiceModel.Channels.CommunicationObject.Open() +30
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +104
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +498
[ServiceActivationException: 由于编译过程中出现异常,无法激活服务“/SOAP/GetDataService.svc”。异常消息为: “http://192.168.100/GetDataService”处带有协定“"IGetData"”的 ChannelDispatcher 无法打开其 IchannelListener。。]
System.ServiceModel.AsyncResult.End(IAsyncResult result) +4413209
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +183
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication context, Boolean flowContext) +205
System.ServiceModel.Activation.HttpModule.ProcessRequest(Object sender, EventArgs e) +322
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +92
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64
让我苦找,最终找到的结果是我因为我在Web.config文件中配置了address的值为:http://192.168.100/GetDataService,看来是我用Windows服务用多了,这个地址的值就下意识的填上去了。msdn的论坛上没有给出解释说为什么不用这个地址,我猜测在Windows服务中这个地址用来在请求到达时提供一个处理改请求的端口,而如果把IIS作为宿主,则这个地址由IIS提供就可以了,IIS提供的是基地址,就像是在windows服务中的baseAddress的概念,而这个地址提供的是相对地址,比如我们可以加入bin的值,表示我们将dll文件放到虚拟目录下的bin文件夹下。
这样我遇到的问题就都解决了。这里的Bin和App_Code文件夹是ASP.NET默认识别的文件夹,可以将dll文件放入Bin文件夹中,将源代码放入App_Code文件夹中,在App_Code文件夹中,ASP.NET会根据文件扩展名来确定调用什么编译器,比如.vb调用VB的编译器,.cs调用C#编译器;但是这个文件夹中不能同时包含不同的源代码,不过这个问题可以通过配置ASP.NET来解决。
posted @ 2009-03-29 21:48 江湖飘 阅读(1267) 评论(0)
编辑
读GoF的《Design Pattern》的收获还是很大的,虽然我还不能完全理解里面的精髓。其中有一个例子就加深了我对auto_ptr的理解。
在这本书中关于代理模式的讲解中提到了关于指针的代理(MyMath类是我自己实现用来演示的,它主要就是实现了一个Show的函数,可以用来打印提示符):

Code
//
// File :
// MyMath.h
// Description:
// About one implementation of auto ptr
// From GoF's Proxy Pattern
// Copyright : 2009 - 2010
// Author : Diwore
// Contact : dinglifedream@163.com
// Compiler : Visual Studio 2008
#include "MyMath.h"
#include <stdlib.h>
#pragma once
// ImagePtr
class ImagePtr
{
public:
ImagePtr(const char* a_szFileName);
virtual ~ImagePtr();
virtual MyImage* operator -> ();
virtual MyImage& operator* ();
private:
MyImage* LoadImage(const char* a_szFileName);
private:
MyImage* m_pImage;
char* m_pFileName;
};
// ImagePtr Implementation
ImagePtr::ImagePtr(const char* a_szFileName)
{
int len = sizeof(a_szFileName);
m_pFileName = new char[len + 1];
strncpy(m_pFileName, a_szFileName, len);
*(m_pFileName + len) = '\0';
m_pImage = NULL;
}
ImagePtr::~ImagePtr()
{
if(NULL != m_pImage)
delete m_pImage;
if(NULL != m_pFileName)
delete m_pFileName;
m_pImage = NULL;
m_pFileName = NULL;
}
MyImage* ImagePtr::operator -> ()
{
return LoadImage(m_pFileName);
}
MyImage& ImagePtr::operator * ()
{
return *LoadImage(m_pFileName);
}
MyImage* ImagePtr::LoadImage(const char* a_szFileName)
{
if(NULL == m_pImage)
m_pImage = new MyImage(a_szFileName);
return m_pImage;
}
/*
* Client Code :
* ImagePtr l_Image = ImagePtr("Image1.jpg");
* //(l_Image.operator ->())->Show();
* l_Image->Show();
*/
这里的ImagePtr类重载了->, *两个符号,这样我们在使用的时候就可以声明一个栈的变量,但是像指针一样使用它。只要我们在编写ImagePtr类的时候不要忘掉释放内存就很少会在出现内存泄露的问题了。即使在抛异常的情况下,因为它是栈上的变量,所以在它退出栈的时候就会自动调用它的析构函数了。
由这个的实现,然我想起了auto_ptr的使用,是否它的实现用的就是这样的思想呢?如下面我模仿它的实现:

Code
//
// File :
// my_auto_ptr2.h
// Description:
// Imitate the implementation of auto_ptr<TemplateName>
// Copyright : 2009 - 2010
// Author : Diwore
// Contact : dinglifedream@163.com
// Compiler : Visual Studio 2008
#pragma once
#define NULL 0
template <class TElement>
class my_auto_ptr2
{
public:
my_auto_ptr2();
my_auto_ptr2(TElement* a_pElement);
virtual ~my_auto_ptr2();
virtual TElement* operator -> ();
virtual TElement& operator * ();
virtual TElement* operator = (void* a_ptr);
private:
TElement* m_pElement;
};
// my_auto_ptr2 Implementation
template<class TElement>
my_auto_ptr2<TElement>::my_auto_ptr2()
{
m_pElement = new TElement();
}
template<class TElement>
my_auto_ptr2<TElement>::my_auto_ptr2(TElement* a_pElement)
{
m_pElement = a_pElement;
}
template<class TElement>
my_auto_ptr2<TElement>::~my_auto_ptr2()
{
if(NULL != m_pElement)
delete m_pElement;
m_pElement = NULL;
}
template<class TElement>
TElement* my_auto_ptr2<TElement>::operator -> ()
{
return m_pElement;
}
template<class TElement>
TElement& my_auto_ptr2<TElement>::operator * ()
{
return *m_pElement;
}
template<class TElement>
TElement* my_auto_ptr2<TElement>::operator = (void* a_ptr)
{
if(NULL != m_pElement)
{
delete m_pElement;
m_pElement = NULL;
}
m_pElement = (TElement*)a_ptr;
return m_pElement;
}
我刚开始还想到了另一种类似的方法,它可以实现推迟类的创建。

Code
//
// File :
// my_auto_ptr.h
// Description:
// Imitate the implementation of auto_ptr<TemplateName>
// Copyright : 2009 - 2010
// Author : Diwore
// Contact : dinglifedream@163.com
// Compiler : Visual Studio 2008
#pragma once
#define NULL 0
/*
* ICreator is used for a class to derive
* so that it can be used to create a class using
* a specifical parameters.
* Every class that derived from ICreator should
* implement Create() method.
*/
class ICreator
{
public:
virtual void* Create() = 0;
};
// my_auto_ptr class
// Used as auto_ptr
// Note: TElement should have a default constuctor
template <class TElement>
class my_auto_ptr
{
public:
my_auto_ptr();
my_auto_ptr(ICreator* a_Creator);
virtual ~my_auto_ptr();
virtual TElement* operator -> ();
virtual TElement& operator * ();
virtual TElement* operator = (void* a_ptr);
private:
TElement* LoadElement();
private:
TElement* m_pElement;
ICreator* m_pCreator;
};
// my_auto_ptr Implementation
template<class TElement>
my_auto_ptr<TElement>::my_auto_ptr()
{
m_pElement = NULL;
m_pCreator = NULL;
}
// ICreator is used to Create an element
// with user define constructor
template<class TElement>
my_auto_ptr<TElement>::my_auto_ptr(ICreator *a_Creator)
{
m_pElement = NULL;
m_pCreator = a_Creator;
}
template<class TElement>
my_auto_ptr<TElement>::~my_auto_ptr()
{
if(NULL != m_pElement)
delete m_pElement;
if(NULL != m_pCreator)
delete m_pCreator;
m_pElement = NULL;
m_pCreator = NULL;
}
template<class TElement>
TElement* my_auto_ptr<TElement>::operator -> ()
{
return LoadElement();
}
template<class TElement>
TElement& my_auto_ptr<TElement>::operator * ()
{
return *LoadElement();
}
template<class TElement>
TElement* my_auto_ptr<TElement>::operator = (void* a_ptr)
{
if(NULL != m_pElement)
{
delete m_pElement;
m_pElement = NULL;
}
m_pElement = (TElement*)a_ptr;
return m_pElement;
}
template<class TElement>
TElement* my_auto_ptr<TElement>::LoadElement()
{
if(NULL == m_pElement)
{
if(NULL != m_pCreator)
m_pElement = (TElement*)m_pCreator->Create();
else
m_pElement = new TElement();
}
return m_pElement;
}
只是这个在实现中需要注意两点:1. 对泛型的类型,一定要提供一个默认构造函数,否则会编译出错。2. 如果需要在构造的时候使用自己的构造函数,则需要编写一个派生于ICreator接口的类,然后声明一个指针实例传入my_auto_ptr类中。
缺点:
不管是我的模仿实现还是auto_ptr的本身实现,都有两个缺点:
1. 不能在STL中使用他们。个人理解是它们的实例是栈上的实例,而STL内部的成员要求基本上是堆上的实例,这样当它们的对象退出栈的时候,这个对象也就销毁了,这样存在STL中的指针就没什么意义了,所以C++标准之处这样做会产生不可预料的结果。
2. 不可以在构造函数上使用数组(my_auto_ptr2和auto_ptr中)。如一下的语句是不合法的:
my_auto_ptr2<char> str = my_auto_ptr2(new char[10]);
因为数组是要用delete []语句来销毁的,但是默认中的销毁是用delete来直接销毁指针的内容的,所以这样做会产生不可预料的结果。
posted @ 2009-03-29 04:27 江湖飘 阅读(81) 评论(0)
编辑