.Net Framework

...now browsing by category

 

ASP.NET Web service call error, “Unable to generate a temporary class (result=1)”

Tuesday, February 19th, 2013

Got this obscure error while calling a web service method that requires a Xml serializer:

Unable to generate a temporary class (result=1).\r\nerror CS2001: Source file ‘C:\\Windows\\TEMP\\qdrb02m1.0.cs’ could not be found\r\nerror CS2008: No inputs specified\r\n”}  System.Exception {System.InvalidOperationException} “

 

Web searches on key phrase “Unable to generate a temporary class (result=1)” returned some useful results but none could directly resolve my issue. But general direction was pointing to the proper permission of the ASP.Net surrogate identity that most likely does not have sufficient right to the local I/O where XML serialization takes place.

To prove this, I fired up a console application and called the same web service method; as anticipated, the Console app did not throw error at all. So that’s true – it is to do with the Windows account that IIS uses to run the ASP.Net process.

By default, IIS7 uses “ApplicationPoolIdentity” as the Identity for the Application pool automatically created when a new website is added to the IIS/Sites. But what’s underneath this mysterious “ApplicationPoolIdentity” – you could not even find it in Windows by looking up user accounts? Below are several things I tried and let’s see how they fared:

  1. I tried to give “Full Control” permission to ASP.NET Machine Account on c:\windows\Temp folder. Not work.
  2. Changed the app pool identity to “Network Service” (via IIS7/Site/Advanced Settings) and gave the “Network Service” full control permission to c:\windows\temp (via Windows Explorer). It worked! Then I reduced permission to only “Read, List Folder Contents”, and it still worked.
  3. Changed the app pool identity to “Local System”, of course that worked too.

 

So, at the end, to get rid of error “Unable to generate a temporary class (result=1)..”,  I ended up using the “Network Service” as the Application Pool identity (leave the security mode as Integrated) and granted the “Network Service” account permission “Read, List folder contents” on “C:\Windows\Temp” folder.

P.S.: after I deployed the web app to my staging web server, the error returned. The staging server is running IIS6 and the app pool identity by default was already tied to “Network Service” account. So I went directly to the c:\windows\temp folder and as I anticipated, the account did not have “read, list folder contents” permission. So I granted the permission to “Network Service” account and then it all worked!

Asp.Net Form Postback error:Error – Operation is not valid due to the current state of the object

Wednesday, December 12th, 2012

Sometimes when there are a large number of input fields on a Asp.Net form, and doing postback, I would get this error:
“Error – Operation is not valid due to the current state of the object”

As it turned out there is a restriction on how many fields can be posted back to server and the large grid that contains a large number of textbox fields probably was the culprit. Google search returned some postings that all point to the configure setting

<appSettings>
<add key=”aspnet:MaxHttpCollectionKeys” value=”2000″ />
</appSettings>

 

After I stuck this line into the appSettings, the problem went away.

Smtp Permission error at Winhost

Friday, December 7th, 2012

When I was developing my ASP.Net app on local machine,  I had no problem sending email by calling directly the SMTP relay server assigned by my hosting company Winhost, with port set to 587 of course. But when I deployed the app to the winhost server, the email tool threw this exception :

Request for the permission of type ‘System.Net.Mail.SmtpPermission, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ failed.

I did suspect some some security permission to Smtp related assembly and have done some search toward that direction. First I got a lead from some post via Google search and one suggested added this entry into the <system.web> section; but that did not work, so I am not going to give reference to this post.

<securityPolicy>
<trustLevel name=”Full” policyFile=”internal”/>
</securityPolicy>

Today, I went into Windost support site and did another search on their forum, and they pointed me to using this instead:

<system.web>

<trust level=”Full” />

</system.web>

Yes, that was all it needed!

Setting up Elmah SQL Server objects manually

Tuesday, December 4th, 2012

1. Run Elmah.axd on localhost and got this error,”Could not find stored procedure ‘ELMAH_GetErrorsXml'”.
What happened was that the Elmah sql objects were not installed properly when I run NuGet package-install elmah from inside VS2010 IDE.

