T4MVC and named parameters - asp.net-mvc

I'm running into an error with T4MVC and named parameters. I have a controller:
public class ProductsController : Controller
{
public virtual ViewResult List(int page = 1)
{
// foo.DoSomething()
}
}
It seems T4MVC creates an overload List() as well. The result is that calling
myProductsController.List(3)
correctly executes foo.DoSomething(). But calling
myProductsController.List()
does NOT execute foo.DoSomething() - T4MVC created an empty List() overload.
I've taken T4MVC out of my project, and everything works fine now. But I'd really like to be able to use it - am I missing a setting somewhere?

UPDATE: Ok, I have a real fix now. It's checked into the Codeplex repository. You can get the latest T4MVC.tt by going to here. Before I include that in the next official build, it would be great if you could try it and confirm that it works for you. Thanks!
You're right, there is a problem here. I had not run into this situation before. For a short term quick fix, just get rid of the following code from T4MVC.tt (around line 370):
<#foreach (var method in controller.ActionMethodsUniqueWithoutParameterlessOverload) { #>
[NonAction]
[<#= GeneratedCode #>, DebuggerNonUserCode]
public <#=method.ReturnTypeFullName #> <#=method.Name #>() {
return new T4MVC_<#=method.ReturnType #>(Area, Name, ActionNames.<#=method.ActionName #>);
}
<#} #>
But I'll need to look for a real fix. Normally, this generation happens when the action has no no-param overload. It just needs to detect that an action with all-optional params should basically be treated as a no-param case.

Related

Swagger - NotSupportedException: Ambiguous HTTP method for action

NotSupportedException: Ambiguous HTTP method for action - AAON.Insiite.Api.Controllers.TokenController.Get (AAON.Insiite.Api). Actions require an explicit HttpMethod binding for Swagger 2.0
I've read the several questions regarding this issue on SO but none of the solutions have worked.
I've tried:
Adding [HttpGet] to the method in question.
Adding [NonAction] to the method in question.
Changing access modifier of method to Protected.
Deleting the method still throws an exception for the now deleted method.
Cleared Visual Studio Cache
I've tried clearing my visual studio cache but to no avail.
[HttpGet]
public IActionResult Get()
{
return Ok("Running");
}
According to #Crumblenautjs answer, I had a similar problem with the custom routing convention. After debugging for a while I discovered that also RouteAnalyzer_Main (which is used by swagger to define routes) routes are being replaced together with "my" controllers.
My solution is to skip Apply when RouteAnalyzer occurs, at least works for my solution.
public void Apply(ControllerModel controller)
{
if (controller.ControllerName == "RouteAnalyzer_Main")
{
return;
}
}
The issue was a controller naming convention. Solved.

Telerik grid export functionality, issue with ToGridModel()

I have included Telerik.Web.Mvc assembly and still not able to get ToGridModel() method for export function.
Below are some details about my code
Html.ActionLink(" ", "ExportData", new {..})
public ActionResult ExportData(...)
{
}
issues in code
Not able to define variable with IEnumerable xxx (giving error as it required 1 argument)
Not able to call ToGridModel() method.
Can anybody guide me how should i do this? what I am missing?
Make sure you've brought the extension method into scope by adding the proper using directive pointing to the namespace in which this extension method is defined:
using Telerik.Web.Mvc.Extensions;

Use object in Route with PlayFramework : Reverse routing

Is it possible to generate an url mapped by an object ?
The Pojo Object Mapping is a native function of PlayFramework (1.2.2), but what about the reverse routing?
I would like to do this :
Java:
class MyControler extends Controller {
public static function myAction(MyObject o) {}
}
Route: (something like this ? If it's possible, i don't know the syntax to do it !)
GET /folder/{myObject.name}/{myObject.id} MyController.myAction(myObject)
Template :
Go
Expected result :
Go
(I have a Symfony background, and I search an equivalent to the Object Route Class)
I think Play! don't support this functionnaly, could someone confirm or refute this idea?
Thank you.
What you’re asking for is not currently possible.
So the usual workaround is this pattern:
GET /folder/{id} MyController.myAction
class MyController extends Controller {
public static void myAction(Long id) {
MyObject o = MyObject.findById(id);
// You may probably want to add the following line:
notFoundIfNull(o);
// … then your code here
}
}
The solution is not so verbose, but I agree that further version of Play! should allow a more simple syntax, similar to what you suggested.
Well, if it is going to work, it will need the package declaration :
GET /folder/{models.myObject.name}/{models.myObject.id}
According to Julien Richard-Foy, there is no solution.
So I propose a workaround, a little ugly because the route will be describe twice.
This quick solution breaks the MVC model, but it's possible to do otherwise, sending a UrlHelper to the template for exemple.
In your model, add a generateUrlDetail() method :
public String generateUrlDetail() {
return String.format("/myRoute/%s/%d-%s.html", JavaExtensions.slugify(this.foo.name), this.id, JavaExtensions.slugify(this.bar));
}
Tips : Play! allows to define a route with more identifiers than necessary. So it's possible to write a route with 2+ variables, but only the ID will be used in the action.
GET /myRoute/{foo}/{<[0-9]+>id}-{bar}.html Foo.detail(id)
And in your template :
Go
Render : Go
And it works :)
Try this approach. Bind with the id of the object. Works for me
Go

