Search code examples
asp.net-mvcasp.net-mvc-4razorasp.net-mvc-partialviewrazor-2

how to force partial view to render proper url


ASP.NET MVC4 search Razor partial view is defined as

@inherits ViewBase<MvcMusicStore.ViewModels.SearchViewModel>

@using (Html.BeginForm("Browse", "Store" , FormMethod.Get,
    new { @class = "searchform" }))
{

    @Html.TextBoxFor(model => model.Search, new
{
    @class = "searchfield",
    value = "Search..."
})
    <input class="searchbutton" type="submit" value="@("Search...")" />
    <input type="hidden" value="relevance" name="order" />
}

and used in site.cshtml:

@Html.Partial("Search", new MvcMusicStore.ViewModels.SearchViewModel())

If page address is http://localhost:52223/Store/Browse/Kuupakkumine search form is created with invalid action /Store/Browse/Kuupakkumine. Kuupakkumine is automatically added to end of url:

<form action="/Store/Browse/Kuupakkumine" class="searchform" method="get">
 <input class="searchfield" id="Search" name="Search" type="text" value="Search...">    
<input class="searchbutton" type="submit" value="Search...">
</form>

How to fix this so that correct url, /Store/Browse will appear in browser html ?

Storecontroller Browse method signature is

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]
public ActionResult Browse(string category, string order, int? page, bool? descending,
 int? itemsPerPage, string brand, string color, string @class, string type, bool? grid,
    string search, bool? instock, CartLayout? cartLayout, string id)

Solution

  • Your using the default route (url: "{controller}/{action}/{id}",) and your Browse() method includes a matching string id parameter which means that the value of id is added as a route value. The BeginForm() method uses these values to generate the forms action attribute. This behavior is useful because if you are (say) creating a form to edit a model, and that model contains a property int ID, then it is not necessary to include a hidden input for the ID property.

    To override the default behavior, you need to explicitly set the route value to null

    Html.BeginForm("Browse", "Store", new { id = "" }, FormMethod.Get, new { @class = "searchform" }))