mvc5 attribute based routing not working - asp.net-mvc-5

I am using visual studio 2013 and created a default mvc project.In home controller I have modified the below
[RoutePrefix("home")]
[Route("{action=index}")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
//[Route("Home/About")]
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
In RouteConfig.cs I have done the following modification
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}/{id}",
// defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
//);
}
}
This is not working.But when I go for convention based routing it is working. Plz help me.

to make a web api create a WebApiConfig.cs :
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
}
}
}
in your global.asax :
GlobalConfiguration.Configure(WebApiConfig.Register);
and then you can define controller :
[RoutePrefix("home")]
public class HomeController : ApiController
{
[Route("action")]
public string myaction()
{
return "hello world";
}
}
this way the route /home/action will send back the defined string
now the big difference between WebApi and MVC is that you dont use your server side to Template and provide views, it is mainly used for REST actions: GET PUT POST DELETE
I don't know what you want to achieve but I hope this will be usefull
Edit:
I was thinking maybe you forgot to register your MVC routes in global.asax there should be a similar call to make like:
GlobalConfiguration.Configure(RegisterRoutes.routes);
something like that
and in your code try to change :
[RoutePrefix("Home")]
public class HomeController : Controller
{
[Route("Index")]
public ActionResult Index()
{
return View();
}
[Route("About")]
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
and routes should be /Home/Index and /Home/About

Related

MVC 5 ActionLink with Areas

http://localhost:55201/SERVICES/customers/CALLME
how to make this link using #Html.ActionLink
Services is RouteArea, Customers is RoutePrefix and Customer is Controller
#Html.ActionLink("Click me", "CallMe",new { area = "Services"})
is this code right? its returning blank anchor.
[RouteArea("Services")]
[RoutePrefix("Customers")]
public class CustomerController : Controller
{
[Route("~/Test")]
public ActionResult Index()
{
ViewBag.Controller = "Customer";
ViewBag.Action = "Index";
return View("ActionName");
}
[Route("CallMe")]
public string CallMeFunction()
{
return string.Format("CallMeFunction() invoked");
}
}

MVC 5 View from base controller (controller inheritance)

does anyone know how tell the child controller to load base (parent) controller view instead of looking for it in it's own folder?
public class BaseController : Controller
{
public virtual ActionResult Test()
{
return View("Test");
}
}
public class ChildController:BaseController
{
public override ActionResult Test()
{
return base.Test();
}
And the Error is The view 'Test' was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Child/Test.cshtml.....
So the solution that I found yeat is to make parent action looks like this
public class BaseController : Controller
{
public virtual ActionResult Test()
{
return View("~Views/Base/Test.cshtml");
}
}
Is there any better solution ?
private const string ViewPath = "~/Views/{0}/{1}.cshtml";
private ViewResult GetView(string action, object model = null)
{
var controllerName = ControllerContext.RouteData.Values["controller"].ToString();
var path = string.Format(ViewPath, controllerName, action);
return
new ViewResult
{
ViewName = path
};
}

MVC5 Dynamic route on the root

I want the following to urls to be mapped dinamically to the HomeController => Index with the segment variable...
www.site.com/one
www.site.com/two
public HomeController
{
[Route("{segment:string}")]//this wont work... 404
public ActionResult Index(string segment) //one or two
{
return View();
}
}
I think I managed to do it like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
// other routes
}
}
[RoutePrefix("")]
public class HomeController : Controller
{
[Route("{segment}")]
public ActionResult test(string segment)
{
return View();
}
}
and accessed the following urls:
http://localhost/TestWebApplication/segment1 -> goes to test action -> put segment = "segment1"
So, shortly put: make sure that attribute routing is enabled and skip the string constraint (I receive an error that is not recognized).

AmbiguousMatchException exception in ServiceStack?

