Git Product home page Git Product logo

attributerouting's People

Contributors

antonmoiseev avatar benbenbenbenbenben avatar captaincodeman avatar danielfurze avatar davidboike avatar filipw avatar gregmac avatar jsclayton avatar jskimming avatar kamranayub avatar kenny-evitt avatar leoasis avatar lordriffraff avatar mccalltd avatar patridge avatar phillip-haydon avatar shawncarr avatar waynebrantley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

attributerouting's Issues

A potentially dangerous Request.Form value was detected from the client

Hi Tim,

Due to the dynamic nature of my application. I am unable to utilize the attribute [AllowHtml] on a model property to get a Request.Form value with an unsafe value.

Here is an example form
<form action="/Home/Save" method="post">
<textarea name="txt">
<b>Hello Html Tags</b>
</textarea>
<input type="submit" value="submit" />
</form>

I have two scenarios to accept the post. One without and one with AttributeRouting.

The first scenario works without AttributeRouting [project: Unvalidated.csproj]
[HttpPost]
public ActionResult Save()
{
string value = Request.Unvalidated().Form["txt"];
return View("Success");
}

This AttributeRouting version errors [project: ValidateInputFalse.csproj]
[POST("Home/Save")]
public ActionResult Save()
{
string value = Request.Unvalidated().Form["txt"]; // ERROR
return View("Success");
}

Here is the stack trace

A potentially dangerous Request.Form value was detected from the client (txt=" Hello Html Tags</...").

[HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (txt=" Hello Html Tags</...").]
System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection) +8855748
System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, RequestValidationSource requestCollection) +122
System.Web.HttpRequest.get_Form() +150
System.Web.HttpRequestWrapper.get_Form() +11
AttributeRouting.Extensions.MvcExtensions.GetHttpMethod(HttpRequestBase request) in C:\Development\AttributeRouting\src\AttributeRouting\Extensions\MvcExtensions.cs:16
AttributeRouting.RestfulHttpMethodConstraint.Match(HttpContextBase httpContext, Route route, String parameterName, RouteValueDictionary values, RouteDirection routeDirection) in C:\Development\AttributeRouting\src\AttributeRouting\RestfulHttpMethodConstraint.cs:27
System.Web.Routing.HttpMethodConstraint.System.Web.Routing.IRouteConstraint.Match(HttpContextBase httpContext, Route route, String parameterName, RouteValueDictionary values, RouteDirection routeDirection) +22
System.Web.Routing.Route.ProcessConstraint(HttpContextBase httpContext, Object constraint, String parameterName, RouteValueDictionary values, RouteDirection routeDirection) +56
System.Web.Routing.Route.ProcessConstraints(HttpContextBase httpContext, RouteValueDictionary values, RouteDirection routeDirection) +150
System.Web.Routing.Route.GetRouteData(HttpContextBase httpContext) +215
System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +287
System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +60
System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +86
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

Also, I have uploaded a solution which contains the scenarios above. (sorry for the confusing project names).
https://skydrive.live.com/embedicon.aspx/Public/AttributeRouting^_InputValidation.zip?cid=e7737d00ff5b25e9&sc=documents

Thank you
Mike

AttributeRouting and T4MVC

Hello,

I am setting Attribute Routing (I installed the package) on a MVC 3 and I have the following:

namespace MVCSite.Areas.CMS.Controllers {

public partial class RoleController : Bontroller {

[GET("Roles")]
public virtual ActionResult Index() {
return View();
} // Index

}
}

And I have the following on my Home/Index view (I am using T4MVC):
@Html.ActionLink("Test", MVC.CMS.Role.Index());

But it renders as:
Test

Instead of
Test

I also tried to type on the URL CMS/roles but I keep having the 404 error.

What am I missing?

Thank you,
Miguel

Url from resources

Hello,

Can you an optioin to read to value for the url from a resource file?

GET and POST Action result

Hi Tim, First, thank you for an awesome project.

The issue I am having is that when the user fills in and posts a form, on error, I return them to the same form to allow them to correct their mistake by passing back the model. Onsuccess I redirect.

However, I get an error "A public action method '_Control' was not found on controller 'AttributeRoutingTest.Areas.Admin.Controllers.NewsController'." This is because it appears I need both GET and POST verbs to cater for the above POST and redirect(GET) in the save method.

I have uploaded a sample project to my sky drive:
https://skydrive.live.com/embedicon.aspx/Public/AttributeRoutingTest.zip?cid=e7737d00ff5b25e9&sc=documents

Here is some sample code.

Note the RenderAction
-- VIEW
@using (Html.BeginForm("Save", "News", new { area = "Admin" }, FormMethod.Post)) { <h2>Edit</h2> Html.RenderAction("_Control", "News", new { area = "Admin", controlId = "category", currentValue = "1" }); <br /> <input type="submit" value="Save" /> }

-- CONTROLLER: I have set it up for both get and post as per the following save action

[POST("News/_Control/{controlId}/{currentValue}")]
public ActionResult _Control(string controlId, int? currentValue)
{
    return PartialView("_Control");
}```

-- SAVE ACTION

[POST("News/Save")]
public ActionResult Save()
{
bool saveErrored = true;

if (saveErrored)
    return View("Edit"); // with model so previous values can be filled back in, allowing the user to make any corrections.
else
    return RedirectToAction("Index");

}```

