I have an application that have EF 16 classes that share this information: They all are classes only with a key field and a description.
I think it should be a waste if I make a controller with just 1 method just to present a form to fill these classes info, then I was thinking in to make a generic form(with key, description) and dynamically fill the right class through a sort of selection the selected info in any way, any good suggestion or pattern to do that? Where the generic methods should be located.
Have you looked into MVC templates? You should be able to use templates to automatically "generate" your Edit and Display Views. No need to create a distinct View for each of your classes.
I had similar situation and did it almost like that:
interface IKeyDescription
{
int Key { get; set; }
string Description { get; set; }
}
public partial class Class1 : IKeyDescription;
public partial class Class2 : IKeyDescription;
public abstract class BaseKeyDescriptionController<T> where T : IKeyDescription
{
[Inject]
public IKeyDescriptionService<T> Service { get; set; }
[HttpGet]
public ActionResult List()
{
//View is stored in shared folder
return View("List",Service.List());
}
[HttpPost]
public ActionResult List(IList<T> elements)
{
Service.Save(elements);
....
}
}
public class Class1Controller : BaseKeyDescriptionController<Class1>
{
}
public class Class2Controller : BaseKeyDescriptionController<Class2>
{
}
View will inherit from System.Web.Mvc.ViewPage<IKeyDescription>.
Related
I have a model that is defined in EF database first edmx. From there I expose some tables and views (mainly views). As it's possible to augment the EF model with OData, how could I add a navigation property of a complex type to another EF and OData exposed type?
Currently I define a partial class and add the properties and attributes using them. But it looks like it's possible to add the desired properties with OData's modelbuilder functionality too, or perhaps better yet, first use ODataConventionModelBuilder and then augment the results. Alas, I'm unable to stitch together a working example from the existing API documentation and examples I've found.
Here's the code
//This class is generated from a view by EF (edmx)...
public partial class AccountView
{
public System.Guid Id { get; set; }
public int CompanyId { get; set; }
}
//Here's augmenting the EF generated view with some additional data...
[MetadataType(typeof(AccounViewMetaData))]
public partial class AccounView
{
//This is added here explicitly. AccountView itself exposes just
//a naked key, CompanyId.
public virtual Company Company { get; set; }
//This is just in case...
public class AccounViewDomainMetaData
{
//This is to add a navigation property to the OData $metadata. How to do this
//in WebApiConfig? See as follows...
[ForeignKey("Company")]
public int CompanyId { get; set; }
}
}
//This is an EF generated class one from an edmx..-
public partial class Company
{
public Company() { }
public int CompanyID { get; set; }
public string Name { get; set; }
}
//How to add a navigation property from AccountView to Company so that it'd become
//possible to call http://example.com/Accounts?$expand=Company and http://example.com/Accounts(1)?$expand=Company ?
var builder = new ODataConventionModelBuilder();
var companySet = builder.EntitySet<Entities.Company>("Companies");
var accountSet = builder.EntitySet<Entities.AccountView>("Accounts");
accountSet.EntityType.HasKey(i => i.Id); //EF has hard time recognizing primary keys on database first views...
//How to hide this from the result if there's a way to create a ?$expand=Company navigation property?
//accountSet.EntityType.Ignore(i => i.CompanyId);
This is related to my other question regarding OData and models.
I am reading a book on ASP.NET MVC, and it refers to "members of a view model class"? Specifically what are "members"? An example would help greatly!
Thanks!
A class member could be property, field, method, constant, event, ...
Here's an example of a view model with a property (which is a member):
public class MyViewModel
{
public string FooBar { get; set; }
}
or with a property and a method:
public class MyViewModel
{
public string FooBar { get; set; }
public string FormatTheFoo()
{
return string.Format("{0} bazinga", this.FooBar);
}
}
As far as events are concerned, well, they are indeed members, but in terms of an ASP.NET MVC view model, they are probably not something commonly used.
I'm starting to working on ASP.NET using MVC. I writing to action results, one of them is a HTTP GET and the another HTTP POST
[HttpGet]
public ActionResult DoTest()
{
Worksheet worksheets = new worksheets(..);
return View(w);
}
[HttpPost]
public ActionResult DoTest(Worksheet worksheet)
{
return PartialView("_Problems", worksheet);
}
Now, Worksheet class has a property called Problems and this is a collection, but uses as an abstract class item.
public class Worksheet
{
public List<Problem> Problems { get; set; }
}
Here's my abstract class and one implementation
public abstract class Problem
{
public Problem() { }
public int Id { get; set; }
public abstract bool IsComplete { get; }
protected abstract bool CheckResponse();
}
public class Problem1 : Problem
{
...
public decimal CorrectResult { get; set; }
// this is the only property of my implementation class which I need
public decimal? Result { get; set;}
public override bool IsComplete
{
get { return Result.HasValue; }
}
protected override bool CheckResponse()
{
return this.CorrectResult.Equals(this.Result.Value);
}
}
I have right now, many implementations of Problem class, but I really need to get just one value of my implementation class. But it thrown the above image error.
What can I do to allow model binder recover that part of my abstracts classes
The following code would not compile:
var problem = new Problem();
... because the Problem class is abstract. The MVC engine cannot just create a Problem directly. Unless you give it some way to know which type of Problem to instantiate, there's nothing it can do.
It is possible to create your own ModelBinder implementation, and tell MVC to use it. Your implementation could be tied to a Dependency Injection framework, for example, so that it knows to create a Problem1 whenever a Problem class is requested.
Or you could simply change your action method to take a concrete type:
public ActionResult DoTest(IEnumerable<Problem1> problems)
{
return PartialView("_Problems",
new Worksheet {
Problems = problems.Cast<Problem>().ToList()
});
}
I am using Data Annotations in my MVC 4 project with Scaffolding Nuget to create CRUD views. I am using Layer level Database model not EF.
So my Class look like as below:
[MetadataType(typeof(CustomerMetaData))]
public partial class UserProfile: IBrObject
{
public UserProfile(string aspUserName): this()
{
this.AspUserName = aspUserName;
}
public string AspUserName { get; set; }
public DateTime MetaDateFirstSaved { get; set; }
}
public class CustomerMetaData
{
[ReadOnly(true)]
[ScaffoldColumn(false)]
[DisplayName("ASP UserName")]
public object AspUserName { get; set; }
[DisplayName("Date First Saved")]
[DataType(DataType.Date)]
public object MetaDateFirstSaved { get; set; }
}
when i am trying to create views with Scaffolding Nuget it still shows AspUserName column not hide or not read only.
How i can hide or readonly ?
You use object in metadata and string and DateTime respectively in actual view model so they don't match.
Update
Another possibility (I pretty sure this is what's happening in your case) is because your model type in the view defined as Interface type rather than class type.
In your view replace #model IBrObject with #model UserProfile.
Hope this helps
object AspUserName != string AspUserName
I've got a series of views, each are typed to have their own ViewModel class which contains everything they need to display themselves, for example:
public class CreateResourceViewModel
{
public Project Parent { get; set; }
public SelectList Categories { get; set; }
public Resource Resource { get; set; }
}
The post action method for this I'd like to use would look like this:
[AcceptVerbs (HttpVerbs.Post)]
public ActionResult Create (Resource resource)
{
// Update code...
}
Notice that the only object I'm interested in is the Resource property of the CreateResourceViewModel, not the CreateResourceViewModel itself. Everything else is just gravy for for the user, what they're updating is the resource class...
Is this possible within the MVC Framework (even if it's v2 CTP)?
Thanks all
Sure. Use:
public ActionResult Create([Bind(Prefix="Resource")]Resource resource)