2. Remedy was downloading the elmah-1.2-db-sqlserever.sql script from here
4. Open SQL Server 2008 Management studio and connected to the remote database hosted at Winhost
5. Opened the Elmah db sql script file and executed it on the remote database.
6. Now returned to localhost/Elmah.axd and error log is showing.

Open a new window from aspnet code-behind

Thursday, November 29th, 2012

While creating a Cmi course launch Simulator, I run into the need to open up a new window from asp.net code behide, instead of simply doing a Response.Redirect, which will just transfer the browser window to the target AU entry window, and the window where Cmi Simulator launched the course will be lost.

After reading posts here and there, I learned there were three possible ways to achieve what I needed and I picked the one that best suit me to implement in the end solution.

Soution 1: Simply open a new tab to display AU Entry page

On the CmiSimulator.aspx, I had a server-side button called btnLaunchCourse, when the button is clicked, it simply grabs the

LaunchUrl on the page and does a response.Redirect to the website and page defined in the LaunchUrl. To make sure the target page is displayed in a different tab on the browser, just added the OnClickClick attribute like below:

Text=”Launch Course” CssClass=”submitButton” OnClientClick=”form1.target=’_blank';” />

The code-behind OnLaunchCourse has only this line of code:

Response.Redirect(LaunchUrl);

Here Form1 is the id of the aspnet form on the page. If the page is embedded in a master page, the form tag is located in the master page.

Solution 2: Open a pop-up window

Keep the button html code as it is,

Text=”Launch Course” CssClass=”submitButton” />

And register javascript to open a new window from code-behind “OnLaunchCourse”:

protected void OnLaunchCourse(object sender, EventArgs e)
{

//Response.Redirect(txtLaunchUrl.Text);
string url = txtLaunchUrl.Text;
string newWindow = “window.open(‘” + url + “‘,’_blank’,’height=700,width=800,status=yes, toolbar=no, menubar=no,location=no,scrollbar=yes, resizable=yes, titlebar=no’);”;
ScriptManager.RegisterStartupScript(this, typeof(string), “OpenWindow”, newWindow, true);

}

Solution 3: Extension method

public static void Redirect(this HttpResponse response, string url, string target, string windowFeatures)
{
//credit to this posting at http://stackoverflow.com/questions/104601/asp-net-response-redirect-to-new-window

//windowFeatures example:

windowFeatures=”directories=no,toolbar=no,menubar=no,location=yes,status=no,resizable=yes,width=800,height=600″;
if ((String.IsNullOrEmpty(target) || target.Equals(“_self”, StringComparison.OrdinalIgnoreCase)) &&

String.IsNullOrEmpty(windowFeatures))
{
response.Redirect(url);
}
else
{
Page page = (Page)HttpContext.Current.Handler;

if (page == null)
{
throw new InvalidOperationException(“Cannot redirect to new window outside Page context.”);
}
url = page.ResolveClientUrl(url);

string script;
if (!String.IsNullOrEmpty(windowFeatures))
{
script = @”window.open(“”{0}””, “”{1}””, “”{2}””);”;

}
else
{
script = @”window.open(“”{0}””, “”{1}””);”;
}
script = String.Format(script, url, target, windowFeatures);
ScriptManager.RegisterStartupScript(page, typeof(Page), “Redirect”, script, true);
}
}

At the end, the most elegant solution is the extension method and that was implemented in my final solution. I thank the author of this extension method, Tančev Saša, you’re my hero of the day!

Add a website to local IIS7 and browse to it with friendly name

Tuesday, October 2nd, 2012
  1. Launched IIS7 -> Sites -> Add Web Site
  2. Entered yangsoft.com; left application pool with default name
  3. Mapped to physical path H:\Development\yangsoft.com\Yangsoft.Web
  4. Pick a unassigned port: 8092
  5. Host name: yangsoft.com (hopefully, this will precede the real domain name, once the entry is made into hosts file)
  6. After exiting IIS7, browsed to C:\Windows\System32\drivers\etc and opened the hosts file with notepad
  7. Added this entry: 127.0.0.1 yangsoft.com and saved.
  8. Browsed to http://localhost:8092 but get a bad request error 400: invalid hostname
  9. Returned to IIS7 and changed App Pool Identity “yangsoft.com” to use .net 4.0 and Integrated Mode. By default, whenever a website was first setup, it uses .net v 2.0
  10. Now go to browser and type in :yangsoft.com:8092 and it brought up the local site that is in development folder, not in the deployed folder.
  11. In order to launch the website from VS 2010 IDE in the same fashion, I went into VS2010 web project properties and changed the Servers setting from “Use Visual Studio Development Server” to “Use Local ISI Web server” and pasted in the url: yangsoft.com:8092
  12. Ran the project in debug mode and now the website rendered as http://yangsoft.com:8092/Default.aspx instead of the http://localhost:2236/Default.aspx or whatever random port number the IDE picks for you.

