Microsoft.Web.Administration null reference when trying to add application to site - c#

i'm trying to add an application to site via code (C#) and i get a null reference.
someone have an idea why?
here's the code i use:
Application app;
using (var sm = new ServerManager())
{
if (site.Applications["/" + appName] == null)
{
site.Applications.Add("/" + appName, physicalPath);
sm.CommitChanges();
}
app = site.Applications["/" + appName];
}
return app;
the code fails on the "add" line.
the appName is a string like "MyNewApp".
the physicalPath is a string like "C:\inetpub\wwwroot\MyService".
the site is Microsoft.Web.Administration.Site object of the IIS6.1 (win 7 ent) default web site.

found the answer: NullReferenceException in Microsoft.Web.Administration when adding https binding
its all because of the "using" statement.
the site didn't have a parent ServerManager at the point of the application add.

Related

How to get website's physical path on IIS 10?

In my MVC app I want to get website's physical path on IIS server. This old post is about it, but I'm using a newer version of IIS (10.0.19041.1). Is there another way of accomplishing this task?
I was trying the accepted solution from the above mentioned post, but it throws me an exception System.NullReferenceException: 'Object reference not set to an instance of an object.' site was null..
using Microsoft.Web.Administration;
//...
int iisNumber = 2;
using (ServerManager serverManager = new ServerManager())
{
var site = serverManager.Sites.Where(s => s.Id == iisNumber).SingleOrDefault();
var applicationRoot = site.Applications.Where(a => a.Path == "/").SingleOrDefault(); //here I get the exception
var virtualRoot = applicationRoot.VirtualDirectories.Where(v => v.Path == "/").SingleOrDefault();
Console.WriteLine(virtualRoot.PhysicalPath);
System.Diagnostics.Debug.WriteLine("***************************************path to IIS website: " + virtualRoot.PhysicalPath + "***************************************");
}
My website properties:

How to get the ApplicationPool object based on a Site in IIS

I've created an application that gets all of my Sites in IIS and checking each URL in Bindings if there's an HTTP error and if a certain error is encountered, my application will reset the IIS Site Instance in IIS, however, it's not enough to fix the error as it should. I would be needing to reset both the Site and the Application pool it belongs to.
Is there any way to get the Application Pool object based on the Site object?
I have tried the code below but this only works if an application pool only has 1 Site/Application in it. The problem is, I don't get the matching App Pool of the Site if I have a number mismatch between the List of Sites vs List of ApplicationPools since 1 AppPool can have multiple Sites/Applications.
ServerManager serverMgr = new ServerManager();
SiteCollection sites;
ApplicationPoolCollection appPools;
public List<(Site, ApplicationPool, string)> getSiteInfo()
{
List<(Site, ApplicationPool, string)> siteInfo = new List<(Site, ApplicationPool, string)>();
List<string> siteUrls = new List<string>();
sites = serverMgr.Sites;
appPools = serverMgr.ApplicationPools;
foreach (Site site in sites)
{
foreach (ApplicationPool appPool in appPools)
{
foreach (Binding binding in site.Bindings)//getting site url
{
string bindingInfo = binding.BindingInformation; // "192.111.1.1:80:google.com" /// *:808:
string[] adrs = bindingInfo.Split(':'); //0 = ip, 1 = port, 2 = hostname
if (adrs[0] == "*")
{
adrs[0] = "localhost";
}
//adding to my list of sites and it's corresponding Application Pool in 1 tuple variable
siteInfo.Add((site, appPool, adrs[0] + ":" + adrs[1] + "/" + adrs[2])); //localhost:80/google.com
}
}
}
return siteInfo;
}
I need something similar to this code: (see comments)
public List<(Site, ApplicationPool, string)> getSiteInfo()
{
List<(Site, ApplicationPool, string)> siteInfo = new List<(Site, ApplicationPool, string)>();
List<string> siteUrls = new List<string>();
sites = serverMgr.Sites;
foreach (Site site in sites)
{
foreach (Binding binding in site.Bindings)
{
//I need something like this to make sure the AppPool I'm getting is of the Site I have.
ApplicationPool appPool = site.ApplicationPoolName;//<-- This Line
string bindingInfo = binding.BindingInformation;
string[] adrs = bindingInfo.Split(':');
if (adrs[0] == "*")
{
adrs[0] = "localhost";
}
//So that I can do this when passing the Site Info tuple Variable with the Site Object together with the corresponding AppPool for later use of the IISReset Class in my project.
siteInfo.Add((site, appPool, adrs[0] + ":" + adrs[1] + "/" + adrs[2]));
}
}
return siteInfo;
}
Sorry for the long and sloppy explanation but I would be happy to clear out if you have questions with this. Thank you.
I figured it out by using Applications attribute of a site. To get the application pool of a Site I did the code below. Where I got the list of applications of a site and used that to identify the app pool from the list of application pools in the server. However this only works if the site only has 1 application, that's why I'm indexing 0(zero) to get the first application (which is the only application of my site) to search for it's corresponding app pool.
ApplicationCollection apps = site.Applications;
ApplicationPool appPool = serverMgr.ApplicationPools[appname[0].ApplicationPoolName];