thank you very much,
Mike

Possible testing bug with AR and HttpMethod?

Hi Tim,

I've been playing with AR in some xUnit tests/facts .. and i've had some problems with trying to retrieve a list of routes for a particular context.

eg. routes.GetRouteData(httpContext);

So after debugging a lot, i finally came across this bit of AR code..

class: mvcExtensions, line 14

public static string GetHttpMethod(this HttpRequestBase request)
{
    return request.SafeGet(r => r.Headers["X-HTTP-Method-Override"]) ??
            request.SafeGet(r => r.GetFormValue("X-HTTP-Method-Override")) ??
            request.SafeGet(r => r.GetQueryStringValue("X-HTTP-Method-Override")) ??
            request.SafeGet(r => r.HttpMethod, "GET");
}

Now, becuase i'm in a TEST class, I need to mock my context stuff, like the request. Kewl. What I wasn't (read: forgot) to mock was the HttpMethod property. When I mocked that property to return "GET", then everything worked again. Kewl :)

So my question is this .. should that last line in the above code snippet do a check for string.IsNullOrEmpty(HttpMethod) ? "GET" : HttpMethod ?

(What made me lead to this was that I notice the stack trace was giving me a First Chance Null Exception in AR .. somewhere .. and i -think- this is where it might have happened?)

Or maybe i've not set up my AR attribute(s) right?

Here's a sample attribute :-

[GET("1.0/location")]
public JsonResult ..... 

so yeah .. thoughts?

Translation Provider: Problem with RouteUrl and Actions with Optional parameters

Hello,

I have the following action:

[GET("Users")]
public virtual ActionResult Index(Int32 p = 1) {
}

When I add a translation I get the following:

AddTranslations().ForController<UserController>()
  .RouteUrl(x => x.Index(), new Dictionary<String, String> { 
     { "pt", "Utilizadores" } 
});

I get the following error:

An expression tree may not contain a call or invocation that uses optional arguments

Any idea how to solve this?

Thank You,
Miguel

AttributeRouting.xml locked

Hello,

A minor issue is I find the file AttributeRouting.xml is locked by devenv.exe

This is an issue because it is preventing a backup script from completing. It appears to have been introduced in v1.

The location of the file is Solution\Packages\AttributeRouting.1.0.30808\lib\net40\AttributeRouting.xml

While I can work around this; i thought it would be worth mentioning because it may not be by design that the resource is not being released.

thank you,
Mike

Multiple Params With Route Defaults/Optionals

I have the following AR (Example 1)

        public ActionResult _CenterImage(Guid? guid_Gallery, bool? slideShow, string currentController, string image)```

Due to a javascript construction of the action like this:
```        var action_CenterImage = '@Url.Action(GalleryRoutes.RouteAction("", "Gallery", "_CenterImage"))'
            .concat('/', guid_Gallery, '/False/', controller);

The action returns blank.

To rectify the problem, I create a AR like this. (Example 2)

        [GET("Gallery/_CenterImage", Order = 2)]
        public ActionResult _CenterImage(Guid? guid_Gallery, bool? slideShow, string currentController, string image)

Are my nullable params incorrect because i thought the the first AR example would cater for both situations. Thanks

No default document, found?

Hi :)

i'm trying to use this with a pretty small website.

It's a single ASP.NET MVC3 project. When I run my site, I only get an IIS 404.20 error -> no default document found.

I commented out the default route which is auto created inside the stock RegisterRoutes global.asax method.

This is when i try and goto the route www.foo.com/ <-- notice there's no controller/actionMethod

do i need to define that default route, somewhere?

cheers!

Route registration doesn't work in Mvc 3 project without bindingRedirect 2.0.0 => 3.0.0

When using the "routes.MapAttributeRoutes();" from my test project I got an empty RouteCollection. It was solved by copying the assemblyBinding element in the Web.config to an App.config file in my test project.

I'm using Mvc3 and obviously everything works fine when I run the web application because the Web.config has the redirect by default:

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
                <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

Obviously not a bug per se, and I am unsure whether there are any reasonable ways to solve this automagically for users. But it did take some time to figure out nevertheless. Perhaps it could be added to the docs?

ConstrainTranslatedRoutesByCurrentUICulture in 1.6

Hello,

I just installed version 1.6 and have the following configuration:

  RouteTable.Routes.MapAttributeRoutes(x => {
    x.ScanAssembly(Assembly.GetExecutingAssembly());
    x.AddDefaultRouteConstraint(@"^id$", new RegexRouteConstraint(@"^\d+$"));
    x.AddTranslationProvider<RouteTranslationProvider>();
    x.ConstrainTranslatedRoutesByCurrentUICulture = true;
    x.UseLowercaseRoutes = true;
    x.UseRouteHandler(() => new CultureRouteHandler());        
  });

I defined only one culture PT. I tried to access the URL "pt/cms/home/index" and it worked fine.
But when I type in the URL "en/cms/home/index" it goes to the PT version!

Shouldn't a 404 error fire? I have set "x.ConstrainTranslatedRoutesByCurrentUICulture = true"

My CultureRouteHandler is the following:

public class CultureRouteHandler : MvcRouteHandler {

    private const String _culture = "culture";

