Bind GridLookup control in shared layout mvc 5 - asp.net-mvc

I am using Devexpress MVC application where i used one GridLookup control in shared layout. I needed here some controller which will call a method on every request. For this purpose i used base controller and using ActionExecutingContext method where i am calling my menu loading and gridlookup loading. I am using viewdata to set the value and in shared view i used partial view of my GridLookup control where i am binding viewdata to GridLookup.
Below is the Base controller used to load menu and filters of gridlookup.
protected override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
ProcessingMenus();
}
Below is the shared layout where i am using partialview of gridlookup control
#Html.Partial("_ReportFilter")
Below is the GridLookup control used in this partial:
#{
var gridLookup = Html.DevExpress().GridLookup(settings =>
{
settings.Name = "LookupLobMultiple";
settings.KeyFieldName = "Description";
settings.GridViewProperties.CallbackRouteValues = new { Controller = "Manage", Action = "BindLOB" };
settings.Properties.SelectionMode = GridLookupSelectionMode.Multiple;
settings.Properties.TextFormatString = "{0}";
settings.Properties.MultiTextSeparator = ";";
settings.CommandColumn.Visible = true;
settings.CommandColumn.ShowSelectCheckbox = true;
settings.CommandColumn.SelectAllCheckboxMode = GridViewSelectAllCheckBoxMode.AllPages;
settings.GridViewProperties.SettingsPager.Visible = false;
settings.GridViewProperties.Settings.ShowGroupPanel = false;
settings.GridViewProperties.Settings.ShowFilterRow = false;
settings.Columns.Add("ID").Visible = false;
settings.Columns.Add("Description").Caption = "Line of Business";
settings.PreRender = (s, e) =>
{
MVCxGridLookup gl = (MVCxGridLookup)s;
gl.GridView.Selection.SelectRowByKey(ViewData["LOB"]);
};
});
}
#gridLookup.BindList(ViewData["LobModal"]).GetHtml()
In the above GridLookup control you can see am binding data using viewdata which is loading in ProcessingMenus method.
First issue here is in GridLookup i have used controller and action method also but this is not calling when i check and uncheck any value and showing Loading....
Second issue when after sometime if i again hit the url OnActionExecuting method is not calling due to it menus are not loading again.

I found the answer from Devexpress team is to call partial view in shared view use #{Html.RenderAction("action", "controller");} and then in that action call the partial view that need to show in shared layout with passing model data.
and in partial view just bind the grid with the passed model.
That's it.
Thank you for all your suggestions.

Related

What happens when you return View when should be PartialView?

In a View I am calling an action that returns a View
View:
Html.RenderAction("Read", "Stats", new { Module = statsModel.Module, Name = statsModel.Name });
Controller:
public ActionResult Read(Module module, string name, bool showStatsItems = true)
{
eRPortalEntities db = new eRPortalEntities();
StatsPanelService service = new StatsPanelService(db, UserID);
StatsPanelViewModel spv = service.Read(module, name);
spv.ShowStatsItems = showStatsItems;
return View("StatsPanel", spv);
}
This unfortunately causes some of my Bootstrap functionality to break. Such as dropdowns and modals not toggling.
If instead I have the controller return a PartialView, everything works as expected
return PartialView("StatsPanel", spv);
I'm not looking for a specific reason why my bootstrap stopped working but more of an explanation of... Why would this cause issues in general?
Unless you explicitly specify the Layout to be null, When you do return View("StatsPanel"), Razor view engine will render the view content inside the Layout (_Layout.cshtml) similar to how you render a page normallly. That means, it will include all those scripts & Css in the head section again. That could be the reason it is messing up your markup.
Using PartialView() method seems appropriate in your use case. If you still want to use the View() method, you can explicitly define layout as null in your StatsPanel.cshtml view like this
#{ Layout = null; }

MVC EditorFor templates not used when calling controller from another controller

Within an MVC project we have an area with a controller SomeController returning a partial view containing EditorFor statements, each with their own template.
Everything works fine if the controller is invoked directly via a route for that area. However, if it's called via another controller outside of the area, i.e. via 'new SomeController().SomeAction()', the templates are not used, even if explicitly specified (the view is returned ok, but shows just default textboxes etc).
What could be the reason for this and how can it be fixed?
When your action is invoked merely using ctrl.Action(), the current RouteData will be used (with the current area/controller/action values in it) and when Razor tries to resolve your EditorTemplates paths it consults the ViewContext that is still containing the (now wrong) values of the originating action.
You better use the ControllerFactory in order to mimic the desired behavior:
var ctrlFactory = ControllerBuilder.Current.GetControllerFactory();
var routeData = new RouteData();
routeData.DataTokens.Add("area", "target_area_name");
routeData.Values.Add("controller", "target_controller_name");
routeData.Values.Add("action", "target_action_name");
var requestContext = new RequestContext(this.HttpContext, routeData);
var ctrl = ctrlFactory.CreateController(requestContext, "target_controller_name") as TargetControllerType;
if (ctrl != null)
{
ctrl.ControllerContext = new ControllerContext(requestContext, ctrl);
var ctrlDesc = new ReflectedControllerDescriptor(typeof(TargetControllerType));
var actionDesc = ctrlDesc.FindAction(ctrl.ControllerContext, "target_action_name");
var result = actionDesc.Execute(ctrl.ControllerContext, new Dictionary<string, object>()) as ActionResult;
this.RouteData.DataTokens["area"] = "target_area_name";
this.RouteData.Values["controller"] = "target_controller_name";
this.RouteData.Values["action"] = "target_action_name";
return result;
}
See MSDN

