I'm trying something new (to me) in using an abstract base class for my layout viewmodel.
The problem is that when I run the site as is, it throws a very cryptic (to me) exception. What does this exception mean, and what might I do to resolve it?
Layout
#model MyApp.Core.ViewModels.LayoutViewModel
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>#Model.Title</title>
</head>
<body>
<div>
#RenderBody()
</div>
</body>
</html>
Index
#model MyApp.Core.ViewModels.Home.IndexViewModel;
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>#Model.Body</h1>
LayoutViewModel
namespace MyApp.Core.ViewModels
{
public abstract class LayoutViewModel
{
public string Title { get; set; }
}
}
IndexViewModel
namespace MyApp.Core.ViewModels.Home
{
public class IndexViewModel : LayoutViewModel
{
public string Body { get; set; }
}
}
Controller
[HttpGet]
public ActionResult Index()
{
var model = new IndexViewModel
{
Title = "Hello World",
Body = "Hello World"
};
return View(model);
}
And the Exception
Compilation Error Description: An error occurred during the
compilation of a resource required to service this request. Please
review the following specific error details and modify your source
code appropriately.
Compiler Error Message: CS1003: Syntax error, '>' expected
Source Error:
Line 27:
Line 28:
Line 29: public class _Page_Views_Home_Index_cshtml :
System.Web.Mvc.WebViewPage<FutureStateMobile.Core.ViewModels.Home.IndexViewModel;>
{
Line 30:
Line 31: #line hidden
Source File: c:\Users\Chase\AppData\Local\Temp\Temporary ASP.NET
Files\root\b314e0d7\36f522db\App_Web_index.cshtml.a8d08dba.yr7oemfz.0.cs
Line: 29
Compare and contrast:
Layout
#model MyApp.Core.ViewModels.LayoutViewModel
Index
#model MyApp.Core.ViewModels.Home.IndexViewModel;
Got it yet? Here's the answer:
one of them has a ; which shouldn't be there
I just add the line twice, and deleted... problem solved!
#model MyApp.Core.ViewModels.LayoutViewModel
#model MyApp.Core.ViewModels.Layout_OrOther_Model
Try to compile, you get an error (only one model blah, blah..)
Delete one of them.
#model MyApp.Core.ViewModels.LayoutViewModel
Compile.
That works for me!
bad:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<DSNY.Core.Interfaces.IUser>" %>
versus
good:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<DSNY.Core.Interfaces.IUser>>" %>
Compiler kept telling me it was expecting an extra >.
Related
I have the following constants defined as follows:
namespace MyProject.Constants
{
public static class AppConstants
{
// View Bag / Temp Data Constants
public const string CurrentAction = "CurrentAction";
public const string CurrentController = "CurrentController";
}
}
In my _layout.cshtml file I am setting them as follows:
#using MyProject.Constants
#{
TempData[AppConstants.CurrentAction] = ViewContext.RouteData.GetRequiredString("action").ToLower();
TempData[AppConstants.CurrentController] = ViewContext.RouteData.GetRequiredString("controller").ToLower();
}
<!DOCTYPE html>
<html>
...
<body>
#Html.Partial("_SubNavigation")
</body>
</html>
But I'm unable to access the TempData inside my _SubNavigation.cshtml partial view:
<li>Home</li>
I get error The name 'AppConstants' does not exist in the current context
If I add the following snippet directly inside the partial then it works?
#using MyProject.Constants
#{
TempData[AppConstants.CurrentAction] = ViewContext.RouteData.GetRequiredString("action").ToLower();
TempData[AppConstants.CurrentController] = ViewContext.RouteData.GetRequiredString("controller").ToLower();
}
I get error The name 'AppConstants' does not exist in the current context
Without the snippet you quote, does you partial view start with
#using MyProject.Constants
?
This is needed in every view that references names in that namespace, and for any other namespaces you need. If you need a namespace is a significant proportion of your views consider adding it to the global namespaces list in the web.config file in the Views folder.
to all, I realy need help. I am new in SolrNet and beginer in asp.net mvc 4. My project is to use SolrNet and view results in web app created in asp.net mvc 4. So, for begin I whant to just do simple query from SolrNet and display it in web,
So far I have create this:
Start new empty MVC project with name: SOLRTest
From Package Manager Console I have done this: Instal-Package SolrNet -Version 0.4.0-beta2
In HomeController i use this code:
using System;
using System.Web.Mvc;
using Microsoft.Practices.ServiceLocation;
using SOLRTest.Models;
using SolrNet;
namespace SOLRTest.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
try
{
var solr = ServiceLocator.Current.GetInstance<ISolrReadOnlyOperations<Customer>>();
SolrQueryResults<Customer> rezultati = solr.Query(new SolrQueryByField("customer", "INTS"));
return RedirectToAction("Index", "Home");
}
catch (Exception ex)
{
string error = ex.Message;
}
return View();
}
}
}
In Models i use this code:
using SolrNet.Attributes;
namespace SOLRTest.Models
{
public class Customer
{
[SolrField("customer")]
public string customer { get; set; }
}
}
In View i use this code:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<%# Import Namespace="SOLRTest.Helpers" %>
<%# Import namespace="SOLRTest.Models" %>
<!DOCTYPE html>
<html>
<body>
<div>
test
</div>
</body>
</html>
<% foreach (var izpis in SOLRTest.Models.Customer)
{ %>
<li>
<ul>
<%= Html.SolrFieldPropName<Customer>(izpis) %>
</ul>
</li>
<% } %>
For Helpers I use this code:
using System.Web.Mvc;
using Microsoft.Practices.ServiceLocation;
using SolrNet;
namespace SOLRTest.Helpers
{
public static class HtmlHelperMapperExtensions
{
private static IReadOnlyMappingManager mapper
{
get { return ServiceLocator.Current.GetInstance<IReadOnlyMappingManager>(); }
}
public static string SolrFieldPropName<T>(this HtmlHelper helper, string fieldName)
{
return mapper.GetFields(typeof(T))[fieldName].Property.Name;
}
}
}
And finaly in Global.asax I use this to connect to server:
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using SOLRTest.Models;
using SolrNet;
namespace SOLRTest
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
Startup.Init<Customer>("http://service...local:8080/solr/msglog_pilot...");
}
}
}
Errors which I get is:
Server Error in '/' Application.
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS0119: 'SOLR4.Models.Customer' is a 'type', which is not valid in the given context
Source Error:
Line 12: </body>
Line 13: </html>
Line 14: **<% foreach (var izpis in SOLR4.Models.Customer)**
Line 15: { %>
Line 16: <li>
How to write correct code for View in MVC4, and also is my code for simple query in Controller correct.
Please help. Thanks for ideas.
Daniel
<% foreach (var izpis in SOLRTest.Models.Customer)
{ %>
<li>
<ul>
<%= Html.SolrFieldPropName<Customer>(izpis) %>
</ul>
</li>
<% } %>
SOLRTest.Models.Customer is a type, not a variable. You cannot foreach over a Type. Change your foreach to loop over your actual model variable.
You are not returning your model from your controller either.
I am working with MVC4.
When I cause an exception the information is shown in the browser.
How can I get the exception information in an exception assistant instead?
Thanks for any suggestions.
You can use Exception Handling in Global.asax:
protected void Application_OnError( )
{
var exception = Server.GetLastError( );
//handle exception here
}
You can also use Exception filters:
There is a method 'RegisterGlobalFilters()' having 'filters.Add(new HandleErrorAttribute())' filter that deals with all the errors in MVC application. The method 'RegisterGlobalFilters()' called by 'Application_Start()' method.
public static void RegisterGlobalFilters(GlobalFiltersCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
Error View
The Error view that is created by default contains the following HTML:
Collapse | Copy Code
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Error</title>
</head>
<body>
<h2>
Sorry, an error occurred while processing your request.
</h2>
</body>
</html>
Accessing the exception details in Error view:
public class HandleErrorInfo
{
public HandleErrorInfo(Exception exception, string controllerName,
string actionName);
public string ActionName { get; }
public string ControllerName { get; }
public Exception Exception { get; }
}
Check this link for further information :
Exception Handling in ASP.NET MVC
PD:
Set in web.Config:
<CustomErrors mode="Off">
to stop watching the exception in browser
Create an Error Controller with several methods (each method is an error) :
public Class Error : Controller
{
public ActionResult ErrorMethodName()
{
return View();
}
}
In each ErrorName.cshtml, write informations about your error.
Now for each Method in your other Controllers do this :
public ActionResult MethodeName()
{
try
{
// your code
}
catch (exception)
{
return.RedirectToAction('ErrorMethodName','Error');
}
}
I started up a Default MVC 4 project using the ASPX engine (not Razor), and everything works fine.
I can use
<% Model.Name %>
and
<% Model.Rating %>
for book ratings (instead of the Restaurant Review that is up on the asp.net/mvc tutorials site). However, my code errors on the
<% ViewBag.Message %>
...so for some reason, when inheriting from the "BookReviewer" Class within the BookReview model, I can view the Model information but not the Viewbag? Am I missing something? Code below.
[Controller]
HomeController.cs:
public class HomeController : Controller
{
var model = new BookReview()
{
Name = "Pro jQuery For Noobs",
Rating = 7
};
return View(model);
}
[Model]
BookReview.cs
namespace Bookreview.Models
{
public class BookReview
{
public string Name { get; set; }
public int Rating { get; set; }
}
}
[View]
Index.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<BookRevew.Models.BookReviewer>" %>
<asp:Content ID="indexFeatured" ContentPlaceHolderID="FeaturedContent" runat="server">
<h2>
<% ViewBag.Message %>
<% Model.Name %>
<% Model.Rating %>
</h2>
</asp:content>
As we can see by your comments, you are setting the ViewBag.Message in another controller. The ViewBag is only for data for the view that was set by the controller that served the view.
If you need to send it from another controller, you should use a parameter in your action method, then you can set the ViewBag.Message to the passed in parameter.
I have implemented exception handling using below code.[Edited Start] I do not know why it is calling view twice. [Edited Done]
Basecontroller
public class BaseController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.IsCustomErrorEnabled)
{
filterContext.ExceptionHandled = true;
if (filterContext.Exception.GetType() == typeof(ArgumentOutOfRangeException))
{
this.View("OutOfRange").ExecuteResult(this.ControllerContext);
}
else
{
this.View("Error").ExecuteResult(this.ControllerContext);
}
}
base.OnException(filterContext);
}
}
HomeController
public class HomeController : BaseController
{
public ActionResult Exception2()
{
throw (new ArgumentOutOfRangeException());
}
public ActionResult Exception3()
{
throw (new Exception());
}
}
Error View (Shared folder only)
#model System.Web.Mvc.HandleErrorInfo
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
</head>
<body>
<h2>
Sorry, an error occurred while processing your request.
</h2>
<h3>
#if (Model != null)
{
<p>#Model.Exception.GetType().Name<br />
thrown in #Model.ControllerName #Model.ActionName</p>
<br />
#Model.Exception
}
</h3>
</body>
</html>
OutOfRange view (Shared folder only)
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>OutOfRange Exception</title>
</head>
<body>
<div>
<h3>
#if (Model != null)
{
<p>#Model.Exception.GetType().Name<br />
thrown in #Model.ControllerName #Model.ActionName</p>
<br />
#Model.Exception
}
</h3>
</div>
</body>
</html>
Execution URL : http://[domainName]/Home/Exception2
Here it is working fine. [EDITED : Here it also call twice.]
Execution URL : http://[domainName]/Home/Exception3
Here it is not working fine. You can see that "Sorry, an error occurred while processing your request." is coming twice. When I debugged the application using above URL, Error view called twice ( First time Model is null and second time Model contains some value). May I know what is wrong with my implementation?
Things to try:
Remove the default HandleError global action filter attribute from your Global.asax if it is present. When you create a new ASP.NET MVC 3 application the default template registers it inside the RegisterGlobalFilters method. So comment out the line which registers this attribute.
Enable custom errors in your web.config:
<customErrors mode="On" />
UPDATE:
If you want to pass a model to the Error.cshtml view (as it is strongly typed to HandleErrorInfo) you could do the following:
else
{
string controllerName = filterContext.RouteData.GetRequiredString("controller");
string actionName = filterContext.RouteData.GetRequiredString("action");
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
var result = new ViewResult
{
ViewName = "Error",
ViewData = new ViewDataDictionary<HandleErrorInfo>(model)
};
filterContext.Result = result;
}
Add base.OnException(filterContext); before
if (filterContext.HttpContext.IsCustomErrorEnabled)
protected override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
if (filterContext.HttpContext.IsCustomErrorEnabled)
}
I had the same problem, but I managed to resolve the error by adding:
Response.End();
To the end of my OnException method.
I know it's not the ideal resolution, but, it did at least get me out of a bind until such a time as I can investigate a more complete option.