    protected override IHttpHandler GetHttpHandler(RequestContext context) {
      Thread.CurrentThread.CurrentCulture = new CultureInfo("pt");
      Thread.CurrentThread.CurrentUICulture = new CultureInfo("pt");
      context.RouteData.Values[_culture] = culture;
    }
    return base.GetHttpHandler(context);
  } // GetHttpHandler  

} // CultureRouteHandler

Thank You,
Miguel

Multiple Translation Providers

Hello,

I have been using the new Translation Provider and it is great. I have one suggestion:

At the moment, if I am not wrong, it is only possible to use one translation provider:

routes.MapAttributeRoutes(config =>
{
    config.AddRoutesFromController<TranslationController>();
    config.AddRoutesFromController<TranslationWithCustomKeysController>();
    config.TranslationProvider = translations;
});

I think it would be useful to have many TranslationProviders. For example:

RouteTranslationProvider
AreaXYZRouteTranslationProvider
...

In this case I have the global translation provider and one specific for the routes in one area.

This helps not only on organization, and area portability, but also avoid namespaces issues.
For example, usually there are main controllers and area controllers with the same name.

And some people might want to have a AreaLocalizationProvider, ActionLocalizationProvider, ...

I would suggest something as Profiles in Automapper:

  Mapper.Initialize(x => {
    x.AddProfile<MapperProfile>();
    x.AddProfile<AreaXYZMapperProfile>();
  });

So it would becomes something like:

routes.MapAttributeRoutes(config =>
{
    config.AddRoutesFromController<TranslationController>();
    config.AddRoutesFromController<TranslationWithCustomKeysController>();
    config.AddTranslationProvider<RouteTranslationProvider>;
    config.AddTranslationProvider<AreaXYZRouteTranslationProvider>;
});

What do you think?

Thank You,
Miguel

Weird behavior by Html.ActionLink

Hi,

I added a GET route via attribute (pretty simple /show/{user})

But when using Html.ActionLink, it refused to work and appended ?Length=4 instead of the value I tried to put there using RouteValueDictionary.

Only after adding the fourth parameter (html attributes object) it worked as expected.

Any idea why it works this way?

Thanks

Add CodeTemplates

Add MVC2 and MVC3 CodeTemplates for generating MVC-style and RESTful-style controllers with actions decortated with RouteAttributes. Also add templates for generating RESTful method-compatible views.

parameters automatically filled when using Html.ActionLink

Hi,

I'm not sure if it's a bug with MVC or with AR, this is what happens: I'm using a controller with this pattern /show/{id}/{?param1}.
Then I create a link under the same view to the same controller only without the param1 parameter, but it is still filled by Html.ActionLink and I get wrong routes to that controller (that include this param).

It does work if I add new {param1 = ""} to every link, but that's not very convenient.

Thank you

Localization Needed

Hello Tim,

I am using Attribute Routing on a CMS I develop and I have a few questions.

1 - CONVENTIONS

  I am planning to use the RestfulRouteConvention but I have a few questions:      

  A) Do you consider Post / Index as Post / List?
       Or it can be just the "entry" page?


  B) Instead of:

       Edit โ€” GET ControllerName/{id}/Edit     (Post/34/Edit)

       Wouldn't be better to have:

       Edit โ€” GET ControllerName Pluralized/{id}/Edit     (Posts/34/Edit)

       Reference: http://edgeguides.rubyonrails.org/routing.html

       You pluralize the controller or add an attribute to the controller? 

       I suppose both can be used, correct?


 C) I see that all forms must have the HttpMethodOverride.

       I need to a "Delete" link in each row of a table. How would you do it?

       Maybe using Ajax? But can I do the HttpVerbs.Delete?

        $('table.Data a.Delete').click(function (e) {
          e.preventDefault();
          if (confirm("Delete this item?")) {
            $.ajax({ type: 'POST', url: $(this).href });
          };
        });

2 - SLUG IN URLs

  I would like to have friendly slugs on the URLs. A few options:


  A) posts/124/learn-about-attribute-routing         (SLUG = TITLE)

       In this case when the TITLE / SLUG changes I will not have broken links.

       This is because the post is retrieved using the ID.

       The only problem is if the title is changed I get 2 URLs indexed to the same page:

         OLD: posts/124/learn-about-attribute-routing

         NEW: posts/124/learn-about-mvc

       I think this is penalized by Search Engines. In fact, aren't you penalized when using:

        [GET("", Order = 1)]
        [GET("Posts", Order = 2)]
        [GET("Posts/Index", Order = 3)]
        public void Index()
        {
           return View();
        }

        You have multiple routes to the same page.


  B) posts/124-learn-about-attribute-routing        (SLUG = ID + TITLE)

       In this case when the TITLE / SLUG changes I will have broken links.

       That is a problem worse then the previous one.


  On both cases the Slug is saved on the Database when creating the post ...

  ... probably it is better then creating it on the fly. What do you think?

  Which approach would you use?

  And is this compatible with Restfull convention?