PFB my code.
namespace ManualCSharpe
{
public class MyServices : Service
{
[Route("/L/hello/")] //RequestDTO one
public class HelloL
{
public string Name { get; set; }
}
[Route("/H/hello/")] //RequestDTO two
public class HelloH
{
public string Name1 { get; set; }
}
public class HelloResponse //ResponseDTO
{
public string Result { get; set; }
}
public class HelloServiceL : Service //Service One
{
public object Get(HelloL request)
{
return new HelloResponse { Result = "Low" };
}
}
public class HelloServiceH : Service //Service
{
public object Get(HelloH request)
{
return new HelloResponse { Result = "High" };
}
}
//Define the Web Services AppHost
public class AppHost : AppSelfHostBase
{
public AppHost()
: base("HttpListener Self-Host",new Assembly[] {typeof(HelloServiceL).Assembly, typeof(HelloServiceH).Assembly}) { }
public override void Configure(Funq.Container container) { }
}
//Run it!
static void Main(string[] args)
{
var listeningOn = args.Length == 0 ? "http://*:133/" : args[0];
var appHost = new AppHost()
.Init()
.Start(listeningOn);
Console.WriteLine("AppHost Created at {0}, listening on {1}",
DateTime.Now, listeningOn);
Console.ReadKey();
}
}
}
When I am tring to added two service then it is show below exception.
An unhandled exception of type 'System.Reflection.AmbiguousMatchException' occurred in ServiceStack.dll
Additional information: Could not register Request 'ManualCSharpe.MyServices+HelloL' with service 'ManualCSharpe.MyServices+HelloServiceL' as it has already been assigned to another service.
Each Request DTO can only be handled by 1 service.
I have below douts.
Here I have created two different DTO for Two Service. Why it is showing error like Each Request DTO can only be handled by 1 service. In simple word, Two route mapped with two DTO with two Service.
Can I create one route for multiple RequestDTO with multiple service? In Simple word, One Route/L/hello/ can be mapped with two DTO HelloL and HelloH.
You can't have Service class implementations nested inside another outer MyServices class:
public class MyServices : Service
{
[Route("/L/hello/")] //RequestDTO one
public class HelloL
{
public string Name { get; set; }
}
[Route("/H/hello/")] //RequestDTO two
public class HelloH
{
public string Name1 { get; set; }
}
public class HelloResponse //ResponseDTO
{
public string Result { get; set; }
}
public class HelloServiceL : Service //Service One
{
public object Get(HelloL request)
{
return new HelloResponse { Result = "Low" };
}
}
public class HelloServiceH : Service //Service
{
public object Get(HelloH request)
{
return new HelloResponse { Result = "High" };
}
}
}
Remove the outer MyServices class completely and just have the DTO's and Service classes directly under a C# namespace.
Also routes shouldn't end with a / suffix, so I'd change:
[Route("/L/hello/")]
to:
[Route("/L/hello")]
#mythz answer is correct for OP but I came here looking for an answer for a different situation which the cause was not particularly obvious - you will get this exception if you attempt to register the same assembly twice, for example, if you move a service implementation into the same assembly and were pulling it in like so:
public AppHost() : base("App", typeof(AdminService).GetAssembly(), typeof(InboundService).GetAssembly(),typeof(ProductService).GetAssembly())
For those of you who come here from a google search, a AmbiguousMatchException exception in ServiceStack can sometimes be triggered within ServiceStack but handled internally.
You can change your exception setting so it doesn't break on this exception.
I had changed my exception setting to break on all exceptions and this had me stuck for a while.

Service Stack Plug-in Not Addressable