Adding the specified count to the semaphore would cause it to exceed its maximum count.

Wednesday, June 27th, 2012

This was a scary error message I got it today while I tried to switch my EF project to connect to a live database. The way I did the switch was have a pair of Entity Framework connection strings in my web.config, with one pointing to development and one to production database, and when the switch turned to production, the system will automatically pick up the live connection string; and that’s it. Test had been going well in development environment and the production database was exact copy, in terms of schema, of the developmental one, so I felt confident to make the switch and expected the codes should run as expected.

But then came this ugly and convoluted error message from the bottom of Entity framework, “Adding the specified count to the semaphore would cause it to exceed its maximum count.”; what on the earth was this? Google search for the phrase returned quite a few answers, some suggesting it might be sql queries had error, other pointing to Microsoft internal bug in db connection pooling. I found this one clicked – disabling pooling; I always favor simple than complex; this was simplest to do, just added an entry to my connection string, which by default was enabling connection pooling. Amazingly, that did it and the error went away! So here was the EF connection string before I made the change, connectionString=”metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=sqlSvr1;initial catalog=sqlDb1;integrated security=false;user id=user1;password=password1234!;multipleactiveresultsets=True;App=EntityFramework&quot;”

and here is the connection string that cleared the semaphore error,  connectionString=”metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=sqlSvr1;initial catalog=sqlDb1;integrated security=false;user id=user1;password=password1234!;pooling=false;multipleactiveresultsets=True;App=EntityFramework&quot;”

More interestingly, after the error went away, I took out the pooling=false, and ran the app again, things just flied without anymore problem; I also switched back to development database, with pooling option enabled, and still didn’t see the semaphore error as I expected that I would. So, if I could regenerate the error at some point, I suspect if I just simply clean the solution and rebuild the entire solution, I might achieve the same outcome – no more this dreadful and convoluted error, “Adding the specified count to the semaphore would cause it to exceed its maximum count.” (got it from the InnerException)


Use reflection to retrieve SOAP Web service methods

Tuesday, February 28th, 2012

For a local object, retrieving its public methods is quite straightforward using Reflection. Sample codes below will suffice:

using System.Reflection;
using ....;
MethodInfo[] methods = typeof(LocalObjectType).GetMethods(BindingFlags.Public | BindingFlags.Static);
//sort by method names
Array.Sort(methods, delegate(MethodInfo m1, MethodInfo m2)
{ return m1.Name.CompareTo(m2.Name); });
foreach (MethodInfo mi in methods)
{ Console.WriteLine(mi.Name); }

But this does not work if my type is a proxy type to a remote web service. After some readings here and there, I finally was able to get a list of web service SOAP methods from a SOAP ASMX url. Here are the function I created to return a List of the MethodInfo:

using System; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Net;
using System.IO;
using System.Web.Services;
using System.Web.Services.Description;
using System.CodeDom;
using System.CodeDom.Compiler;