3 - LOCALIZATION

  We already talked about localization before. In fact created a branch when we talked.

  After reading and researching a lot I think there is a better approach.


  (A) Use different Country Top Level domains for each version.

       ENGLISH: www.domain.com;     PORTUGAL: www.domain.pt;    FRANCE: www.domain.fr

      "At the SMX Confernece in Sydney Australia, Priyank Garg and Greg Grothaus, Yahooโ€™s and 
       Googleโ€™s search engineers, shared some issue:

       If you use multiple country domains (ccTLD), even if content is in the same language (identical content) 
       on all of your localized sites (for instance you have it all in English, as it commonly happens with USA, 
       UK and Australia), you will not experience any duplicated content issues / penalties. This is true for both 
       Google and Yahoo, however, you might get some penalty if you abuse this feature (spammy sites) and 
       if you donโ€™t localize your site properly."


  (B) If Top Level domains are not available then use sub domains.

        ENGLISH: en.domain.com;     PORTUGAL: pt.domain.com;    FRANCE: fr.domain.com


   HOW IT WORKS

   When a page is requested the MVC application detects the domain of the request and sets the culture.


   ADVANTAGES     

   The portuguese version is indexed by Google.pt, the french version by Google.fr, etc.

    I did a search for MSN in Google.com, Google.pt and Google.fr and in fact I got:

    www.msn.com, pt.msn.com and fr.msn.com.


    ISSUES

    A route translation would be necessary to do the following:

    - Go from "www.domain.pt/contacto" to "www.domain.com/contacto"

    - Go from "www.domain.pt/post/ola-mundo" to "www.domain.com/post/hello-world"          

    The problem is that for the last route the title can change ...

    And in fact a post can have no translation so it would be redirected to home/index or other defined route.

    I am not sure if the best option would be to have a table to hold routes.

    What do you think?

Cheers,
Miguel

'System.Web.WebPages' not found on MVC2

I've been reading through the documentation and while it was never stated somewhere explicitly, I assume that AttributeRouting should also work for MVC 2 projects? I've just started using it and keep getting the error: "Could not load file or assembly 'System.Web.WebPages, Version=1.0.0.0' or one of its dependencies."

I saw this entry in your changelog: "Used System.Web.WebHelpers to sniff the form and querystring collections hanging off the request for an http method override without triggering request xss validation", and when I looked it up, it appears that System.Web.WebHelpers is defined in System.Web.WebPages.dll. Is there any way around this? I can't switch to MVC 3 due to restrictions of my host.

Thanks!

Parameters in Index action

Hello,

I am defining a base route system for a CMS using Attribute Routing and I have the following:

[GET("users/page/{page=1}")]
public virtual ActionResult Index(Int32 page) {
  return View();
} // Index

I am displaying "users/page/1" to because "users/1" is Users > Show.

If I need to filtrer users by Age and define a Sort Direction and Field I could use:

[GET("users/age/{age=10}/page/{page=1}/field/{field=username}/direction/{direction=asc} ")]
public virtual ActionResult Index(Int32 page, Int32 age, String field, String direction) {
  return View();
} // Index

So I would get:

"users/age/10/page/1/field/username/direction/asc"

Does this make sense? Or should I use only something like:

"users?age=10&page=1&field=username&direction=asc"

I could also pass some of the parameters inside the model.

But I think having them on the url is better.

Thank You,
Miguel

AR Bug. Posted the Stack Trace.

Hello,

On a project where I use Attribute Routing I have the following action:

[POST("Files"), Authorize(Roles = "Master"), ValidateAntiForgeryToken]
public virtual ActionResult Create(FileNewModel model) {
}

When I submit an Image with 80 KB everything works fine.
But when I submit a Video with 6 MB I get the following error:

"Maximum request length exceeded"

STACK TRACE:

at System.Web.HttpRequest.GetEntireRawContent()
at System.Web.HttpRequest.GetMultipartContent()
at System.Web.HttpRequest.FillInFormCollection()
at System.Web.HttpRequest.get_Form()
at System.Web.HttpRequestWrapper.get_Form()
at AttributeRouting.Helpers.HttpRequestBaseExtensions.GetFormValue(HttpRequestBase request, String key) in C:\Development\AttributeRouting\src\AttributeRouting\Helpers\HttpRequestBaseExtensions.cs:line 13
at lambda_method(Closure , HttpRequestBase )
at AttributeRouting.Helpers.ObjectExtensions.SafeGet[T,TResult](T obj, Expression1 memberExpression, TResult defaultValue) in C:\Development\AttributeRouting\src\AttributeRouting\Helpers\ObjectExtensions.cs:line 17 at AttributeRouting.Helpers.ObjectExtensions.SafeGet[T,TResult](T obj, Expression1 memberExpression) in C:\Development\AttributeRouting\src\AttributeRouting\Helpers\ObjectExtensions.cs:line 10
at AttributeRouting.Helpers.MvcExtensions.GetHttpMethod(HttpRequestBase request) in C:\Development\AttributeRouting\src\AttributeRouting\Helpers\MvcExtensions.cs:line 16
at AttributeRouting.RestfulHttpMethodConstraint.Match(HttpContextBase httpContext, Route route, String parameterName, RouteValueDictionary values, RouteDirection routeDirection) in C:\Development\AttributeRouting\src\AttributeRouting\RestfulHttpMethodConstraint.cs:line 26
at System.Web.Routing.HttpMethodConstraint.System.Web.Routing.IRouteConstraint.Match(HttpContextBase httpContext, Route route, String parameterName, RouteValueDictionary values, RouteDirection routeDirection)
at System.Web.Routing.Route.ProcessConstraint(HttpContextBase httpContext, Object constraint, String parameterName, RouteValueDictionary values, RouteDirection routeDirection)
at System.Web.Routing.Route.ProcessConstraints(HttpContextBase httpContext, RouteValueDictionary values, RouteDirection routeDirection)
at System.Web.Routing.Route.GetRouteData(HttpContextBase httpContext)
at AttributeRouting.Framework.AttributeRoute.GetRouteData(HttpContextBase httpContext) in C:\Development\AttributeRouting\src\AttributeRouting\Framework\AttributeRoute.cs:line 61
at System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext)
at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context)
at System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Any idea? This seems to be a bug.

