Why should I specify a data context class when scaffolding a view? - asp.net

When adding a new view to an ASP.NET MVC 5 project using the Add View dialog pictured below, I'm invited to choose a template and a model class, which allows me to quickly generate a form for creating new instances of the model or a view that displays the model's properties. But why should the view care what the data context class is? In my project, whether or not I specify the data context class, the same view is generated, but I'm guessing there's a scenario where it would make a difference. What might that be?

If you refer to an existing DbContext then the wizard will insert public DbSet<Employee> Employee { get; set; } (if it doesn't already exist) in your DbContext derived class . Looks like Visual Studio doing some of the leg work.

Related

ASP.NET MVC: When should I create custom View Engine

I know what View Engine is, I preferred to use Razor view engine just because of its simple syntax over ASPX engine. Inbuilt view engine performs almost all task for you, then in what scenario I should create my own view engine,
I googled it but getting answers for How to create it and not when and why to create it.
Can any one help me to describe the real time scenario?
For example, you can change the view files locations that Razor searches with the help of custom view engine.
Normally, in MVC these locations are searched for partial views:
// Part of the RazorViewEngine implementation from the Asp.net MVC source code
PartialViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
Then add for example LayoutsPartialViews folder to Shared folder and add partial views which for example will be used only for layouts. And add for example ColorfuleHeader.cshtml to that location. And try to render that view via this:
#Html.Partial("ColorfulHeader");
Such exception will be throwned:
The partial view 'ColorfulHeader' was not found or no view engine
supports the searched locations. The following locations were
searched...:
So we must add this location to the searched locations. And for doing this we must create our custom view engine:
public class CustomLocationViewEngine : RazorViewEngine
{
public CustomLocationViewEngine()
{
PartialViewLocationFormats = new[] {
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml",
"~/Views/Shared/LayoutsPartialViews/{0}.cshtml",
"~/Views/Shared/LayoutsPartialViews/{0}.vbhtml",
};
}
}
Also, remember that the action invoker goes to each view engine in turn to see if a view can be found. By
the time that we are able to add our view to the collection, it will already contain the standard Razor View
Engine. To avoid competing with that implementation, we call the Clear method to remove any other
view engines that may have been registered, and then call the Add method to register our custom
implementation.
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomLocationViewEngine());

how to access the project properties in a .cshtml razor file?

is it possible to Access my Project Properties within the .cshtml Razor file?
I need something like this:
#if (myProject.Properties.Settings.Default.foo) {...}
while foo is a boolean
I get the error that because of a security reason it is not possible.
You shouldn't really be calling ConfigurationManager directly from your view. Views should be 'dumb' in MVC, ie not have any knowledge of the data structure or back-end, and by calling ConfigurationManager directly your view knows too much about how your settings are stored. If you changed your settings to use a different store (ie a database) then you'd have to change your view.
So, you should grab that value elsewhere and pass it to your view so your view just takes care of rendering it and that's it. You probably have 2 options:
Add something into the ViewBag and grab it in the view
Render an action from a common controller that passes a strongly typed ViewModel to a partial view.
I'd discourage option 1 because in general it is good to avoid the ViewBag because it isn't strongly typed (Is using ViewBag in MVC bad?). Also, to do this you'd either have to inherit from a BaseController for every controller which can be a pain, or create a global action filter that overrides ActionExecuted and stuffs something in the ViewBag there.
Option 2 is probably better. I'd create a common controller something like:
public class CommonController : Controller
{
[ChildActionOnly]
public ViewResult Settings()
{
// Get some config settings etc here and make a view model
var model = new SettingsModel { Foo = myProject.Properties.Settings.Default.foo };
return View(model);
}
}
Then in your layout file you can call:
#Html.Action("Settings", new { controller = "Common" })
Which renders a strongly-typed partial view (~/Views/Common/Settings.cshtml) which looks like:
#model YourProject.Models.SettingsModel
#if(Model.Foo)
{
// So something
}
That way you are still using a strongly typed model and view, your layout view stays clean and simple and your partial view remains 'dumb'
The app settings are stored in the web.config file as
<applicationSettings>
<YourProject.Properties.Settings>
<setting name="Setting" serializeAs="String">
<value>asdqwe</value>
</setting>
so you can try use ConfigurationManager.AppSettings dictionary like
ConfigurationManager.AppSettings["Setting"]

ScaffoldColumn(false) not working because it is a FK

I am using ASP.NET Dynamic Data. The page dynamically creates a List, Edit, Details pages to display the records stored in the table in the DB.
I have the Sub Contractors in the table but I want its visibility set to false on screen.
I've tried
[HideColumnIn(PageTemplate.List)]
[Display(Name = "SubContractor Id", Order = 70)]
public object SubContractorId { get; set; }
ALSO:
[ReadOnlyColumnIn(PageTemplate.List)]
But no joy. Iv made these changes in the database.cs file.
Anyone know how can I make it disappear or remove the hyperlink from it?
EDIT:
[ScaffoldColumn(false)] usually works but because SubContractorId is a FK it seems to not take effect.
Consider the possibility of using Custom pages (List and other) for your Dynamic Data site which allows you hide specific fields.
For more information: How to: Customize the Layout of an Individual Table By Using a Custom Page Template

How to use areas with controllers from a different assembly?

I'm starting a new ASP.NET MVC project, and I decided to put my controllers in a different assembly. Evertyhing works fine, but I have hit a problem: I created a new area in my MVC Project, called Administration. I have an AdminController Class in my seperate assembly which is supposed to return views from my Admin area, but everytime it tries to return a view,
it looks for it in the wrong place (~/Admin/SomeView.cshtml Instead of ~/Administration/Admin/SomeView.cshtml)
How can I tell the controller to look for views in the wanted area?
Please take a look into this article. And also you problem was answered here.
Basically you will need to extend MvcViewEngine, to tell MVC to look for your Views in the different from standatd pathes:
public class YourMegaViewEngine : WebFormViewEngine
{
public YourMegaViewEngine ()
{
ViewLocationFormats = new string[]
{
"~/Views/Administration/{1}/{0}.cshtml" //I may be wrong for you case, but this is the place to puth you path
};
}
}

Binding a radgrid to a tree like data structure

I have a structure that looks following
Class TreeNode {
public TreeNode Parent { get; }
public IEnumerable<TreeNode> Children { get; }
public . . . .
}
I want to bind this to a asp.net telerik radgrid with detail tables for each level of the children. I know that radgrid supports declarative binding to a self referencing hierarchy using a datasource control but that assumes you have a flat dataset (e.g. from a database) and can look at a parent key field of some sort. My question has anyone bound a radgrid to a data structure like this before and is there a way to do it declaratively or mostly declaratively?
I can't answer your question directly since I've no experience with the telerik grid, but I can offer a work around.
Add a method to your class that flattens its contents into a self-referencing table like structure such as the one you mentioned. This way you can still work with the class and it's more advanced structure like you want to, but can still output the contents in a consumable form that matches the expectations of the UI components.
This is also a good candidate for an extension method too.
Another possible way I can think of is to build the hierarchy dynamically by filtering the date for the child tables based on their parent inside the DetailTableDataBind grid handler. This demo is a good reference:
http://demos.telerik.com/aspnet-ajax/grid/examples/programming/detailtabledatabind/defaultcs.aspx
but I must agree that Stephen's suggestion might be more handy.
Dick

Resources