How do I form the URL to call this WebAPI function? - asp.net-mvc

I have this controller in an MVC 5 WebAPI application and I can't seem to figure out how to form the URL to call it. I keep getting a 404. tried .../ssa, /ssa/ssamedians, /ssa/ssamedians?titles=abc... What am I missing?
public class ssaController : ApiController
{
public IHttpActionResult getSsaMedians(string Titles = "")
{
SsaDB db = new SsaDB();
try
{
IEnumerable<Title_Medians> medians = db.getTitleMedians(Titles, null, null);
System.Web.HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
return Ok(medians);
}
catch
{
return NotFound();
}
}
There are also Actions called getSsaMediansByAaa() and getSsaMediansByBbb(). Once I got rid of the api/ in the routeTemplate, I now get a "Multiple actions were found that match the request".

Open your WebApiConfig.cs file and add this:
config.Routes.MapHttpRoute(
name: "SSATitles",
routeTemplate: "api/{controller}/{action}/{Titles}",
defaults: new { controller = "ssa", action = "getSsaMedians", Titles = UrlParameter.Optional }
);
For more information on webapi routing look here:
http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

You have an parameter in your method, that means that you need to add an extra link in your url.
Examlple.com/DirToApi/getSsaMedians/YourString
You may also want to check your RouteConfig file in your App_Start

Related

Redirect with ASP.NET MVC MapRoute

On my site, I have moved some images from one folder to another.
Now, when I receive a request for old images '/old_folder/images/*' I want to make a permanent redirect to new folder with these images '/new_folder/images/*'
For example:
/old_folder/images/image1.png => /new_folder/images/image1.png
/old_folder/images/image2.jpg => /new_folder/images/image2.jpg
I have added a simple redirect controller
public class RedirectController : Controller
{
public ActionResult Index(string path)
{
return RedirectPermanent(path);
}
}
Now I need to setup proper routing, but I don't know how to pass the path part to the path parameter.
routes.MapRoute("ImagesFix", "/old_folder/images/{*pathInfo}", new { controller = "Redirect", action = "Index", path="/upload/images/????" });
Thanks
I would do in next way
routes.MapRoute("ImagesFix", "/old_folder/images/{path}", new { controller = "Redirect", action = "Index" });
and in controller like that
public class RedirectController : Controller
{
public ActionResult Index(string path)
{
return RedirectPermanent("/upload/images/" + path);
}
}
first download and install RouteMagic package from this link , then redirect your old address to the new address Like the below code :
var NewPath = routes.MapRoute("new", "new_folder/images/{controller}/{action}");
var OldPath = routes.MapRoute("new", "old_folder/images/{controller}/{action}");
routes.Redirect(OldPath ).To(NewPath );
for more information please check out the following link
Redirecting Routes To Maintain Persistent URLs
Answer above using RouteMagic is a good idea, but the example code is wrong (it's included in Phil's post as a bad example).
From the RouteMagic Github demo site global.asax.cs:
// Redirect From Old Route to New route
var targetRoute = routes.Map("target", "yo/{id}/{action}", new { controller = "Home" });
routes.Redirect(r => r.MapRoute("legacy", "foo/{id}/baz/{action}")).To(targetRoute, new { id = "123", action = "index" });
If you specify two routes, you will be setting up an extra mapping that will catch URLs which you don't want.

How can i map all actions to C# class not ASP?

I want map all urls like /Home/User or /Home/About or /Home/Register or ... to c# page like this:
for example User.cs Page is like this:
public class User
{
public string run(UrlParameter id){
return "Hello World";
}
}
i want when user send request for /Home/User .. Call Run function of User Class and show return value to user. How can i do that in ASP MVC?
can i do this with change routes in RouteConfig? now current of my MVC routes is:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
and when i call some url program run an asp page in view folder as default of MVC Project in c#.net.
For more explains:
I have protocol between my client side and server side program that is JSON. i want return string JSON when client ask something and for do it i do not need to asp page for rendering html, i only need to call some function that return JSON to client.
How can i do that with MVC?
I'm assuming your question has two parts.
For the first part : Mapping a url to a page. This is in a sense what routing is. It maps a url to an action, which could be a page or maybe a resource like a picture, or a response like JSON data. Notice it's not always a page, generally a url maps to a resource.
Read the URL routing docs here:
routes.MapRoute(
name: "Default",
url: "/Page1",
defaults: new { controller = "Home", action = "Page1",
id = UrlParameter.Optional }
);
In the above example : fakedomain.com/Page1 will run the Page1 method on the HomeController class and if there isn't any code you've added in there it will search for a Page1.aspx or Page1.cshtml inside your views folder.
I would recommend at this point reading about REST. I suggest this article : How I explained REST to my wife
For your second part : How do you return JSON data. Well you use WebApi. See the docs here.
WebApi allows you to write controllers that return data based on the request. So if your client sends an Ajax request with accept headers set to application/json, WebApi will return JSON.
Also it follows the typical system of asp.net-MVC's controllers, routes and actions.
So to return JSON data that represents products you would have a ProductController that looks like this:
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup",
Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo",
Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer",
Category = "Hardware", Price = 16.99M }
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public Product GetProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
}
With asp.net-mvc4 and the default routing setup for WebApi the above controller would respond to the following URLs
This would get all products
/api/products/
This would get call the GetProductById and return ONE product:
/api/products/put_id_here
I would highly recommend getting all the pre-requisites like visual studio and asp.net-mvc from Web Platform installer and then follow this tutorial.