Thank You,
Miguel

For consideration: Add explicit support for globalized routes

Hi,

First off, this is a great library. Thanks so much for the investment of time and effort... very well put together.

Earlier this week I spent a bunch of time faffing around with culture switching based on locale route parameters. Any thoughts on adding some defaults into your library to help with this?

I'm a little crunched for time right now, but if you think it's a good idea, I wouldn't mind throwing a few hours towards a nice implementation.

Thanks again,

...brent

Routing to subdomains

It would be a great nice to have if AttributeRouting allowed routing to a subdomain. Haven't found any code that currently does that in the project.

If you are planning something to add this, or need any help it would be nice to aid in this feature.

I think at least it should be implemented at a RouteArea level, something like:

[RouteArea("admin", Subdomain="admin")]

Or specifying both prefix and subdomain:

[RouteArea("admin", Subdomain="internal", AreaUrl="admin")]

Let me know your thoughts on this feature.

GetHttpMethod() uses Unvalidated() which cannot be used in unit tests.

The most recent release of AttributeRouting updated the GetHttpMethod extension method to be defined as:

public static string GetHttpMethod(this HttpRequestBase request)
{
    return request.Headers["X-HTTP-Method-Override"] ??
        request.Unvalidated().Form["X-HTTP-Method-Override"] ??
        request.Unvalidated().QueryString["X-HTTP-Method-Override"] ??
        request.HttpMethod;
}

The use of the Unvalidated() method prevents this code from being executed in a unit test. A null reference exception will be thrown because the Unvalidated() method tries to access HttpContext. For example:

var context = new HttpContextMock(requestPath: "shorturl/test");
var routes = new RouteCollection();
routes.MapAttributeRoutes(config => config.ScanAssemblyOf<MyController>());
RouteData routeData = routes.GetRouteData(context);

That will throw an exception with the following stack trace:

System.NullReferenceException : Object reference not set to an instance of an object.
at Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.CollectionReplacer.GetUnvalidatedCollections(HttpContext context)
at System.Web.Helpers.Validation.Unvalidated(HttpRequest request)
at AttributeRouting.Extensions.MvcExtensions.GetHttpMethod(HttpRequestBase request) in C:\Development\AttributeRouting\src\AttributeRouting\Extensions\MvcExtensions.cs: line 17
at AttributeRouting.RestfulHttpMethodConstraint.Match(HttpContextBase httpContext, Route route, String parameterName, RouteValueDictionary values, RouteDirection routeDirection) in C:\Development\AttributeRouting\src\AttributeRouting\RestfulHttpMethodConstraint.cs: line 27
at System.Web.Routing.Route.ProcessConstraint(HttpContextBase httpContext, Object constraint, String parameterName, RouteValueDictionary values, RouteDirection routeDirection)
at System.Web.Routing.Route.ProcessConstraints(HttpContextBase httpContext, RouteValueDictionary values, RouteDirection routeDirection)
at System.Web.Routing.Route.GetRouteData(HttpContextBase httpContext)
at System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext)

I am not sure what the best solution to this problem will be besides to create a version of Unvalidated that does not depend on HttpContext.

Localization - Add culture code to route

Hello,

I am using the new Localization version.

In some cases I might need to add the culture code to the route:

/{culture}/area/prefix/controller/action/id

What is the best way to do this?

Thank You,
Miguel

Controller Inheritence

Hi Tim,

This is difficult to explain :)

I have two MVC projects. One is called Admin where all the m/v/c are compiled and consumed by any other web project that needs a /admin. I will call the consumer project, Derived.

