T4MVC and just path without query parameters - t4mvc

Can I render a url without query parameters with T4MVC without using nullable ints?
public virtual ActionResult GetSchoolsForDistrict(int districtId)
{
return Json(_schoolsService.GetSchoolsByDistrict(districtId.Value), JsonRequestBehavior.AllowGet);
}

You should be able to call it without any parameters. e.g.
Html.ActionLink(MVC.Schools.GetSchoolsForDistrict())
This is because T4MVC always generates an overload with no parameters.

Related

Web Api Routing: Multiple controller types were found that match the URL for parameter VS constant paths

My issue is similar to Web Api Routing : Multiple controller types were found that match the URL but I want to keep them in separate controllers.
From the comments, 2 preexisting answers are good workarounds but do not solve the actual issue I'm trying to resolve.
The URLs I'm making up are similar to nested directories in a file system OR are very similar to Firebase URLs.
/BiggestSet/{BiggestSetCode}/Subset1/{Subset1Code}/SubsetOfSubset1/{SubsetOfSubset1}
... etc all the way down to where ever the tree stops. Think of it as a tree of data.
/Collection/{Instance}/Collection/{Instance}
The issue I have is that at the /Collection level I want to also provide specific collection level operations. Like Add and search and other collection specific Operations Collection/ProccessData
Collection Controller:
/Collection/Add
/Collection/ProcessDataOnTheColleciton
Instance Controller:
/Collection/{InstanceCode}
/Collection/{InstanceCode}/ProcessOnTheInstance
The problem I'm having is the Collection/ProcessData clashes with the instance Collection/{InstanceCode}
NOTE: 1 is an parameter and the other is a constant.
If you setup the controllers so that collection and Instance are in the same controller. the /{InstanceCode} doesn't clash with the /ProcessData
BUT
If you setup so the controllers are split into logical functions WebAPI gives the error Multiple controller types were found that match the URL.
Does anyone know how to modify attribute routing to somehow behave as if they are in the same controller OR to prioritize the constant over the parameter across controllers?
To keep two separate controllers and still have such routes you can use regular expression route constraints. This way you can specify for the instanceCode you accept everything except the actions from the other controller.
Here is a sample of how to configure routes like that:
public class CollectionController : ApiController
{
[HttpGet]
[Route("Collection/Add")]
public string Add()
{
return $"CollectionController = Collection/Add";
}
[HttpGet]
[Route("Collection/Process")]
public string Process()
{
return $"CollectionController = Collection/Process";
}
}
public class InstanceController : ApiController
{
[HttpGet]
[Route("Collection/{instanceCode:regex(^(?!Add$|Process$).*)}")]
public string Get(string instanceCode)
{
return $"InstanceController = Collection/{instanceCode}";
}
[HttpGet]
[Route("Collection/{instanceCode:regex(^(?!Add$|Process$).*)}/Process")]
public string Process(string instanceCode)
{
return $"InstanceController = Collection/{instanceCode}/Process";
}
}
Here is also a link to the post that explains the regular expression used in the sample.
An even better option would be if you have a specific format for the instanceCode and set the regular expression to accept only this specific format. Then you would not need to modify the regular expression for every new action added. I include also a link to the documentation for all available Route constraints. There you can see all the available options. For example if your instance code is a number you don't even need a regular expression you can just restrict with the int constraint like this [Route("Collection/{instanceCode:int}")].

Why does RedirectToAction have no effect

When the method with the barcode parameter is called, RedirectToAction has absolutely no effect. I can see that it does indeed return to that route in the URL, but the model is not refreshed and it displays stale data.
In the SQL Server profiler I can see that the call isn't being made to pull back the new data.
How can I force this to happen?
Incidently, the call to: public ActionResult SRScanItem(string barcode) is itself the result of a RedirectToAction from another controller.
I have handful of calls to RedirectToAction("SRPickCollectionItems") elsewhere in the same controller and these all work fine.
Any idea what may be causing this?
public ActionResult SRPickCollectionItems()
{
IEnumerable<ISRPickingItemSummary> items =
SRPickingItemsViewModel.
GetDisplayableChunk(ApplicationState.CollectionId.ToString(),
ApplicationState.AssistantNumber);
return View(items);
}
public ActionResult SRScanItem(string barcode)
{
DataLayer.Instance.AddStockroomFoundItem(barcode, ApplicationState.CollectionId, ApplicationState.AssistantNumber);
return RedirectToAction("SRPickCollectionItems");
}
Maybe the redirect is going to a cached page.
Could you try and decorate SRPickCollectionItems with
[OutputCache(Duration = 0)]
You don't seem to returning to a post method, only a get so it is not obvious how the method with the Redirect is getting called unless you are send the barcode as a query string parameter in a get call through an actionlink or link tag.
Normally you would have two methods named SRPickCollectionItems. The Get method (which you already have) loads the view and the post method (that you are missing) processes the postback. The post method would be thus...
[HttpPost]
public ActionResult SRPickCollectionItemsstring barcode){
DataLayer.Instance.AddStockroomFoundItem(barcode, ApplicationState.CollectionId, ApplicationState.AssistantNumber);
return RedirectToAction("SRPickCollectionItems");
}