I am trying to setup a modular ServiceStack implementation but I can't seem to figure out how to address my plug-in.
Here is my ASP.Net MVC 4 Global.asax.cs:
public class MvcApplication : System.Web.HttpApplication
{
[Route("/heartbeat")]
public class HeartBeat
{
}
public class HeartBeatResponse
{
public bool IsAlive { get; set; }
}
public class ApiService : Service
{
public object Any(HeartBeat request)
{
var settings = new AppSettings();
return new HeartBeatResponse { IsAlive = true };
}
}
public class AppHost : AppHostBase
{
public AppHost() : base("Api Services", typeof(ApiService).Assembly) { }
public override void Configure(Funq.Container container)
{
Plugins.Add(new ValidationFeature());
Plugins.Add(new StoreServices());
}
}
protected void Application_Start()
{
new AppHost().Init();
}
This loads fine and I'm able to see the available "HeartBeat" Service. The service loaded by the plug-in is not found though.
Here is the plug-in code:
public class StoreServices: IPlugin
{
private IAppHost _appHost;
public void Register(IAppHost appHost)
{
if(null==appHost)
throw new ArgumentNullException("appHost");
_appHost = appHost;
_appHost.RegisterService<StoreService>("/stores");
}
}
and the corresponding service that it loads:
public class StoreService:Service
{
public Messages.StoreResponse Get(Messages.Store request)
{
var store = new Messages.Store {Name = "My Store", City = "Somewhere In", State = "NY"};
return new Messages.StoreResponse {Store = store};
}
}
[Route("/{State}/{City}/{Name*}")]
[Route("/{id}")]
public class Store : IReturn<StoreResponse>
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string State { get; set; }
}
public class StoreResponse
{
public Store Store { get; set; }
}
The url to run heartbeat is from localhost}/heartbeat and the meta can be found at from localhost}/metadata.
When I try to call {from localhost}/stores/1234 though I get a unresolved route?, but if you see the route attribute on the service call it should resolve?
The following is the response I get for the stores request:
Handler for Request not found:
Request.ApplicationPath: /
Request.CurrentExecutionFilePath: /stores/123
Request.FilePath: /stores/123
Request.HttpMethod: GET
Request.MapPath('~'): C:\Source Code\White Rabbit\SpiritShop\SpiritShop.Api\
Request.Path: /stores/123
Request.PathInfo:
Request.ResolvedPathInfo: /stores/123
Request.PhysicalPath: C:\Source Code\White Rabbit\SpiritShop\SpiritShop.Api\stores\123
Request.PhysicalApplicationPath: C:\Source Code\White Rabbit\SpiritShop\SpiritShop.Api\
Request.QueryString:
Request.RawUrl: /stores/123
Request.Url.AbsoluteUri: http://localhost:55810/stores/123
Request.Url.AbsolutePath: /stores/123
Request.Url.Fragment:
Request.Url.Host: localhost
Request.Url.LocalPath: /stores/123
Request.Url.Port: 55810
Request.Url.Query:
Request.Url.Scheme: http
Request.Url.Segments: System.String[]
App.IsIntegratedPipeline: True
App.WebHostPhysicalPath: C:\Source Code\White Rabbit\SpiritShop\SpiritShop.Api
App.WebHostRootFileNames: [global.asax,global.asax.cs,packages.config,spiritshop.api.csproj,spiritshop.api.csproj.user,spiritshop.api.csproj.vspscc,web.config,web.debug.config,web.release.config,api,app_data,bin,obj,properties]
App.DefaultHandler: metadata
App.DebugLastHandlerArgs: GET|/stores/123|C:\Source Code\White Rabbit\SpiritShop\SpiritShop.Api\stores\123
This code doesn't does not give your service a url prefix like you're assuming:
_appHost.RegisterService<StoreService>("/stores");
Instead the optional params string[] atRestPaths only specifies routes for the DefaultRequest route of that Service. You can specify which operation is the default using the [DeafultRequest] attribute, e.g:
[DefaultRequest(typeof(Store))]
public class StoreService : Service { ... }
Which allows you to specify the routes in-line instead of on the request DTO, i.e:
_appHost.RegisterService<StoreService>(
"/stores/{State}/{City}/{Name*}",
"/stores/{Id}");
But as you've already got the routes on the Request DTO you can ignore them here, i.e:
_appHost.RegisterService<StoreService>();
But you'll need to include the missing /stores url prefix, e.g:
[Route("/stores/{State}/{City}/{Name*}")]
[Route("/stores/{Id}")]
public class Store : IReturn<StoreResponse> { .. }

Resources