(For further information on the method, see my bottom comment on http://stackoverflow.com/questions/6656843/area-as-a-virtual-on-other-websites).

There is a HomeController in both projects, Derived inherits Admin. The index method is Virtual in Admin and override in Derived.

When i visit Derived - /Home/Index, the Admin home controller has preference even though it appears to use the correct view. I have a ViewData magic string which is setting which controller was used. Both website tests i setup, http://webadmin.local and http://webderived.local the magic string as always coming from the Admin Home controller.

I have uploaded a sample project to my skydrive.
https://skydrive.live.com/embedicon.aspx/Public/InheritController.zip?cid=e7737d00ff5b25e9&sc=documents

The route debugging on http://webderived.local/ is showing both home controller routes.

I wonder if there is another way around this or if I have created an undocumented feature. Maybe the Admin Home controller route should not be there because it is overridden.

(btw: i accidentally clicked fork. Trying to undo that now).

thanks, Mike

Route works only on top of controller. Why?

Hello,

I have the following routes on a controller:

[GET("Users")]
public virtual ActionResult Index(Int32 p = 1)

[GET("Users/New")]
public virtual ActionResult New()

[POST("Users"), ValidateAntiForgeryToken]
public virtual ActionResult Create(UserNewModel model)

[GET("Users/{id}")]
public virtual ActionResult Show(Int32 id)

[GET("Users/{id}/Edit")]
public virtual ActionResult Edit(Int32 id)

[PUT("Users/{id}"), ValidateAntiForgeryToken]
public virtual ActionResult Update(Int32 id, UserEditModel model)

[GET("Users/{id}/Delete")]
public virtual ActionResult Delete(Int32 id)

[DELETE("Users/{id}"), ValidateAntiForgeryToken]
public virtual ActionResult Destroy(Int32 id)

[GET("Users/SignIn")]
public virtual ActionResult SignIn()

[POST("Users/SignIn"), ValidateAntiForgeryToken]
public virtual ActionResult SignIn(UserSignInModel model)

When I try to access Users/SignIn I get a 404 error.

If I move this action to the top in the controller then it works fine.

But I don't see why.

Any idea?

Thank You,
Miguel

Route Single word url to area

Hi there,

may be, I'm to damn stupid, but I try now for one hour to do the following:

Litte information, I'm a german developer and I have german mvc project.

OK,

On my local system, I have the following url http://localhost:4711/Tierlexikon <- german word for animal lexicon

and I have an area "Tierlexikon" with (at the moment) one controller with the name "AnimalLexiconController", and this controller have an action "Index".

All I want to do is route the url above to the action Index.

I tried:

  • [RouteArea("Tierlexikon", AreaUrl = "Tierlexikon")] for the controller and [GET("/")] for the action
  • [RoutePrefix("Tierlexikon")] for the controller and [GET("/")] for the action
  • [RouteArea("Tierlexikon", AreaUrl = "Tierlexikon")] for the controller and [RouteDefault("controller", "AnimalLexicon")] and [GET("/")] for the action

I think I know the problem, there are not enough information, MVC needs in the url area and controller, so if I'm not to stupid, can you please provide an attribute with which I can do want I want?

Best regards

Words within routes with optional parameters?

Hi,

I'd like to have something like the following:

 [GET("/show/{id}/{slug}/user-{?username}")]

but when the username is not there, not show the user- part in generated links

Is this somehow possible to accomplish? I've added strings in all kinds of places and it worked in the past - but it don't know how to accomplish this when the parameter is optional.

Thank you

Generated URLs don't seem to support appending a trailing slash.

When configured this way, for example, [GET("/some/location")], with or without a querystring would generate /some/location/ or /some/location/?test=x for outbound URLs.

I slapped together a pull request for this behavior that I will submit right after this.

Exception when request contains a potentially dangerous data

When a request contains html or any potentially dangerous data, AtributeRouting fails when retrieving HttpMethod.

This is no good for example when using [AllowHtml] or [ValidateInput(false)] in models and controller actions.

This is a stack trace that will point to the issue immediately:

[HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (Description="<span class="Apple-s...").]
   System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection) +8855748
   System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, RequestValidationSource requestCollection) +122
   System.Web.HttpRequest.get_Form() +150
   System.Web.HttpRequestWrapper.get_Form() +11
   AttributeRouting.Extensions.MvcExtensions.GetHttpMethod(HttpRequestBase request) in C:\Development\AttributeRouting\src\AttributeRouting\Extensions\MvcExtensions.cs:16
   AttributeRouting.RestfulHttpMethodConstraint.Match(HttpContextBase httpContext, Route route, String parameterName, RouteValueDictionary values, RouteDirection routeDirection) in C:\Development\AttributeRouting\src\AttributeRouting\RestfulHttpMethodConstraint.cs:29
   System.Web.Routing.HttpMethodConstraint.System.Web.Routing.IRouteConstraint.Match(HttpContextBase httpContext, Route route, String parameterName, RouteValueDictionary values, RouteDirection routeDirection) +22
   System.Web.Routing.Route.ProcessConstraint(HttpContextBase httpContext, Object constraint, String parameterName, RouteValueDictionary values, RouteDirection routeDirection) +56
   System.Web.Routing.Route.ProcessConstraints(HttpContextBase httpContext, RouteValueDictionary values, RouteDirection routeDirection) +150
   System.Web.Routing.Route.GetRouteData(HttpContextBase httpContext) +215
   System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +287
   System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +60
   System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +86
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

AttributeRouting and SiteMap. Did anyone implemented something similar?

Hello,

I am trying to implement a SiteMap service compatible with AttributeRouting

[Sitemap(Priority = 0.8, Frequency = Frequency.Hourly)]
[GET("Articles/Recent")]
public ActionResult Index()
{
return View();
}

I created the attribute which can be used without or with parameters (Priority, Frequency).

My idea is to have a Sitemap/Index action where I would:

1 - Get all routes with Sitemap attribute together with custom info.

2 - Generate custom routes. For example, a route like:

 [GET("Post/{id}")]
 [Sitemap(Priority = 0.8, Frequency = Frequency.Hourly)]
 public ActionResult Index(int id)
 {
    return View();
 }

 In this case I would get the route and on the Sitemap/Index action I would generate N sitemap entries.
 Each entry would be created with a new ID gotten from the database.

How to link this idea with AttributeRouting?

Did anyone ever did something like this?

Thank You,
Miguel

RenderAction + PostBack causes exception

When using something along the lines of:

@{
    Html.RenderAction("LoginControl", "Auth");
}

Any postback that occurs is met with an exception:
Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.

Inner:
{"Execution of the child request failed. Please examine the InnerException for more information."}

Inner:
{"A public action method 'LoginControl' was not found on controller 'TestMVC.Controllers.AuthController'."}


Create a page that has both a GET/POST, with a form on it:

@using(Html.BeginForm("Index", "Home", FormMethod.Post))
{
    @Html.TextAreaFor(m => m.Text);

    <input type="submit" value="Submit" />
}

[GET("", IsAbsoluteUrl = true)]
public ActionResult Index()
{
   return View(new HomeModel());
}

[POST("", IsAbsoluteUrl = true)]
public ActionResult Index(HomeModel homeModel)
{
   return View(homeModel);
}

Create a partial view, and on the same page render is like:

@{
    Html.RenderAction("LoginControl", "Auth");
}

[ChildActionOnly]
[GET("Auth/LoginControl")]
public ActionResult LoginControl()
{
    return PartialView("LoginControl");
}

Then when you post the page it will throw an exception.

Can submit a test project that reproduces this if need be. (not sure how to on github, first time submitting issue)

Not sure what I'm doing wrong

Hi, I've read about this module, got all excited, but can't seem to make it work.

I added the package from Nuget and tried to add the config option to use lowercase URLs in the file that was created in App_Start, but nothing happened, all links were still CamelCase.

I tried to disable the default RegisterRoutes in Global.asax, but that broke everything.

Only thing that is differs in my code from the examples in the wiki, is that my controllers inherit from Controller and not ControllerBase, could that be the problem? Isn't this package supposed to work with MVC3?

I'm really new to MVC, so forgive me if I missed something really obvious.

Thank you

Routes.axd in AR 1.6 ...

Hello,

I installed AR 1.6 and I am not able to access "routes.axd" in IIS and in VS Development Server.

I checked by Web.Config file and I have:

<system.webServer>   
  <handlers>
    <add name="Routes" verb="*" path="routes.axd" type="AttributeRouting.Logging.LogRoutesHandler, AttributeRouting" />
  </handlers>
</system.webServer>

And I also have:

<system.web>   
  <httpHandlers>
    <add verb="*" path="routes.axd" type="AttributeRouting.Logging.LogRoutesHandler, AttributeRouting" />
  </httpHandlers>    
</system.web>  

And in Global.asax I have the following routes:

  RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  RouteTable.Routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.([iI][cC][oO]|[gG][iI][fF])(/.*)?" });
  RouteTable.Routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, typeof(HomeController).Assembly);

