MVC4 hosting views from other MVC project - asp.net

I am attempting to figure out how to host MVC4 apps that were built under different solutions. There are many examples of doing this on SO and on the web using the RazorGenerator nuget package with Areas - it works very well. In my situation, I want to avoid using areas - every application my company develops will be in it's own MVC4 project (then collectively in the same solution).
I've integrated RazorGenerator into my apps, the code gen is working as expected. However, my host solution can not find the View in it's default locations. As an example, I have a Controller/View built in one app called MyAccount/Index.
Controller:
namespace Accounts.Controllers
{
public class MyAccountController : Controller
{
//
// GET: /MyAccount/
public ActionResult Index()
{
return View();
}
}
}
View (as generated from RazorGenerator):
namespace Accounts.Views.MyAccount
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Web.Mvc.Html;
using System.Web.Routing;
using System.Web.Security;
using System.Web.UI;
using System.Web.WebPages;
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "1.5.4.0")]
[System.Web.WebPages.PageVirtualPathAttribute("~/Views/MyAccount/Index.cshtml")]
public partial class Index : System.Web.Mvc.WebViewPage<dynamic>
{
public Index()
{
}
public override void Execute()
{
#line 1 "..\..\Views\MyAccount\Index.cshtml"
ViewBag.Title = "Index";
#line default
#line hidden
WriteLiteral("\r\n\r\n<h2>Index</h2>\r\n\r\nMy AccountController Index view.");
}
}
}
I know that by default, the ViewEngines are going to try to find this view in the default locations (Views and Shared), so I added my own ViewEngine to the Engines collection:
MyViewEngine.cs:
public class MyViewEngine : RazorViewEngine
{
private static string[] _viewLocations
= new string[]
{
"~/Accounts/Views/{1}/{0}.cshtml"
};
public MyViewEngine()
{
base.ViewLocationFormats = ViewLocationFormats.Union(_viewLocations).ToArray();
}
}
However, the view still isn't found:
The view 'Index' or its master was not found or no view engine supports the searched locations.
The following locations were searched:
~/Views/MyAccount/Index.cshtml
~/Views/Shared/Index.cshtml
~/Views/MyAccount/Index.aspx
~/Views/MyAccount/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/MyAccount/Index.vbhtml
~/Views/Shared/Index.vbhtml
~/Accounts/Views/MyAccount/Index.cshtml
Maybe I am misunderstanding how the view is located -I had thought it would have been found in Accounts/Views/MyAccount/. Any ideas what I might be doing wrong?
Thanks!

Found my issue - it was due to not having the RazorGeneratorMvcStart warmup code in place. It is generated automatically into the App_Start folder when you add the nuget package, however I erroneously removed it.

Related

Dapper.Contrib methods unavailable for IDbConnection object

I am trying to use Dapper.Contrib to extend the functionality of the IDbConnection interface with, amongst others, the .insert() method.
To do so, I have followed the somewhat brief and scattered documentation here and here. In short, I have used NuGet to add Dapper and Dapper.Contrib to my project, I have added using Dapper; and using Dapper.Contrib; at the top of my Repository class, and I am using System.Data.SqlClient.SqlConnection() to create an IDbConnection.
Still, my connection object does not have the extended methods available. For example, when trying to use the .insert() method, I get the message:
'IDbConnection' C# does not contain a definition for 'Insert' and no
extension method 'Insert' accepting a first argument of type could be
found (are you missing a using directive or an assembly reference?)
This is in an ASP.NET Core 2.0 project using Razor Pages.
For completeness sake, you can find the Repository class below.
Maybe interesting to note, is that the using lines for Dapper and Dapper.Contrib are grayed out...
Also, of course I have a (very minimalistic) Model Class for the TEST Entity, containing one parameter, TEST_COLUMN, annotated with [Key].
using Dapper.Contrib;
using Dapper;
using Microsoft.Extensions.Configuration;
using TestProject.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
namespace TestProject.Repository
{
public class TEST_Repository
{
IConfiguration configuration;
public TEST_Repository(IConfiguration configuration)
{
this.configuration = configuration;
}
public void Insert()
{
using (var con = this.GetConnection())
{
con.Insert(new TEST { TEST_COLUMN = "test" });
}
}
public IDbConnection GetConnection()
{
return new SqlConnection(configuration.GetSection("ConnectionStrings").GetSection("DefaultConnection").Value);
}
}
}
The Insert method you are looking for lives inside of the Dapper.Contrib.Extensions namespace, as can be seen in the source, included for completeness:
namespace Dapper.Contrib.Extensions
{
...
public static long Insert<T>(this IDbConnection connection, ...)
...
}
Hence, in order to use the Extension methods, you should add the following line to your code:
using Dapper.Contrib.Extensions;

Umbraco 7: Reference / set path to views in separate folders