Difficulty to start up with basic unit test (Sample from my book -- SportsStore)

I'm really new in TDD and, actually, I'm trying to follow the sample from my book (SportsStore -- Pro ASP.NET MVC Framework/Steve Sanderson/APRESS). I'm on pages 103-105.
Although there are more on this, as new to all of this, I'm concerned with the following statements.
ProductsController controller = new ProductsController(repository);
var result = controller.List(2);
//...
regarding the above statements, when I write this (as in the book),
var products = result.ViewData.Model as IList<Product>;
I get a compiler error "System.Web.MVC.ActionResult" does not contain a definition for ViewData ..." But, when I remove the List() from the statement, then the compiler error disapear.
var result = controller.List(2);//Doesn't work
var result = controller;//It works
Is something wrong there? I checked Apress website for that book, but there is nothing listed as Errata or issue. So I'm really lost.
Thanks for helping
That is because actionresult does not contains a definition for viewdata howerver viewresult does and viewresult is actually an actionresult so you can cast it to (ViewResult) and then get the viewdata
var products = ((ViewResult)result).ViewData.Model as IList<Product>;
you may also be missing System.Web.Mvc library from your test project
Alternatively you can change the code in your Products Controller from:
public *Action*Result List()
{
return View(productsRepository.Products.ToList());
}
to:
public *View*Result List()
{
return View(productsRepository.Products.ToList());
}
ViewResult is a subclass of the base class ActionResult.

Why do none of my ActionFilters run?

I asked a question earlier today about ActionFilters in ASP.Net MVC. It turned out my problem was really that my ActionFilter is not even running. Among other things I read this article, and I can't find anything he does that I don't.
This is my code:
// The ActionFilter itself
public class TestingIfItWorksAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.TempData["filter"] = "it worked!";
base.OnActionExecuting(filterContext);
}
}
// The Controller Action with the filter applied
[TestingIfItWorks]
public ActionResult Test()
{
var didit = TempData["filter"];
return View();
}
A breakpoint in the filter method is never hit when I debug, and TempData["filter"] holds a null value when the view is rendered.
Why is this not working?
In case it's helpful to anyone using MVC 4/5:
ActionFilters don't run if you get the namespace of your ActionFilterAttribute or IActionFilter wrong: https://stackoverflow.com/a/13710468/188926
Use System.Web.Http.Filters for Web API, System.Web.Mvc for standard MVC actions.
As in the question, the filter attribute will simply be ignored (no error) if you get it wrong, which makes it difficult to diagnose.
Based on your comments to another answer
When testing via unit tests, the filter is not invoked. If you want to invoke the filter then you'll need mimic the ControllerActionInvoker. It's probably better, to test the filter itself in isolation, then use reflection to ensure that the filter is applied to your action with the correct attributes. I prefer this mechanism over testing the filter and action in combination.
Original
Surely you need an override on your method otherwise you aren't actually replacing the method on the base class. I would have expected the compiler to complain that you needed either a new or override on it. If you don't include the override keyword, it will behave as if you used new. Since the framework invokes it as an ActionFilterAttribute, this means that your method will never get called.
Quoting from MSDN:
If the method in the derived class is
not preceded by new or override
keywords, the compiler will issue a
warning and the method will behave as
if the new keyword were present.
In addition to what tvanofosson said, your action method isn't actually rendering anything to the view. Does your view have a <%=TempData["Filter"].ToString()%> statement or something similar?

Resources