When I try to access "routes.axd" I get the error:
"A first chance exception of type 'System.NullReferenceException' occurred in AttributeRouting.DLL"

Any idea what I might be missing?

Thank you,
Miguel

Hypens in Url

I want to have hypens in the url like:

[GET("company-overview")]
public ActionResult CompanyOverview()
{
return View(Service.GetCompanyOverview());
}

In a View I do:
@Html.ActionLink("Company Overview", "company-overview", new { area = "MediaRoom" })

But that will not work and I just see a hyperlink generated with an empty href.

I am forced to have my GET declared like:

[GET("companyOverview")]
public ActionResult CompanyOverview()
{
return View(Service.GetCompanyOverview());
}

In the markup of a View I do:
@Html.ActionLink("Company Overview", "companyOverview", new { area = "MediaRoom" })

and now the hyperlink is generated correctly.

I have not experienced this issue before and I am at a loss at how to fix it.

Routes.axd not working on IIS Express

Hello,

I am able to access Routes.axd when using VS Development Server.

However when I use IIS Express I get a 404 error when accessing Routes.axd.

I added the following on Web.Config:

<system.webServer>
  <handlers>
    <add verb="*" path="routes.axd" type="AttributeRouting.Logging.LogRoutesHandler, AttributeRouting" />

But this didn't solved it. Any idea?

Thank You,
Miguel

MVC actions returning string are missed by the auto-scan

Hi,

First let me say I love this project - was looking for something like this for hours and posted on StackOverflow but couldn't find anything and was about to give up - then found this via NuGet. Works perfectly!

The only small problem I came across is that I was using actions that return a string just for testing but those were missed by MapAttributeRoutes(). It took me a bit of time and head scratching until I looked at the code and realized that AttributeRouting.Extensions.ReflectionExtensions.GetActionMethods() only looks for methods that return ActionResult!

The definition of an ASP.MVC action is any public method on a controller class, so I think the search criteria should change. However if for some reason you have to live this limitation, I think at least the AttributeRouting documentation should mention this so that others won't spend as much time as I did head scratching... :-)

Great Work. Thanks again!

Lowercasing causes query string parameter names to be lowercase

I'm not sure how to replicate this issue or even if it's a bug, just figured I should let you know. I've been getting heaps of traffic to my blog about AR and someone made a comment about Query String Parameter Names being lowercased.

http://www.philliphaydon.com/2011/08/mvc-routing-with-attributes-makes-routing-awesome/

