I'm trying to migrate an existing ASP.NET Webforms 3.5 application into an ASP.NET MVC 3 application. That means, I attempt to convert existing .aspx pages with webcontrols and codebehind recpectively with controller logic and razor views.
At the moment I'm focusing on the master page (to get an analogue layout.cshtml for all other razor views).
For example I've replaced controls like asp:Menu, asp:LoginView with partial views and #Html.Action to invoke the controller action, run some code that has been in the codebehind of that masterpage before and return that partial view.
But now I'm getting lost with many web controls of the masterpage that have been set in/visible, depending on the code behind. For example there are two asp:panels in the master page that have been switched in/visible depending on the visited page.
The problem is that in razor views I don't have web controls and in controllers I cannot set attributes/properties (like private int counter;).
Thus I don't know how to carry on...
I hope you have got some ideas or experience with this situation.
Please ask if any information is missing.
You can either set properties of the Model or ViewData in the Controller and then use these in the Razor view with #if
e.g.
On the controller:
public ActionResult Index()
{
ViewBag.Foo = IsThisFoo();
View();
}
In the View:
#if (ViewBag.Foo) {
<p>This is foo</p>
}
else
{
<p>This is bar</p>
}
nb: best practice would be to do it as part of a strongly typed Model for the view
Related
I m new in mvc. I had a web forms application and there was a masterpage of every page.
there was a virtual function in master page template and every page's page_load i was overriding it.
now i have mvc pattern in my project. where exactly should i put all these business in my project.
there are special views that can be used in MVC(assuming your are using razor).
There views are _viewstart and _layout(though can be named anything else).
so basically a _layout.cshtml view in a specific controller's views folder can work as a master page for the views existing in the same folder and a _layout.cshtml view in the shared folder can work as a master page for all the views present.
to specify to use a particular view as a masterpage use set the Layout variable inside the view. for ex Layout = "~/Views/Shared/_layout.cshtml";
Normally Master Pages goes in Shared folder in Views Folder.
I would recommend if you have multiple masterpages, try to minimize number for the same.
Make a parent Masterpage which should be called on all pages.
For using mutiple masterpages you can do something like this
<script language="C#" runat="server">
protected void Page_PreInit(object sender, EventArgs e)
{
if (User.IsInRole("Admin"))
{
this.MasterPageFile = "~/Views/Shared/Site2.Master";
}
else
{
this.MasterPageFile = "~/Views/Shared/Site.Master";
}
}
Also you can use
ViewMasterPage.MasterPageFile inbuilt class
I am used to ASP.NET where each user control would have its own codebehind, and you do things related to that usercontrol in that codebehind C#.net file, so you can reference the usercontrol anywhere you like.
I am new to ASP.NET MVC, and I added an ascx control, and I can not seem to figure out where do I write the code for setting viewdata specific to that control? I have this ascx control inside my master page, so the setting up for viewdata for that control should be at such a place that is available to all pages, so I can not do it inside Index() or something.
If you need a partial view (.ascx) that has its own controller ("code-behind") associated with it, consider using RenderAction() rather than RenderPartial().
http://blogs.intesoft.net/post/2009/02/renderaction-versus-renderpartial-aspnet-mvc.aspx
Take the example of wanting to have a "Latest news items" sidebar on every page of your ASP.NET MVC web site. I have a NewsItemController which is fine for pages dedicating their attention to NewsItems. What about having a news sidebar appear on the HomeController for the home page though? Or any other controller for that matter?
My first instinct is to put the logic for selecting top 5 NewsItems in a user control which is then called in the Master Page. That way every page gets a news sidebar without having to contaminate any of the other controllers with NewsItem logic. This then means putting logic in what I understood to be the presentation layer which would normally go in a Controller.
I can think of about half a dozen different ways to approach it but none of them seem 'right' in terms of separation of concerns and other related buzz-words.
I think you should consider putting it in your master page. Your controller can gather data (asynchronously, of course), store it in a nice ViewModel property for your view (or in TempData) and then you can call RenderPartial() in your master page to render the data.
The keeps everything "separate"
http://eduncan911.com/blog/html-renderaction-for-asp-net-mvc-1-0.aspx
This seems to address the question - even using the instance of a sidebar - but using a feature not included with MVC 1 by default.
http://blogs.intesoft.net/post/2009/02/renderaction-versus-renderpartial-aspnet-mvc.aspx
This also indicates the answer lies in RenderAction.
For anyone else interested, here's how I ended up doing it. Note you'll need to the MVC Futures assembly for RenderAction.
Basically you'd have something like this in your controller:
public class PostController
{
//...
public ActionResult SidebarBox()
{
// I use a repository pattern to get records
// Just replace it with whatever you use
return View(repoArticles.GetAllArticles().Take(5).ToList());
}
//...
}
Then create a partial view for SidebarBox with the content you want displayed, and in your Master Page (or wherever you want to display it) you'd use:
<% Html.RenderAction<PostController>(c => c.SidebarBox()); %>
Not so hard after all.
You can create a user control (.ascx) and then call RenderPartial().
Design a method in your controller with JsonResult as return type. Use it along with jQuery.
Use RenderAction() as suggested by elsewhere.
News section with ASP.NET MVC
I'm looking into ASP.NET MVC, and whether or not to make the switch. One thing that I do a heck of a lot in ASP.NET, is to render HTML on AJAX callbacks and sent back to the client. I use a generic ViewManager for rendering User Controls.
I created a sample MVC App from the templates, and was looking for the RenderUserControl method inside a Controller. I found: System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial but that doesn't seem to be what I'm looking for in this context.
Is there an equivalent to the ASP.NET ViewManager in MVC?
What you want to do is return a partial view:
public ActionResult IWillCallThisViaAjax()
{
return PartialView("MyUserControlName");
}
I make heavy use of View Components in some of the larger applications I've built in Monorail - What is the equivalent approach in ASP.Net MVC for a view component, that can support sections etc.?
Actually you have several options to create the equivalent of a ViewComponent in ASP.NET MVC, depending in the complexity of your component. I use these two approaches which are the more mvc-ish of the options I am aware of.
1:
The simplest thing is to create a ViewUserControl and display it using Html.RenderPartial with the helper. The ViewUserControl is a simple piece of markup with no backing controller (I think you can put a codebehind file if you want).
Optionally, you can pass a model object or the entire ViewData dictionary to the view when calling RenderPartial, like this:
<% Html.RenderPartial("TopBar", model); %>
"TopBar" is an ascx page. This works anywhere, in master pages and in normal views.
2:
If you want your component to have more complicated logic or to access datasources, IoC, etc, then you can use Html.RenderAction which is an extension method found in the Microsoft.Web.Mvc assembly. I am using this out of the mvccontrib distribution. It works like this, you need to create a normal controller with all the logic you need, then create some views and all of these things become your component, for example:
public class AboutComponentController : Controller {
public IRepository Repository{ get; set; }
public ActionResult Detail() {
var lastEvent = Repository.FindAll<Auditoria>().FirstOrDefault();
return View(lastEvent);
}
}
Notice how I have a reference to an IRepository which is going to be injected with IoC (Windsor in my case) and I can do anything a normal controller would do.
Now, in any page (master or normal) where you want to use your component, import Microsoft.Web.Mvc and call Html.RenderAction with the appropriate parameters. This will create a mini mvc pipeline that creates the controller, resolves the view, etc., just like a Monorail ViewComponent. I prefer to use the lambda based variation of the method, like this:
<% Html.RenderAction<AboutComponentController>(x => x.Detail("a message"));%>
Unfortunately, the only way to pass parameters is to use the method call itself, which in turn must be unique in the controller. Still needs some work to resemble a ViewComponent.
I don't use masterpages or layouts in the views of my components since they are composition elements themselves.
Remember that when using the Webforms view engine, you can have strongly typed views if you like to have intellisense when using the Model variable in code blocks.
The beauty of this is that you can mix view engines with these approaches, I usually create the components in nvelocity and display them in aspx pages, etc.
I now there can be issues with caching of the partial views but I haven't run into any so far. I am sure there are other options (like subcontrollers in mvccontrib) but this is usually enough for simple cases. Of course you can use normal ASP.net components in your aspx view pages but that would be cheating right? hehe. I hope it helps.
Phil Haack blogged about creating areas to group controllers into sub-folders/sections similar to MonoRails.