public List<MethodInfo> GetSoapMethods()
{
System.Net.WebClient client = new System.Net.WebClient(); string asmxUrl = "http://myservices.mydomain.com/Service.asmx";
if (!asmxUrl.Contains("?wsdl"))
asmxUrl += "?wsdl";
System.IO.Stream stream = client.OpenRead(asmxUrl);
//read service description
ServiceDescription desc = ServiceDescription.Read(stream);
//initialize a service description importer
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap12";
importer.AddServiceDescription(desc, null, null);
//generate a proxy client
importer.Style = ServiceDescriptionImportStyle.Client;
importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
CodeNamespace nmspace = new CodeNamespace();
CodeCompileUnit unit1 = new CodeCompileUnit();
unit1.Namespaces.Add(nmspace);
//import the service into the code-dom tree, this creates proxy codes that use the service
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
if (warning == 0)
{
//System.Xml.Serialization.XmlSchemas mySchema = importer.Schemas;
//Console.WriteLine(mySchema.ToString());
//generate the proxy code
CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");
//compile the assembly proxy with the appropriate references
string[] assemblyReferences = new string[5]{"System.dll","System.Web.Services.dll",
"System.Web.dll","System.Xml.dll","System.Data.dll"};
CompilerParameters parms = new CompilerParameters(assemblyReferences);
CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
Type[] types = results.CompiledAssembly.GetTypes();
Type foundType = null;
foreach (Type t in types)
{
if (t.BaseType == typeof(System.Web.Services.Protocols.SoapHttpClientProtocol))
{
Console.WriteLine(t.ToString());
foundType = t;
break;
}
}
//instantiate proxy class
object service = results.CompiledAssembly.CreateInstance(foundType.ToString());
//this will get all the methods, public or not in the webservice
List<MethodInfo> lstMethods = service.GetType().GetMethods().ToList();
return lstMethods;
}
else
{
Console.WriteLine("Warning..");
return null;
}
}

Deploy .Net 4.0 Website to Local IIS7

Wednesday, January 18th, 2012

I had a website that was upgraded from .Net 2.0 to v.4.0; normally I used Web Deployment Project to pack it and deploy to remote IIS6 server using xcopy and had not encountered the need to deploy to local IIS which is IIS7 now. Today I did, and ran into a few errors before getting it to run, so I recorded the steps and fixes here to refresh myself and help others from being hassled by these again:

  1. Used Web Deployment Project to deploy the solution (Output Assemblies setting: Merge all outputs to a single assembly and Treat as library component checked)
  2. I did not check the “Create an IIS virtual directory for the output folder option as I wanted to create the website manually.
  3. Opened IIS7 and added a new website, called it “NewAdmin”; went to binding and changed port to 8081 as other default ports were already taken by other sites; left the application pool to use the default one created by the system.
  4. By default every new site created in IIS7 uses ASP.Net v2.0, obviously, changed that to .Net v.4.xxxx, and left the Integrated mode and ApplicationPoolIdentity unchanged.
  5. Now browsed to the site and got this error, “There is a duplicate ‘system.web.extensions/scripting/scriptResourceHandler’ section defined”, and some more, “There is a duplicate ‘system.web.extensions/scripting/webServices/jsonSerialization’ section defined”..
  6. Googled and read postings from here, and led me to doing the next step
  7. Removed these sections from the sectionGroup:<section name=”scriptResourceHandler” type=”System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″ requirePermission=”false” allowDefinition=”MachineToApplication”/><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”/>

     

  8. Browsed to the site again, a different error was displayed “The page you are requesting cannot be served because of the ISAPI and CGI Restriction list settings on the Web server.” what’s going on?
  9. Well, actually this should have been done in step 3) – I need to lift the ISAPI and CGI Restrictions on the site just created. By default, IIS7 shutdowns everything; this is far different from IIS6 and earlier version, so be aware!
  10. Went back to local host node, clicked on Features View, then double clicked on ISAPI and CGI Restrictions – saw that By default ASP.Net v4.0.30319 was restricted. Changed that to “Allow”.
  11. That’s it.

NT AUTHORITY\NETWORK SERVICE does not have write access to ‘..\Temporary ASP.NET Files’.

Wednesday, January 4th, 2012

Got this error while trying to browse to a WCF service from IIS7: The current identity (NT AUTHORITY\NETWORK SERVICE) does not have write access to ‘D:\WINDOWS\Microsoft.NET\Framework\v4.0.3019\Temporary ASP.NET Files’. 

What happened? There must be some recent Windows updates to IIS7 that had messed up the previously security settings, but this was just my guessing. Important thing was how to fix this quickly. Found a post here granting access to IIS configuration and other directorys used by ASP.Net, and executed this line of command:

C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regiis -ga “NT Authority\Ne
twork Service”

And that took care of it. “Network Service” is the identity used by the Application Pool used by the WCF service.