ASP.net MVC4 WebAPI JSON Medium Trust - asp.net

So, I've been playing with ASP.net MVC4 and the new WebAPI the past few days. One of the first things I always do when starting a new app is throw <trust level="Medium" /> into my Web.config so I can be sure my app will run on most hosts.
Usually, if I use the stock Microsoft stuff everything works without a problem. But tonight I was having problems following Brad Wilson's Webstack of Love presentation. All of my AJAX calls were returning a Server 500 error. However, when I would hit the WebAPI directly in the browser, it would return everything in XML format.
So I assume the serialization to JSON withing the WebAPI controller is what is causing the issue. My question is how to work around this?
It bothers me that Microsoft teaches shared hosts to play it safe and lock things down to Medium Trust, then creates new web technology that won't work in Medium Trust. Maybe everything will be fine when it is a final release and the binaries are installed in the GAC? It can take months for shared hosts to upgrade to the latest and greatest.
It seems like the biggest problem is usually Reflection--90%+ of the stuff I've tried that won't run on Medium Trust is due to this (For instance, I'd love to use AutoMapper instead of hand-coding ViewModel => Entity mappings). Is there a way to confine Reflection to the assemblies within an app so it can become part of the Medium Trust feature set and make this problem a thing of the past?
I set up Failed Request Tracing on IIS when I found that the Application_Error event wasn't even firing in my Global.asax. This is the exception being thrown. Not sure how to get any more details.
Warning -MODULE_SET_RESPONSE_ERROR_STATUS
ModuleName ManagedPipelineHandler
Notification 128
HttpStatus 500
HttpReason Internal Server Error
HttpSubStatus 0
ErrorCode 0
ConfigExceptionInfo
Notification EXECUTE_REQUEST_HANDLER
ErrorCode The operation completed successfully. (0x0)
Link to sample project displaying the issue. Also enclosed in the base "Test" directory are screenshots of my fiddler tests: XML-fiddle.png & JSON-fiddle.png.

Web API works just fine in medium trust. Also, since RC version, it 's not deployed to GAC anymore. You can just xcopy Web API dlls onto the server and reference them (or simply just publish your project from VS or git publish it if your host support it, like Azure).
You mention web stack of love. Well, it is SignalR that doesn't work in medium trust mode. See here - according to David Folwer, it won't anytime soon https://github.com/SignalR/SignalR/issues/364
Finally, if you are getting error 500s always add this to Global.asax
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
to receive verbose errors.

My problem had to do with the serializing of Entities with circular relationships (in this case Countries => States, State => Country). The JSON serializer was unable to handle this which led to a 500 error when requesting JSON.
I often use Entities directly for mocking things up and getting a prototype. I always planned on using distinct View Models anyway, but I wanted to understand what was going on and why it was failing.
Kiran Challa's answer in my ASP.net forums question helped me get the error that was occuring: "The RelationshipManager object could not be serialized. This type of object cannot be serialized when the RelationshipManager belongs to an entity object that does not implement IEntityWithRelationships."
That then led me to the Serializing Circular References with JSON.Net and Entity Framework on johnnycode.com.

Related

CurlResources Init null reference exception

I have a WebAPI .NET Framework 4.8 application which needs to make a RESTful GET request to another, third-party web service using a specific cipher. I found a code sample using the CurlThin NuGet packages in a response to this question, and then perused the little documentation on CurlThin I could find, along with taking a peek at the open source library code on GitHub. All examples and documentation talk about the need for an initial call to
CurlResources.Init();
This call only needs to be made a single time at the initialization stage to copy the appropriate DLLs to the application output folder.
I placed this call in my web app's Application_Start method, but cannot get past a NullReferenceException:
I fully expect that I am overlooking something simple that's been staring back at me for hours. Any guidance would be much appreciated.

All requests to ASP.NET Web API return 404 error

I have an ASP.NET MVC 4 web site that includes Web API. The site is developed and tested with Visual Studio 2012 and .NET 4.5 on Windows 8 with IIS Express as web server. In this development environment everything works.
Now it is deployed on a Windows 2008 R2 (SP1) Server with IIS 7.5. .NET 4.0 and 4.5 are installed. The application pool is running with .NET 4.0 in integrated pipeline mode.
In this production environment the MVC web site works, Web API does not. For every request, no matter if GET or POST I get a 404 error. If I just enter a Web API Url in the browser (IE 9 opened locally on the server) to run a GET request I get a 404 page. If I issue a POST request from a Web API client application I get a 404 as well and the message:
No HTTP resource was found that matches the request URI
I've created a test website with MVC 4 and Web API as well and deployed it on the same server and the Web API works. Web API and MVC assemblies have the same version number in both projects.
Furthermore I have added the Web API Route Debugger to the application. If I use a valid route like http://myserver/api/order/12 I get the following result:
For me this means that the correct route template Api/{Controller}/{Id} has been found and correctly parsed into a controller Order and Id=12. The controller (derived from ApiController) exists in the web assembly where also all MVC controllers are.
However, I don't know what the status 000 could mean and why there is no "Route selecting" section displayed (which is normally the case even if the assembly doesn't contain a single ApiController, see screenshots on the linked page above). Somehow it looks like no ApiController is found or even not searched for or the search fails silently.
The IIS log files don't show anything useful. Changing various application pool settings and using the same app pool for the test and the real application didn't help.
I am currently in the process to remove "features", configuration settings, third party assemblies, etc. from the application to bring it down to the small size of the test application in the end and hoping that at some point it starts to work.
Does somebody have a clue what the issue could be? Also any debugging or logging idea to possibly find the reason is very welcome.
Edit
Thanks to Darrel Miller's tip in the comments below I have integrated Tracing for ASP.NET Web Api.
For the (GET) request URL http://myserver/api/order/12 I get the following:
In development environment, successful (in short form):
Message: http://localhost:50020/api/order/12; Category:
System.Web.Http.Request
Controller selection and instantiation...
Operator: DefaultHttpControllerSelector; Operation: SelectController;
Message: Route="controller:order,id:12"; Category:
System.Web.Http.Controllers
Operator: DefaultHttpControllerSelector; Operation: SelectController;
Message: Order; Category: System.Web.Http.Controllers
Operator: HttpControllerDescriptor; Operation: CreateController;
Message: ; Category: System.Web.Http.Controllers
Operator: DefaultHttpControllerActivator; Operation: Create; Message:
; Category: System.Web.Http.Controllers
Operator: DefaultHttpControllerActivator; Operation: Create; Message:
MyApplication.ApiControllers.OrderController; Category:
System.Web.Http.Controllers
Action selection, parameter binding and action invocation follows...
Content negotiation and formatting for result...
Operator: DefaultContentNegotiator; Operation: Negotiate; Message: Typ = "String" ...
more
Disposing the controller...
Operator: OrderController; Operation: Dispose; Message: ; Category:
System.Web.Http.Controllers
In production environment, not successful (in short form):
Message: http://myserver/api/order/12; Category:
System.Web.Http.Request
Operator: DefaultHttpControllerSelector; Operation: SelectController;
Message: Route="controller:order,id:12"; Category:
System.Web.Http.Controllers
The whole part of controller activation, action selection, parameter binding, action invocation is missing and it follows content
negotiation and formatting for the error message immediately:
Operator: DefaultContentNegotiator; Operation: Negotiate; Message:
Type = "HttpError" ... more
Thanks to Kiran Challa's comment and source code from this answer I was able to figure out that an assembly (the ReportViewer 11 assembly for SQL Server Reporting Services) was missing on the production server.
Although no ApiController is in this assembly it seems to cause that controllers in assemblies - in this case my Web project's assembly - that are referencing the missing assembly are not found.
Apparently this behaviour is related to this piece of code from the Web API's DefaultHttpControllerTypeResolver source:
List<Type> result = new List<Type>();
// Go through all assemblies referenced by the application
// and search for types matching a predicate
ICollection<Assembly> assemblies = assembliesResolver.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
Type[] exportedTypes = null;
if (assembly == null || assembly.IsDynamic)
{
// can't call GetExportedTypes on a dynamic assembly
continue;
}
try
{
exportedTypes = assembly.GetExportedTypes();
}
catch (ReflectionTypeLoadException ex)
{
exportedTypes = ex.Types;
}
catch
{
// We deliberately ignore all exceptions when building the cache. If
// a controller type is not found then we will respond later with a 404.
// However, until then we don't know whether an exception at all will
// have an impact on finding a controller.
continue;
}
if (exportedTypes != null)
{
result.AddRange(exportedTypes.Where(x => IsControllerTypePredicate(x)));
}
}
I don't know if it has to be this way and I am not quite convinced by the comment in the code but this catch ... continue block is rather silent about a possible problem and it took me a huge amount of time and frustration to find it. I even knew that the ReportViewer wasn't installed yet. I tried to install it and dependent assemblies but it was blocked by another running process on the server, so I decided to postpone the installation until I could contact the administrator and focus on MVC and WebAPI testing first - big mistake! Without Kiran's debugging code snippet I had never had the idea that the existence of a ReportViewer.dll could have anything to do with controller type resolution.
In my opinion there is room for improvement for the average developer like me who doesn't have a deeper knowledge about the inner workings of Web API.
After installing the missing ReportViewer.dll the problem disappeared.
Here are questions about the same symptom which might have the same reason:
All ASP.NET Web API controllers return 404
.Net Web API No HTTP resource was found that matches the request URI
http://forums.asp.net/t/1861082.aspx/1?All+controllers+break+404+whenever+I+publish+to+Azure
Edit
I have issued a request for improvement on CodePlex:
http://aspnetwebstack.codeplex.com/workitem/1075
Edit 2 (Aug 11 '13)
The issue has been fixed for WebAPI v5.0 RC. See the link above to the workitem and its comments section for details.
Great resources in this answer, however, I was getting a 404 for what turned out to be a pretty silly reason:
I created a WiX installer for my API project
Installed it on a test VM (virtual machine)
Requested for the a URI that the API should serve
BANG! 404 :(
It turned out that I had missed packaging and deploying the Global.asax to the root of the virtual directory in my deployment. Adding this here for the benefit of goofies like myself :)
I had the same issue in a remote server, but when I execute on a localhost works fine.
My solution was:
<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0"
type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
</system.webServer>
I hope, that this works for you.

Why do ASP.NET resolve assembly references differently?

I really tried hard to find a similar issue to get some leads, but no one seems to describe the case we are having, so here it goes.
Background
We have a product with the following general design:
[Local installation folder]
Contains a set of .NET assemblies, implementing the bulk of our product functionality.
Example: Implementation1.dll, Implementation2.dll
[GAC]
ClientAPI.dll. Our client assembly, to be referenced from end user Visual Studio projects. Has strong references to the implementation dll's in the local installation folder.
In ClientAPI.dll, we have an entrypoint we require end user projects to invoke. Lets call it Initialize().
The very first thing we do in Initialize is to install a so called assembly resolve handler on the current domain, using the AssemblyResolve event. This handler will know how to locate the implementation dll's and load them into the client process, using Assembly.Load().
Consider a console application. It will look something like:
class Class1
{
void Main(string[] args)
{
ClientAPI.Initialize();
// Use other API's in the assembly, possibly internally referencing the
// implementation classes, that now will be resolved by our assembly
// resolve handler.
}
}
Now, all is good in the console/windows forms/WPF world. Our assembly resolve handler is properly installed and invoked, and it can successfully resolve references to the implementation DLL's once ClientAPI.dll require their functionality.
Problem statement
With that being said, we intend not to support only console or WPF applications, so we were relying on the same design in ASP.NET. Hence, creating a new ASP.NET Web Application project in VS 2010, we figured everything would be as straightforward as:
class Globals : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
ClientAPI.Initialize();
// ...
}
}
A few 20-30 hours of dwelling in the ASP.NET runtime universe, trying the above in both the development server and in IIS, we've learned that things there are not really as we expected.
It turns out that in ASP.NET, as soon as the ClientAPI class is referenced anywhere, all references it has to any other assemblies are instantly resolved. And not only that: the results are cached (by design, since .NET 2.0 we've found), meaning we never have a chance at all trying to assist the CLR.
Without further elaboration about the different things we've tried and learned, it basically comes down to this question we have:
Why is ASP.NET resolving references like this? It is not compatible with how other types of applications does it, and even more, it is not according to the documentation of .NET / the CLR runtime, specifying that references to external types / assemblies are to be resolve when first needed (i.e when first used in code).
Any kind of insight/ideas would be highly appreciated!
Windows Forms / WPF applications run on individual client machines (and therefore run in a single, local context), whereas ASP.Net runs within IIS, within an application pool, on a server or set of servers (in a web farm situation). Whatever is loaded in to the application pool is available to the entire application (and therefore is shared between all clients who connect to the application).
HttpApplication.Application_Start is executed once, when the application starts up. It is not executed per client as it would be with a Winforms application - if you need to initialize something for every client that connects, use Session_Start or Session_OnStart, but then you may run in to memory issues with the server, depending on how many clients are going to connect to your web application. This also depends on whether your class is a singleton, and if the Initialize() method is static. If you have either of those situations, you're going to run in to cross-threading problems fairly quickly.
Additionally, it's worth noting that an idle IIS application pool will reset itself after a period of time. If no one uses the web application overnight, for example, IIS will flush the application's application pool and free up memory. These settings can be changed within IIS administration, but you should be careful when doing so - changing these settings to circumvent a badly designed object (or an object that isn't designed for a web application) can create even more problems.
FYI - I'm being a little fussy, but for the avoidance of doubt, the object is not cached - yes, it is loaded in to memory, but how the memory is managed is up to how you've designed the object (caching in the web world is an entirely different thing, and can be implemented in many different layers of your application).
Don't try and make a web application act like a windows application; you'll just create yourself more problems!

ASP.Net MissingMethodException - "ctor" method not found

We are getting intermittent problems on a production server that we cannot recreate.
There are two very strange things about the issue. Firstly it's a method not found error on the constructor (ctor) for an exception handling helper class and secondly we have custom errors switched on for remote users and this property is being ignored.
The detail of the error is:
Server Error in '/MyWebsite' Application.
Method not found: 'Void MyExceptionHelperClass..ctor (System.Exception)'.
...
Exception Details: System.MissingMethodException: Method not found: 'Void MyExceptionHelperClass..ctor (System.Exception)'.
...
The stack trace is pretty unhelpful.
My thoughts are that there may be an out-of-memory error or something like that that is killing the page. When the exception handling code kicks in it tries to create an exception object which fails for the same reason giving this error.
However this is wild speculation. We are waiting for the event logs to see whether anything is amiss with the server but in the meantime does anyone have any thoughts or suggestions?
UPDATE:
It has proven difficult to get information out of the team responsible for the production servers but I have managed to find out that as far as load balancing is concerned, this site is currently only running on one server (this can be made to switch over onto another if necessary). Given that this is an intermittent problem and there is only one server involved, then I find it difficult to believe that this could be an assembly issue. Surely if it was then the problem would occur every time?
If you see this error happening on a site that has custom errors turned on, then the error is happening in the custom error handling routine itself.
From the look of the .NET error message it appears that your routine is expecting a constructor that accepts an exception by reference - your comment above shows a constructor that accepts by value.
Check carefully that there isn't a stale version of an assembly in your system somewhere. These can lurk in the Temporary ASP.NET Files folder; you'll need to do an "iisreset /stop" before you can clear them out.
In that regard it's always a good idea to make sure that AssemblyInfo.cs is set up to automatically stamp version numbers in some way. We have our version numbers tied to our source code repository system and CI build box so we can tell exactly what was in what assembly really easily.
I would use elmah: http://code.google.com/p/elmah/ to hopefully give you a bit more insight into the issue. It is free and can be used on an existing site without any recompilation. Try it - and post back if the issue is still happening.
As others have also mentioned, I would suspect that your site is somehow using an out of date version of an assembly. Something you could try doing is a full Precompile of your site before deploying to your production server. This ensures that ASP .Net doesn't dynamically compile the site on the fly, and therefore should mean that it's using completely up to date code throughout.
Do you have a no parameter public constructor defined for MyExceptionHelperClass in your code? Or is the class meant to only have static methods, in which case it should be a static class.
public class MyExceptionHelperClass()
{
public MyExceptionHelperClass() { }
}
Unfortunately, this may be one of those cases where the error message is of little to no value. In my experience, this general class of exception may be the result of either a configuration issue or bad logic aroung threading/app domains. For example, I have seen similar issues upon attempting to load the same assembly into an app domain more than once.
You mention that this is difficult to reproduce. If it's only happening on one server in the production farm it's more likely to be a config issue (with that machine). If it's happening on more than one server than it could be either config or threading.
It might be worth spending some time looking at the larger code base around the areas mentioned above. The root cause may not be in this class. Good luck!
I think it's a Framework issue with keeping compiled versions consistency. It's common to see same sort of errors while updating site sources repeatedly. Just try something like
net stop iisadmin /y && del /q /f /s "%systemroot%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\*.*" && iisreset
I encountered this exception today on a webforms page. I found a solution, but I'm not sure why it worked.
Nest the code behind in a 'Namespace [YourNamespace]' tag.
Add the namespace to the html Page tag's Inherits property in the aspx page 'Inherits="PathStart.YourNameSpace.ClassName"'.
Rebuild
Navigate to the page again and you should not encounter the exception.
After following the steps above I reverted the changes and did not re-encounter the exception.

Can Microsoft Code Contracts be used with an ASP.NET Website?

I'm currently using Microsoft Code Contracts in an ASP.NET MVC application without any issues but I can not seem to get it quite running in a basic ASP.NET Web site. I'm not entirely sure it was made to work with this type of project (although it shouldn't matter) so I wanted to bring it up to everyone.
I can compile the contracts just fine but the code skips over them since I'm assuming it hasn't been enabled through the Properties Page like you would do in other project types (ie ASP.NET MVC). I've gone to the property page of the project (which displays a dialog instead of the typical properties page) in my ASP.NET web site but it does not yield the same menu options and as such, doesn't have a section devoted to Code Contracts.
Also, I have Microsoft Code Contracts properly enabled within a class library project that I use to separate my business logic from the web site. The contracts compile fine but when a contract is violated, it throws a rather uninformative "Exception of type 'System.ExecutionEngineException' was thrown" error with no inner exception. My contract specifies a message to display upon violation but it is nowhere within the exception. It simply halts the execution of the process (which I believe is the default functionality for Microsoft Code Contracts).
I can't find anywhere that explicitly states that a particular project type can or can't (or shouldn't) be used with Contracts so I just wanted to see if anyone has had this issue.
Thanks for any help!
I had the same problem and this is how I solved it:
In the Referenced Class Libraries, right click -> properties -> code contracts.
Make sure "perform contract checking" is checked. I had mine set to "Full"
Contract Reference Assembly: make sure it is set to "Build"
Save your changes.
In the Referenced Class Libraries that have no contracts in their code, set the Contract Reference Assembly to "Do Not Build".
Then in the MVC project, have the Code Contracts "perform contract checking" checked. I had mine set to "Full".
Hope that helps somebody.
This sounds less like a Contracts and more like a build/config issue. Have you tried to deploy a prebuilt website? Are you sure that your website code sees the contracts code? Is the ASP.NET runtime using the CLR 4.0, or does it see the earlier Microsoft.Contracts.dll? Etc.

Resources