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

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.

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();
}
}
}

MVC4 hosting views from other MVC project

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.

ASP.NET Membership.FindUsersByName not working. Can't search for users. 404's

When I use this action and go to Profile/Username, it gives me a 404 even though the name exists. I've used Membership.GetNumberOfUsersOnline().ToString(); and that works just fine, returning the amount of users online correctly. I understand that if this code worked properly, it would just return a basic webpage, but it's not even doing that, I get a 404. What gives? Help is greatly appreciated! :)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
namespace MvcMicroBlog.Controllers
{
public class ProfileController : Controller
{
//
// GET: /Profile/
public ActionResult Index(string Profile)
{
Membership.FindUsersByName(Profile);
return View();
}
}
}
Unless you have a custom route defined, you should go to /Profile/?Profile=username, or you can rename your Profile parameter to id.
If you prefer the custom route approach, you can add this to your RegisterRoutes method in Global.asax.cs, before the Default route:
routes.MapRoute(
string.Empty,
"Profile/{Profile}",
new { controller = "Profile", action = "Index" }
);

How to debug ASP.NET MVC3 app that throws error and doesn't hit breakpoints in global.asax?

I just spent time tonight converting an existing ASP.NET webform app to MVC3 using this guide. However, when I go to start the app just to running the app locally to check my work, I'm getting this error:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its
dependencies) could have been removed, had its name changed, or is
temporarily unavailable. Please review the following URL and make sure
that it is spelled correctly.
Requested URL: /
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.237
I've tried setting various breakpoints in my global.asax as I suspected I screwed something up with the routing but the breakpoints aren't hit at all. Since it's not hitting my breakpoints in this file then my assumption is that I don't need to both looking at the Controller or View since that's further down the execution path.
My folder structure contains the following folders and files:
Controllers\
HomeController.cs
Models\
Views\
Home\
Index.cshtml
Shared\
_Layout.cshtml
Error.cshtml
_ViewStart.html
Global.asax
web.config
web.config
Here's the contents of the global.asax:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace www
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//ignore aspx pages (web forms take care of these)
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}", // URL with parameters
// Parameter defaults
new { controller = "Home", action = "Index"}
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
}
\Controllers\HomeController.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace www.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
}
I'm relatively new to ASP.NET MVC and Visual studio so not sure where to begin debugging this. Any tips would be appreciated.
Based on a reply by Mystere Man, the answer was that global.asax was mistakenly put under the \Views\ folder and not in the root. Once I moved it, all was well.

Resources