Issue while testing route entries using mvccontrib test helper in MVC4

I am trying to write test methods for Route entries and in my route config there were a lot of entries for different action. I am using MvcContrib.TestHelper for Testing . I am new to MVC as well as TDD. Kindly help me to solve this issue. My test case is failing and what can I do to make it pass .
Route Entry
routes.MapRoute(
name: "X1Details",
url: "X1/{X1ID}",
defaults: new { controller = "X1", action = "Index", X1ID = "X1ID" }
);
X1Controller
public ActionResult Index(int? instanceID = 0, string InfoMsg ="")
{
}
Test Method
[Test Method]
public void Should_Route_X1Index()
{
"~/X1/"
.ShouldMapTo<X1Controller>(action => action.Index(null, ""));
}
Error
Test method
XXX.Tests.MVCContibRouteMapTest.Should_Route_X1IndexOf
threw exception: MvcContrib.TestHelper.AssertionException: Value for
parameter 'InfoMsg' did not match: expected '' but was ''; no value
found in the route context action parameter named 'InfoMsg' - does
your matching route contain a token called 'InfoMsg'?
Thanks in advance.
I've found this approach to work, which should allow your controllers to remain the same
[Test Method]
public void Should_Route_X1Index()
{
var routeData = "~/X1/".Route();
routeData.Values["InfoMsg "] = "";
routeData.Values["instanceID"] = "0";
routeData.ShouldMapTo<X1Controller>(action => action.Index(0, ""));
}
Default values don't work well with MVCContrib helper. You could modify your controller action like so:
public ActionResult Index(int? instanceID, string InfoMsg)
{
...
}
and then:
"~/X1".ShouldMapTo<X1Controller>(action => action.Index(null, null));

ASPMvc Routing Issues with legacy url