I've put all my Views in their own folders in Visual Studio and now the content is not rendering anymore. From where do I have to set the path for them to render?
Well, the convention is that Umbraco templates live in the ~/View folder. If they live anywhere else you loose the tooling support in the backoffice (and confuse any other Umbraco devs who pick up the project!).
However, provided the folder names match the names of the document types, you could create a controller for each of your document types (i.e. hijack the routing). I'm sure this would allow Umbraco to check in the subfolders.
I'm doing a multisite with single core Umbraco 7. Here's how I'm handling that at the moment:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Web.Mvc;
using Umbraco.Core.Logging;
namespace MyApp.UmbracoExtensions.Shared.Events
{
public class RegisterCustomViewEngine : ApplicationEventHandler
{
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ViewEngines.Engines.Add(new CustomViewEngine());
base.ApplicationStarting(umbracoApplication, applicationContext);
}
}
public class CustomViewEngine : RazorViewEngine
{
private static string[] NewViewFormats = new[] {
"~/Views/SomeFolder/{0}.cshtml",
"~/Views/AnotherFolder/{0}.cshtml",
"~/Views/Wiki/{0}.cshtml"
};
public CustomViewEngine()
{
base.ViewLocationFormats = base.ViewLocationFormats.Union(NewViewFormats).ToArray();
}
}
}

Connecting Web API to SQL Server

I am new to ASP.NET and I am creating a Web API using sort of code first. I have model class call gender and defined as follow
public class Gender
{
public int Id { get; set; }
public string Description { get; set; }
}
I decided to create a new folder call DBContext and inside will defined all my DBContext, so for the gender class I have created GenderDb and look like follow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace BackAPI.Models
{
public class GenderDB : DbContext
{
// not define yet
}
}
However I am having an issue however with DbContext not being defined, apparently I am supposed to use Entity Framework, however I want to create my database not through Visual Studio, but using SQL Server 2014 Express.
I did add my data connection and can see that I created a table in SQL Server, however how do I fix DbContext, if I use EF wouldn't that just create it locally and that not what I want
Entity Framework, along with Migrations, will help you here.
I suggest you check out this tutorial: Code First to a New Database

signalr server hub error

I'm trying to create a server and a asp.net client (2 projects in one solution..).
In the server in the class where the hub is defined i get an error ...
I use visual studio 2013.
this is the startup:
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(TestServer.Startup))]
namespace TestServer
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
}
the hub:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
namespace TestServer
{
[HubName("ServerHub")]
class ServerHub : Hub
{
public void Send(string message)
{
Clients.All.AddMessage(message);
}
}
}
it marks Clients.All.AddMessage(message) as an error : "One or more types required to compile a dynamic expression cannot be found. Are you missing a reference?" I can't understand what reference is missing.
You need to include the Microsoft.CSharp library.
It's easy to do, under the Add Reference dialog go to the Assemblies -> Framework tab. You'll see Microsoft.CSharp listed, add it.
Hope this helps!

C#/ASP.NET - Calling Web API operation via URL? : HTTP Error 500

I'm developing an ASP.NET MVC 4 application. Getting information from the database and displaying it on the webpage went well at this stage. Then I decided I'd like to develop a Web API as well side-by-side with my application's progress. So far so good, until I tried to test it using a URL on the local host.
When I tried it out, I got an HTTP Error 500.
I ran the application from VS 2010 and it opened up http://localhost:23375/ in my browser. At the end of this, I appended my API call, bringing it to:
http://localhost:23375/api/Performance/ShowMachines
When I hit enter, I get the error. Why is this so and how can I resolve it?
Here is the relevant code:
PerformanceController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using PerfMon.Models;
namespace PerfMon.Controllers
{
public class PerformanceController : ApiController
{
PerfMonDataRepository perfRep = new PerfMonDataRepository();
// GET /performance/machines
[HttpGet]
public IQueryable<Machine> ShowMachines()
{
return perfRep.GetAllMachines();
}
}
}
Global.asax.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace PerfMon
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "Machines",
routeTemplate: "api/{controller}/{action}",
defaults: new {
controller = "Performance",
action = "ShowMachines"
}
);
}
}
}
I'm running into the same problem and I think I narrowed it down to the Accept header of HTTP. When you make a call to the API via JavaScript passing the Accept header as JSON or XML it works.
When you make the call from the browser, you are asking for different content types, therefore you get an error 500.
I still couldn't confirm it, but looks like that.
The issue was that when I created the .dbml file, and dragged and dropped the table into it, the automatically generated DataContext class created EntitySet objects to represent the foreign-key relationships. I created simple classes with gets sand sets to return the JSON, rather than the classes in the DataContext, excluding the EntitySet objects. As a result, it worked like a charm. Apparently EntitySets are not serializeable, and thus were giving the 500 Error.

Resources