Newbie-ish questions ahead:
Where should I put my View Model declarations?
I created a file called "ViewModels.cs" in my Models folder.
I created a few View Model classes, including one called RatingViewModel:
using System;
using System.Collections.Generic;var
using System.Linq;
using System.Web;
namespace Web.Model
{
public class ViewModels
{
public class RatingViewModel
{
public User Rater { get; set; }
public Rating Rating { get; set; }
}
}
}V
Now I'm trying to create a helper/service class function that returns a new RatingViewModel object.
I created a "RatingsHelpers.cs" file.
But when I try to crate a new RatingViewModel object, it has no idea what I'm talking about.
I can't figure it out. Am I missing some reference? How can I create/return a new View Model object from my helper/service class?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using Web.Model;
namespace System.Web.Mvc
{
public static class RatingsHelpers
{
public static RatingViewModel functionname()
{ ..... }
But it doesn't know what "RatingViewModel" is...!?!?!?
I just know this should be obvious.
Pulling my hair out,
Johnny
To sum up:
You've created a ViewModels class inside the Web.Model namespace. This class declares a nested class called RatingViewModel
Inside the helper RatingsHelpers located in the System.Web.Mvc namespace you are trying to access the RatingViewModel class.
You could achieve this by using ViewModels.RatingViewModel but I wouldn't recommend you doing so. Nesting classes like this makes no sense.
Instead you could place each view model class into a separate .cs file and put it directly into the Web.Model namespace:
namespace Web.Model
{
public class RatingViewModel
{
public User Rater { get; set; }
public Rating Rating { get; set; }
}
}
Then inside the helper class use could use directly the RatingViewModel class.
The problem is that you put the RatingViewModel class inside the ViewModels class, which means that it's a child class of ViewModels. I'm not sure that's the behaviour you want.
If you want to call a child class you have to write ViewModels.RatingViewModel to reference the class.
Expanding on what scripni said. Having a RatingViewModel class nested inside a ViewModels class inside the Web.Models seems superfluous. You probably want to get rid of the outer ViewModels class.
Related
so i have the next problem. I have a controller and some user roles. I'm using string when i have [Authorize(Roles="Admin")] but i want to use an enum like that because if i change the name of role i will modify in one single place.
I already tried Roles=UserRoles.Admin.ToString(), where UserRoles is my enum but i'm getting an error. I already read aricles from here but seems that no one helps me to solve my problem.
Could you help me with any suggestion?
Create a custom AuthorizeAttribute like this:
using System.Collections.Generic;
using System.Web.Mvc;
namespace MyApp.Whatever
{
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public CustomAuthorizeAttribute(params UserRoles[] userRoles)
{
Roles = string.Join(",", userRoles);
}
}
}
Then you can use it as you would usually use the AuthorizeAttribute, like this:
using System.Web.Mvc;
namespace MyApp.Whatever
{
[CustomAuthorize(UserRoles.Admin, UserRoles.Whatever)]
public class MyController : Controller
{
...
}
}
This can be done, but you need to do a little work.
Create you own custom attribute implementing IAuthorizationFilter (as AuthorizeAttribute does)
Accept your enumeration in its constructor (or via a property)
Forward operations to a contained instance of AuthorizeAttribute
(The whole filter mechanism is extensible to allow this kind of thing.)
However, what I have done in the past, to deal with this is to define a series of constant strings which are passed to the attribute's instances. Thus keeping the names central.
My question is very simple, I am using Entity Framework with asp.net MVC.
I am not sure this question is helpful or not, but I have a doubt.
How entity framework should known, that he has to add migration for which class, why EF will not generate migration for ViewModel class ?
I am just want to know how EF will differentiated between ViewModel.cs class and Model.cs class and add migration only for model.
Thanks in advance.
I think it checks which classes have been added to a DbContext.
using System.Data.Entity;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;
namespace MigrationsDemo
{
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
}
}
Blog will now be considered with the migration. Please see this link for more information on code-first migrations: https://msdn.microsoft.com/en-us/data/jj591621.aspx
There are some places that you can add configuration to Entity Framework, but in its basic form, it iterates the properties on your DbContext class (with a public get), and considers all properties of type IDbSet to be a part of the data model.
The properties do not have to have a set. For example, this is a valid entity definition in DbContext that EF will pick up and generate Migration for:
public IDbSet<MyEntity> MyEntities
{
get { return Set<MyEntity>(); }
}
I'm learning asp.net mvc3 from w3schools and following that tutorial.http://w3schools.com/aspnet/mvc_models.asp In the section "ASP.NET MVC Models" I have created the model like this.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace MvcDemo.Models
{
public class MovieDB
{
public int ID { get; set; }
public string Title { get; set; }
public string Director { get; set; }
public DateTime Date { get; set; }
}
public class MovieDBContext : DbContext
{
public DbSet<MovieDB> Movies { get; set; }
}
}
Then I was going to add a controller according to the instructions.
In the Solution Explorer, right-click the Controllers folder, and select Add and Controller
Set controller name to MoviesController
Select template: Controller with read/write actions and views, using Entity Framework
Select model class: MovieDB (McvDemo.Models)
Select data context class: MovieDBContext (McvDemo.Models)*
Select views Razor (CSHTML)
Click Add
But the problem I have is that the drop down list doesn't show MovieDB (McvDemo.Models) in Model Class and Data Context Class to be selected. Can anyone please help me? Thanks.
You should just be able to recompile (Shift-Ctrl-B) and then try it again - it will be there. Otherwise you can always just declare it yourself at the top of a blank view, but that will not provide the scaffolding that the generator does:
#model MvcDemo.Models.MovieDB;
I recompiled but that did not fix the issue for me and yes I am doing the same thing and ran into the same exact issue. The problem for me was caused by visual web developer not being able to connect to my Movies database. I had to change the definition of my connectionString within web.config like this:
<add name="MovieDBContext"connectionString="Data Source=c:\sites\w3schools_demo\MvcDemo2\MvcDemo2\App_Data\Movies.sdf" providerName="System.Data.SqlServerCe.4.0"/>
If you are having this issue you will need to change the "Data Source" path to point to your Movies.sdf database file.
So I am new to MVC and am working now with MVC3 and the Entity Framework. I am currently using a Model/Schema 1st approach as the database already exists. Therefore I create my ADO.NET Entity Data Model (.edmx) and I have all the needed entities in my MVC app. So far so good on all this.
However let's say one of my Entities is a 'Customer' entity. I can see the auto-generated partial class inheriting from EntityObject in MyEntites.Designer.cs. At this point I want to add some custom business logic to my MVC Model. Natuarally I believe the answer is to use my own partial class created in the Model named 'Customer' as well.
I did a lot of searching on this before asking the question and see all kinds of information on POCO, T4 templates, modifying auto-generated code, etc and am lost. Is it a royal pain to add my own business logic and custom code to the auto-generated entities from EF? I certainly don't want to modify the auto generated code over and over.
I need a straight forward explanation to make the proverbial 'light bulb' go on, and then I can take-off from there. Can someone help me answer how to do this please?
Thanks!
Keep your own class code in a different file, but use the same class and namespace. This will help avoid your code being overwritten by the T4 code generator.
Extending Entity Framework Generated Types
You can also add attributes to generated classes by using a meta class:
Adding Attributes to Generated Classes
Those codes are auto-generated and will be over written on each model update or change.
You can achieve what you need through extending models. Suppose that EF generated the following entity class for you:
namespace YourSolution
{
using System;
using System.Collections.Generic;
public partial class News
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int UserID { get; set; }
public virtual UserProfile User{ get; set; }
}
}
and you want do some work arounds to preserve your you data annotations and attributes. So, follow these steps:
First, add two classes some where (wherever you want, but it's better to be in Models) like the following:
namespace YourSolution
{
[MetadataType(typeof(NewsAttribs))]
public partial class News
{
// leave it empty.
}
public class NewsAttribs
{
// Your attribs will come here.
}
}
then add what properties and attributes you want to the second class - NewsAttribs here. :
public class NewsAttrib
{
[Display(Name = "News title")]
[Required(ErrorMessage = "Please enter the news title.")]
public string Title { get; set; }
// and other properties you want...
}
Notes:
1) The namespace of the generated entity class and your classes must be the same - here YourSolution.
2) your first class must be partial and its name must be the same as EF generated class.
Go through this and your attribs never been lost again ...
In ASP.NET MVC is there a way to enumerate the controllers through code and get their name?
example:
AccountController
HomeController
PersonController
would give me a list such as:
Account, Home, Person
Using Jon's suggestion of reflecting through the assembly, here is a snippet you may find useful:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
public class MvcHelper
{
private static List<Type> GetSubClasses<T>()
{
return Assembly.GetCallingAssembly().GetTypes().Where(
type => type.IsSubclassOf(typeof(T))).ToList();
}
public List<string> GetControllerNames()
{
List<string> controllerNames = new List<string>();
GetSubClasses<Controller>().ForEach(
type => controllerNames.Add(type.Name));
return controllerNames;
}
}
You can reflect through your assembly and find all classes which inherit from type System.Web.MVC.Controller. Here's some sample code that shows how you could do that:
http://mvcsitemap.codeplex.com/WorkItem/View.aspx?WorkItemId=1567
All who using this post better read this post before: using Assembly.GetCallingAssembly() not returns the calling assembly
The issue is that razor views are acting as independent dynamic assemblies and you don't get the desired assembly.
Yair
Create the property in every controller and then you get the name like this.