How to capture the values in a gridview dynamically in asp.net DevExpress MVC

as I can make this code dynamically
public ActionResult EditingUpdate()
{
//...
string fName = GridViewExtension.GetEditValue<string>("FirstName");
string lName = GridViewExtension.GetEditValue<string>("LastName");
//...
}
There are several ways of doing this, it depends on how you want to present the action to the user. I would recommend you follow the example on the DevExpress Demo Page. They show you how to pass the model into your controller.
Controller:
public ActionResult EditingUpdate(MyObject model)
{
string fName = model.FirstName;
....
....
{
Now, the following step is where you have few choices. You can call the controller method in several different ways, all from the gridview partial view. Again, refer to the DevExpress Demo Page. If you want to call the method from an edit action (which is what I assume based on your method name), then you use:
settings.SettingsEditing.UpdateRowRouteValues = new { Controller = "MyController", Action = "EditingUpdate" };
But there are other ways of calling this method, such as
settings.CustomActionRouteValues = new { Controller = "MyController", Action = "EditingUpdate" };
It all depends when you want the gridview to call this method.
Follow the example in the demo, that will help you decide how you want it. Good luck!

Call PartialView via Ext.Net.ComponentLoader

I want to render some Partial Views into the main View. So i used the Ext.Net.ComponentLoader like this:
#(
Html.X().Window()
.Title("Items")
.Width(400)
.Height(300)
.Closable(false)
.Resizable(false)
.Layout(LayoutType.Border)
.Items(i=>{
i.Add(new Panel{
ID = "West1",
Title = "West",
Width=200,
Layout = "Accordion",
Region = Region.West,
Loader = Html.X().ComponentLoader()
.Url(Url.Action("WestItems"))
.Mode(LoadMode.Script)
.Params(new { containerId = "West1" })
});
i.Add(new Panel{
ID = "Center1",
Region = Region.Center,
BodyPadding = 10,
Header = false
});
})
)
the main view here is calling Partial View with action controller "WestItems" which is not good in my case. i want to call partial View directly without action controller like using Html.Partial("_PartialView", Model) also i want to send the Model as parameter to the partial view. Is there any way to call Partial View directly via ComponentLoader? How to send Model as parameter to the Partial View?
We should always call controllers action and they will render partial views.
Partial view are called like:
public PartialViewResult _PartialView(string containerId)
{
...
return new PartialViewResult
{
RenderMode = RenderMode.AddTo,
ContainerId = containerId,
Model = yourModel,
WrapByScriptTag = false
};
}
}

Umbraco Surface Controller or RenderMvcController

Hi I have my 'home' controller and a 'sort' controller in umbraco 7. The 'home' controller works fine for the index action as it is overridden from RenderMvcController. Firstly I am confused which controller I should using in which instance i.e a surface controller or a rendermvccontroller. I cant seem to access the twitter action below which is something I need for ajax. Do I need to put the twitter action in a surface controller or could I use a regular mvc controller in umbraco?
public override ActionResult Index(RenderModel model)
{
var storedProcedure = new StoredProcedure()
{
ConnectionString = ConfigurationManager.ConnectionStrings["CentralDbContext"].ConnectionString
};
DataSet ds = storedProcedure.ExecuteProcedureToDataSet("GetHomePage");
IMapSetup map = new MapHomePage();
HomePage homepage = map.Setup<HomePage>(ds);
homepage.Slideshow = CurrentPage.AncestorsOrSelf(1).First().Descendants("SlideshowItem").Take(5).AsMany<Slideshow>();
this._weatherSettings.DefaultLocation = "warrington";
homepage.Forecast = new Forecaster(this._weatherSettings, this._cacheHelper).GetWeather(this._weatherSettings.DefaultLocation);
return CurrentTemplate(homepage);
}
public ActionResult TwitterSort(int? page)
{
int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
var storedProcedure = new StoredProcedure()
{
ConnectionString = ConfigurationManager.ConnectionStrings["CentralDbContext"].ConnectionString
};
DataSet ds = storedProcedure.ExecuteProcedureToDataSet("GetHomePage");
IMapSetup map = new MapHomePage();
HomePage homepage = map.Setup<HomePage>(ds);
if (Request.IsAjaxRequest())
{
return PartialView("umbTweets", homepage.Twitter.ToPagedList(currentPageIndex, DefaultPageSize));
}
return PartialView(homepage.Twitter.ToPagedList(currentPageIndex, DefaultPageSize));
}
My Approach is:
Render controller is only for displaying data to user.
Surface controller is for interaction (I use this for interaction mainly ajax, or forms)
For rendering child action you can use following example:
http://our.umbraco.org/documentation/Reference/Mvc/child-actions
Update:
To implement custom routing you can have a look on
http://cpodesign.com/blog/umbraco-implementing-routing-in-mvc/

Resources