views:

76

answers:

4

This is a strange one. I changed something (not sure what) and now my app's view doesn't compile at runtime.

The view itself is strongly typed:

<%@ Page Language="C#"
         MasterPageFile="~/Views/Shared/Site.Master"
         Inherits="System.Web.Mvc.ViewPage<MyNamespace.OperatorModel>" %>

When I visit the page, it fails to compile, saying:

CS1061: 'object' does not contain a definition for 'Log' and no extension method 'Log' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

Pretty standard error. The corresponding source code line is:

<%= Html.HiddenFor(model => model.Log) %>

When I look at the compiler-generated code, I see that the base class of the view is not strongly typed:

[System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
public class views_operator_create_aspx
    : global::System.Web.Mvc.ViewPage, // NOT STRONGLY TYPED
      System.Web.SessionState.IRequiresSessionState,
      System.Web.IHttpHandler {

So my question is, what is causing the view compiler to ignore my Inherits attribute on the view definition?

I should point out that other views on the same controller are working, and they have exactly the same page declaration as I've shown above.

EDIT Does anyone know where the generated source code file lives, assuming it is persisted somewhere?

EDIT I found the culprit (in my answer below) but I've no idea why this is happening. If someone can explain I'd appreciate it!

+1  A: 

Are you referencing the OperatorModel properly in your Web.Config? That will allow you to explicitly reference OperatorModel.

<namespaces>
    <add namespace="My.Namespace"/>

alternatively you could change your Inherits value to:

Inherits="System.Web.Mvc.ViewPage<My.Namespace.OperatorModel>"

Also, when passing a model object to the view, make sure you check for null or return an empty OperatorModel:

return View(operatorModel 
    ?? new OperatorModel() { Text = "I can has not found!" });
hunter
Thanks -- sorry I should have included the namespace in my question (I have modified the names by hand). Will edit. The model is definitely not null as I'm newing it in the call to `View(...)`.
Drew Noakes
In the end I found the cause of the problem, if not the solution. Any further ideas? http://stackoverflow.com/questions/3550244/asp-net-mvc-strongly-typed-view-compilation-error/3550857#3550857
Drew Noakes
+1  A: 

I find when I have totally weird errors like this, sometimes if I delete the shadow copy of all my files it will clear it up. You'll find it at:

%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files

Replace whatever version of the Framework you're using in that line above. Delete all the files that correspond to your project (or just delete everything in the directory).

You may have to shut down your w3p service to be sure it lets go of all the files and you can delete it.

Also, I believe you'll find the generated source code you're looking for in there.

CubanX
Useful info, and I'll use it in future, no doubt. In the end I found the cause of the problem, if not the solution. Any further ideas? http://stackoverflow.com/questions/3550244/asp-net-mvc-strongly-typed-view-compilation-error/3550857#3550857
Drew Noakes
+1  A: 

You didn't happen to delete that special, magical web.config file that lives in the root of your /Views folder, did you?

[This catches me at least once a month]

Wyatt Barnett
Nope that file is still intact, but cheers for the idea. In the end I found the cause of the problem, if not the solution. Any further ideas? http://stackoverflow.com/questions/3550244/asp-net-mvc-strongly-typed-view-compilation-error/3550857#3550857
Drew Noakes
A: 

Ok so I pared my view down to this:

<%@ Page Language="C#"
         MasterPageFile="~/Views/Shared/Site.Master"
         Inherits="System.Web.Mvc.ViewPage<MyNamespace.OperatorModel>" %>
<%@ Import Namespace="MyNamespace.Data" %>

<asp:Content ContentPlaceHolderID="MainContent" runat="server">
    <%= GetType() %><br />
    <%= GetType().BaseType %><br />
    <%= GetType().BaseType.BaseType %>
</asp:Content>

The output was, even with all content areas empty:

ASP.views_operator_create_aspx
System.Web.Mvc.ViewPage
System.Web.UI.Page

But if I remove the <%@ Import line, I get this:

ASP.views_operator_create_aspx
System.Web.Mvc.ViewPage`1[MyNamespace.OperatorModel]
System.Web.Mvc.ViewPage

I have no idea why the import should cause the page to no longer be strongly typed. Can someone explain? Any tips on how to debug or trace the compilation would be nice. It's great that I can keep coding now, but this isn't a very satisfying end to the problem.

Drew Noakes
try removing that Import and adding your namespace to your web.config
hunter
@hunter -- in the end, adding the namespace to `Web.config` worked around the problem. I would still like to know what caused the issue I was seeing though...
Drew Noakes
The issue was that you were binding that view to a class that it couldn't create the autogenerated code against. Once you added that namespace to the Web.config you were good to go. It was essentially adding the "using" statement for the namespace of the OperatorModel.
hunter
@hunter, do you mean `MyNamespace.OperatorModel`? Note that it's not in the namespace I was importing (`MyNamespace.Data`). In fact, ReSharper made my import statement go grey because it wasn't actually doing anything. Am I missing something?
Drew Noakes
as long as you've added the namespace that OperatorModel is in or referenced the namespace of OperatorModel in Inherits you should be good to go.
hunter
@hunter -- even without that namespace added it worked. The issue was related to an import statement that shouldn't have had any effect on the code, and even though nothing was being used, the T4 template (or something else) was deciding that the generated class for the view shouldn't derive from a generic ViewPage, and therefore the Model property was of type object.
Drew Noakes