Works pretty great โ€“ although it did lower case my query string parameters as will which may not be desirable. Does anyone know of a good way to ensure a url like this

http://www.something.com/Controller/Action/paramName=ParamValue

goes to

http://www.something.com/controller/action/paramname=ParamValue

This would be ideal.

Actions defined in a base class controller don't get mapped

We have an action on our base controller with a JavaScriptResult to serialize page translations to another language, it simply outputs a JSON object for us to use in JavaScript.

The action is defined in the base controller since the implementation is identical in every controller, the sub-class has a property which defines a parameter to query the db with to get the correct translations.

It seems however that defining a route in the base class:

[GET("GetPageTranslation")]
public JavaScriptResult GetPageTranslation()
{
...
}

Doesn't get mapped.

I've added a work-around for this by defining the route in the global asax file:

routes.MapRoute("PageTranslations", "{area}/{controller}/GetPageTranslation", new { action = "GetPageTranslation" });

This over-comes the issue. But think this is something that AR should handle.

custom rules

hi,
sorry for posting in Issues as i cant see a way to post a request,

what i want is to create custom rules like your lowercase one,
for example
i want to replace a word occurances in route with another one like

www.mysite.com/politic
into
www.mysite.com/politics-articles
i know that that i can reroute or redirect, but that is just a trivial example,

sometimes i need to change 2 different words.
if this possible this would be awesome, as the automatic nature of your lowercase is lovely and want to apply concept with other custom rules of mine

thanks alot in advanced.

Area attribute routing

Hi,

I have found an issue in the area routing.
If you add a controller to the area routing which starts with the same name as the area, the routing goes wrong.

So in your demo project you have an area called Admin.
I've added the following controller:

public class AdministratorController : AdminControllerBase
{
[GET("Administrators")]
public ActionResult Index()
{
return View();
}
}

I've added the corresponding View.

I assume that the following route will be added to the routing table:
http://localhost/Admin/Administrators
But instead the following route is added to the routing table:
http://localhost/Administrators

Could you please look in to this issue?

Thanks
Jan Saris

Localization Needed

I would love to add localization support. However, I have not yet had a need for localizing routes. So to try and come up with a good solution, I would like to open the floor for comments. Please leave your requests and ideas so that I (or a willing contributor) can build something out.

What would be nice to have, and what would AR do?

  1. Support specifying the locale to use during requests via the url with some pattern to match (eg: {culture}.domain.com or domain/{culture}), or with a custom object to provide the logic, or by using the culture of the current thread? Specify via the configuration process or in another attribute somehow?
  2. ITranslationProvider that will translate route areas, prefixes, urls, defaults, and constraints? This provider could have a single method that when given a key, would return a string with the translation. Returning null would tell AR to use whatever is specified via the attributes in code. So the attribute would describe the default culture translation.
  3. Use a conventional approach to specify keys provided to the translation provider? Add a new property to the attributes called TranslationKey, which could simply override the default convention? Convention and configuration. Any need to be able to specify your own convention?
  4. Now, how to make AR use the translation provider to handle inbound requests? Do we need another route for every possible translation? So if you have 100 routes in your app, then having three translations would yield 300 routes? Anyone see this becoming a problem? It would be the easiest to do, and require the least processing after setting up routes.
  5. Next, AR and outbound url generation. Have to use the translation provider to generate the correct url for the current culture. So when browsing a default-English site in Spanish, using the MVC UrlHelper will give the visitor properly translated urls. Would have to add a property to AttributeRoute that stores the translations created during route generation. Then AttributeRoute could place the translation over the default generated route. (Imaging a route like
/{areaUrl}/{prefix}/{routeUrl}/{param}

having a default generated route of

/sea/scape/goat/milk

and ending up with

/easay/apescay/oatgay/milk

with milk left alone cause it's a route param, but could have been supplied from translation for route default, and would apply translated route constraints as well.)

Would this be useful? This is just a stab at what could be done. The simplest way to fully support localization is what I'd want to build in. So suggestions are welcome!

HTTP 404 Not Found

Hi,

awesome library, that i cant work without it anymore, thanks so much for you for giving us such a tool to ease up our lives.

i had my site working fine up until i upgraded to your latest build, now i get
HTTP 404 Not Found

i have made a test by disabling the route attribute temporarily and use normal ASP MVC routing and it is working, so my code is fine.

now i dug a little deeper and found out that if i remove registration to global.asax.cs everything works fine again, so the problem is in the App_Start file that you provide

here is my code in the appstart

[assembly: WebActivator.PreApplicationStartMethod(typeof(MyWebApplication.App_Start.AttributeRouting), "Start")]

namespace Syrianmartyrs.App_Start
{
public static class AttributeRouting
{
public static void RegisterRoutes(RouteCollection routes)
{

        routes.MapAttributeRoutes(config =>
        {
            config.ScanAssembly(Assembly.GetExecutingAssembly());
            config.UseLowercaseRoutes = true;
            config.AddRoutesFromControllersOfType<AdminController>();
        });
    }

    public static void Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}

}

AttributeRouing.xml appears on build

Hello,

When I build my MVC site I get two files on the Bin folder:
AttributeRouting.dll and AttributeRouting.xml.

Why do I get the AttributeRouing.xml?

Is there a way to avoid it?

Thank you,
Miguel

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.