I have got a legacy url that I cannot change, which is output on a page which needs to now post to a new MVC version of the page:
http://somesite.com/somepage?some-guid=xxxx-xxxx
Now I am trying to map this to a new controller but I need to get the some-guid into my controller:
public class MyController : Controller
{
[HttpGet]
public ActionResult DisplaySomething(Guid myGuid)
{
var someResult = DoSomethingWithAGuid(myGuid);
...
}
}
I can change the controller and routes as much as I like, however the legacy url cannot change. So I am a bit stumped as to how I can get access to the some-guid.
I have tried routing with the ?some-guid={myGuid} but the routing doesn't like the ?, so then I tried to let it autobind, but as it contains hyphens it doesn't seem to bind. I was wondering if there was any type of attribute I could use to hint that it should bind from a part of the querystring...
Any help would be great...
I would have thought you would have done a route a bit like this..
routes.MapRoute(
"RouteName", // Name the route
"somepage/{some-guid}", // the Url
new { controller = "MyController", action = "DisplaySomething", some-guid = UrlParameter.Optional }
);
The {some-guid} part of URL matches your url parmater and passes it to the controller.
So if you have your action like so :
public ActionResult DisplaySomething(Guid some-guid)
{
var someResult = DoSomethingWithAGuid(some-guid);
...
}
Give that a go and see how you get on..
routes.MapRoute(
"Somepage", // Route name
"simepage", // URL with parameters
new { controller = "MyController", action = "DisplaySomething"
);
And then in your controller:
public class MyController : Controller {
public ActionResult DisplaySomething(Guid myGuid)
{
var someResult = DoSomethingWithAGuid(myGuid);
...
}
}
Try this:
routes.MapRoute("SomePageRoute","Somepage",
new { controller = "MyController", action = "DisplaySomething" });
And then in your controller:
public ActionResult DisplaySomething() {
Guid sGuid = new Guid(Request.QueryString["some-guid"].ToString());
}

A bug in the routing engine for .NET?

I have an ASP.NET MVC application. In the application, I have a bunch of similarly structured routes for different actions:
/Admin/Addresses/{AddressId}/Delete
/Admin/Phones/{PhoneId}/Delete
/Admin/Notes/{NoteId}/Delete
/Admin/Files/{FileId}/Delete
None of which work... I have been checking the routes and the actions for 5 hours now, and I know they are all written the way they should be, but it's still 404ing all of them.
The funny thing is that the following routes, which are also similar in structure work just fine:
/Admin/Addresses/{Id}/{Type}
/Admin/Phones/{Id}/{Type}
/Admin/Notes/{Id}/{Type}
/Admin/Files/{Id}/{Type}
The only difference between the two sets is that the delete routes use GET and are supposed to return JSON, while the othere ones use POST and redirect.
Has anyone ran into this before?
EDIT: Here's a bigger code sample per the requests on the comments. First code sample is of the ONLY working route (which is probably because it's the first in the list of routes to use the specified url structure) and the second is the next route in line, which isn't working at all...
Routes.MapRoute("Administration (Delete Employee)", "Administration/Employees/{EmployeeId}/Delete", new {
controller = "Administration",
action = "DeleteEmployee"
});
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult DeleteEmployee(short EmployeeId) {
try {
db.DeleteEmployee(EmployeeId);
return Json(new IJsonStatus() {
Success = true
});
} catch (Exception ex) {
Shared.LogWarning(ex);
return Json(new IJsonStatus() {
Success = false,
Exception = ex.Message
});
};
}
And the non-working route:
Routes.MapRoute("Administration (Delete Address)", "Administration/Addresses/{AddressId}/Delete", new {
controller = "Administration",
action = "DeleteAddress"
});
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult DeleteAddress(int AddressId) {
try {
db.DeleteAddress(AddressId);
return Json(new BaseResponse() {
Success = true
});
} catch (Exception ex) {
Shared.LogWarning(ex);
return Json(new BaseResponse() {
Success = false,
Exception = ex.Message
});
};
}
Probably could be useful to see your entire route mapping call rather than just a snippet. That stuff is very, very order of operations dependent.
Second, check out the MVC routing debugger. It helps demystify alot of route mystification issues.
Often times HTTP POST is used to request delete actions. Are you using POST on these actions that are decorated with [AcceptVerbs(HttpVerbs.Get)] ?
Try mapping it more like this:
RouteTable.Routes.Add(new Route(
"Administration/Forums/{action}/{id}",
new RouteValueDictionary(new { controller = "Forums", action = "Index", id = "" }),
new MvcRouteHandler()));
RouteTable.Routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" });
I added the debugger and it matched two routes:
Administration/Notes/{Id}/{Type} <--POST
Administration/Notes/{NoteId}/Delete <--GET
So, I assume that it matched the post route because of the Id in it, which really stands for either CustomerId or EmployeeId because it's a unified action which diferentiates based on the Type.
However, I would have expected the /Delete on the second route to force it into the real route, but I guess it stops at the first matching parameter?

Resources