Failed to Get Full URL in asp.net mvc3 it ignore #

how can i get folowing url
http://localhost:4847/Category/#pageindex=1
i failed to get full url using Request.Url.OriginalString
its only give me blocalhost:4847/Category
ignore other paramters. basically i want to get #pageindex=1 from this url
there is any other way to get (#pageindex=1)
Why are you using # ? Is it hardcoded ? Why not using Html helper methods to generate the Link urls ?
#Html.ActionLink("Category", "Index", new { pageIndex= "1"})
your query string should be like
http://localhost:4847/Category?pageindex=1
Your request for this page will be handled by an Action. So i guess, you should be able to get this as the parameter of that action method.
public ActionResult Index(string pageIndex)
{
//do whatver with pageIndex variable value here
}

ASP.Net Mvc 3 Url.Action method uses parameter values from previous request

When Urls are autogenerated using the Url.Action helper, if a page contains a line similar to
#Url.Action("Edit","Student")
is expected to generate a url like domain/student/edit and its working as expected.
But if the requested url contains some parameters, like domain/student/edit/210, the above code uses these parameters from the previous request and generates something similar even though I've not provided any such parameter to the Action method.
In short, if the requested url contains any parameters, any auto generated links of the page (served for that request) will include those parameters as well no matter if I specify them or not in the Url.Action method.
What's going wrong?
Use Darin's answer from this similar question.
#Url.Action("Edit","Student", new { ID = "" })
Weird, can't seem to reproduce the problem:
public class HomeController : Controller
{
public ActionResult Index(string id)
{
return View();
}
public ActionResult About(string id)
{
return View();
}
}
and inside Index.cshtml:
#Url.Action("About", "Home")
Now when I request /home/index/123 the url helper generates /home/about as expected. No ghost parameters. So how does your scenario differs?
UPDATE:
Now that you have clarified your scenario it seems that you have the following:
public class HomeController : Controller
{
public ActionResult Index(string id)
{
return View();
}
}
and inside Index.cshtml you are trying to use:
#Url.Action("Index", "Home")
If you request /home/index/123 this generates /home/index/123 instead of the expected /home/index (or simply / taken into account default values).
This behavior is by design. If you want to change it you will have to write your own helper which ignores the current route data. Here's how it might look:
#UrlHelper.GenerateUrl(
"Default",
"index",
"home",
null,
Url.RouteCollection,
// That's the important part and it is where we kill the current RouteData
new RequestContext(Html.ViewContext.HttpContext, new RouteData()),
false
)
This will generate the proper url you were expecting. Of course this is ugly. I would recommend you encapsulating it into a reusable helper.
Use ActionLink overload that uses parameters and supply null
You could register custom route for this action for example:
routes.MapRoute("Domain_EditStudentDefault",
"student/edit",
new {
controller = MVC.Student.Name,
action = MVC.Student.ActionNames.Edit,
ID = UrlParameter.Optional
},
new object(),
new[] { "MySolution.Web.Controllers" }
);
you then could use url.RouteUrl("Domain_EditStudentDefault") url RouteUrl helper override with only routeName parameter which generates url without parameters.

Weird behavior of urlrewriting in MVC3 with razor viewengine

I am working on a project which adopted ASP.NET MVC3(Razor) tech.
Now, I have a controller below:
public class Home: Controller
{
public ActionResult Result(string id)
{
return View(id);
}
}
and I have set MapRoute as below:
context.MapRoute(
"Home_result",
"Home/Result/{id}",
new { controller="Home", action = "Result"}
);
and it was suposed to display a View which named "Result" when I typed the url http://domain.com/Home/Result/abc123 in the browser. However it didn't.
Instead it gave me an exception below:
The view 'Result' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/abc123.cshtml
~/Views/Home/abc123.vbhtml
~/Views/Shared/abc123.cshtml
~/Views/Shared/abc123.vbhtml
It is strange isn't it?
Can anyone help me to figure out what mistakes I've made?
return View(id);
Returns a view with the name of ID's value (.cshtml), not the view with the name result.cshtml. I think this is because Id is a string. Are you trying to pass the id to the view?
To return the view matching the name of your controller's action simply use
return View();
If you want to pass that value to the view, for what ever crazy reason, using the viewbag is the easiest way since the string id is being used to declare a view name.
ViewBag.ID = id;
return View();
Then in the view just use the value you stored. And yes Razor HTML encodes by default.
#ViewBag.ID

Resources