How to get Application Pool name through code (C#, ASP.net)

I want to recycle the application pool through my application.
Previously I was storing the application pool name in my database and using that to recycle.
But It happened in the past that we moved apps from one app pool to another and sometimes we forget to update the app pool name in the database.
So I am thinking to get the app pool name through the application and use that for recycling.
In many cases it might be enough to just read the name of the application pool from the environment variable:
var apppool = System.Environment.GetEnvironmentVariable(
"APP_POOL_ID", EnvironmentVariableTarget.Process);
Modified version of #Razon answer :)
public static string GetCurrentApplicationPoolName()
{
ServerManager manager = new ServerManager();
string DefaultSiteName = System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
Site defaultSite = manager.Sites[DefaultSiteName];
string appVirtualPath = HttpRuntime.AppDomainAppVirtualPath;
string appPoolName = string.Empty;
foreach (Application app in defaultSite.Applications)
{
string appPath = app.Path;
if (appPath == appVirtualPath)
{
appPoolName = app.ApplicationPoolName;
}
}
return appPoolName;
}
May this can help: ApplicationPoolName Property
Namespace: Microsoft.Web.Administration
Assembly: Microsoft.Web.Administration (in Microsoft.Web.Administration.dll)
http://msdn.microsoft.com/en-us/library/microsoft.web.administration.application.applicationpoolname(v=vs.90).aspx

Assign application pool to website in iis7 programmatically

I'm using the following method to create application pool and assign it to web site.
This is code for application pool creation:
WebSiteName = some website name which existed.
I see that all values are get where they should be in debug mode
private void ConfiugreAppPoolIIS7(targetMachine)
{
var mgr = ServerManager.OpenRemote(targetMachine);
if (AppPoolProp.ContainsKey("SomeTestAppPool"))
{
string reqAppPool = AppPoolProp["SomeTestAppPool"];
if (!mgr.ApplicationPools.Any(pool => pool.Name == reqAppPool))
{
ApplicationPool myApp = mgr.ApplicationPools.Add(reqAppPool);
myApp.AutoStart = true;
myApp.ManagedPipelineMode = ManagedPipelineMode.Classic;
myApp.ManagedRuntimeVersion = "V4.0";
myApp.ProcessModel.IdentityType = ProcessModelIdentityType.NetworkService;
myApp.Enable32BitAppOnWin64 = true;
mgr.CommitChanges();
foreach (Site site in mgr.Sites)
{
if(site.Name == WebSiteName)
{
site.Stop();
site.ApplicationDefaults.ApplicationPoolName = myApp.Name;
site.Start();
mgr.CommitChanges();
}
}
}
}
}
The result is, I see the Aplication pool created successfuly, and the Website created as well, but, I see in the advanced settings of my web site the default appplication pool is assigned.
Could you please help?
The problem has been fixed by fixing reference to right Microsoft.Web.Administration.dll
Cause of this server manage connected to express iis instead of my local iis.

How to make Installer using WCF

I have one console application.The application calls WCF on server.
The application runs perfectly in Visual Studio 2008.
error:
I used an installer project in Visual Studio.
I make an installer give primary output to the Application.
It cannot connect to WCF on server.
What steps are necessary to make an installer which has an console (Application)exe,
which in turn uses WCF.
My Scope Initialization starts from initScopeInfo.
private void initScopeInfo()
{
DBSyncProxy.SqlSyncProviderProxy client = null;
ScopeConfigHandler scopeHandler = null;
try
{
//Providing the Config file name('db_config_new.xml') stored in static variable.
DBSyncXMLUtil.setXPathDocument(DBSyncConstants.DB_SYNC_CONFIG_FILE_NAME);
//DBSyncXMLUtil.setXPathDocument(filepath);
string endpoint = DBSyncXMLUtil.getSystemParameter(DBSyncXMLUtil.getDocumnetRoot(), "ServiceURL");
In setXpathDocument
public static void setXPathDocument(string uri)
{
public static XPathDocument doc = null;
doc = new XPathDocument(uri);
}
public static string getSystemParameter(XPathNavigator docroot, string key)
{
string value = null;
try
{
string xpath = DBSyncConstants.XPATH_SYSTEM_PARAMETER;
xpath += "[#key='" + key + "']";
Console.WriteLine("DBSyncXMLUtil :: getParameter() :: XPATH =="+xpath);
Probably Error on below mentioned line
XPathNavigator node = getDocumnetRoot(doc).SelectSingleNode(xpath);
if (node != null)
value = node.Value;
else
Console.WriteLine("Invalid XPATH");
}
catch (Exception ex)
{
Console.WriteLine("DBSyncXMLUtil :: getSystemParameter() :: Exception ==" + ex.ToString());
}
return value;
}
Actually you cannot directly create an installer project by adding primary output from a WCF service. You should host the WCF service inside a windows service and add the primary output of the windows service to the installer project.
create a WCF.
create a windows service and host the WCF inside it (call the WCF from windows service).
Create a setup project (installer project).
Add the primary output of the windows service to the installer project.
see this link to see the hosting details...
http://msdn.microsoft.com/en-us/library/ms733069.aspx
See this blog. It will help you with the implementation of windows service...
http://joefreeman.co.uk/blog/2010/03/creating-a-setup-project-for-a-windows-wcf-service-with-visual-studio/

Categories