I'm trying to assign some values from FormCollection in my controller using UpdateModel.
Controller looks like:
public ActionResult EditValues(int id, FormCollection collection)
{
NamedClass picture = PictureProvider.GetById(id);
try
{
if(ModelState.IsValid)
{
UpdateModel(picture, collection);
}
}
catch {}
}
and at string UpdateModel(picture, collection); I've got an ArgumentException that says "Element with the same key has already been added" and nothing more..
"Collection" has same fields as "picture".. I'm not trying to add anything to "collection" that may cause such exception.. Tried to assign value to picture's field manually - OK.
Has anybody seen such trick? Thank you in advance!
UPD: May be StackTrace will be helpful..
System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
System.Web.Mvc.ModelBindingContext.get_PropertyMetadata()
System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model)
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
System.Web.Mvc.Controller.TryUpdateModel[TModel](TModel model, String prefix, String[] includeProperties, String[] excludeProperties, IValueProvider valueProvider)
System.Web.Mvc.Controller.UpdateModel[TModel](TModel model, String prefix, String[] includeProperties, String[] excludeProperties, IValueProvider valueProvider)
System.Web.Mvc.Controller.UpdateModel[TModel](TModel model, IValueProvider valueProvider)
Namedclass is:
public class NamedClass
{
[Key]
public virtual int id {get; set;}
public virtual string username {get; set;}
}
and the View that provides values is:
#model project.Models.NamedClass
#using (Html.BeginForm("EditValues", "PicController", FormMethod.Post))
{
#Html.HiddenFor(m=>m.id)
<div class="display-label">#Html.LabelFor(model=>model.username)</div>
<div class="display-field">
#Html.EditorFor(model => model.username)
</div>
<input type="submit" value="save" />
}
Why can't you just do it like this.
public ActionResult EditValues(NamedClass model)
{
if(ModelState.IsValid)
{
.. save to db
}
return View();
}
Related
Here is the query I try to execute:
var contests = await _dbContext.Contests.Include(o => o.Winner)
.Where(o=>o.Ended!=null)
.Select(c => new
{
Contest = c,
Strings = _dbContext.ContestCountryStrings.Where(o=>o.ContestId==c.Id && (o.Country.Equals(language) || o.Country.Equals("Default"))).ToList()
}).Take(3).ToListAsync();
And these are the entities:
[Table("Contests")]
public class Contest
{
public int Id { get; set; }
public DateTime DueTo { get; set; }
public uint DurationInHours { get; set; }
public DateTime? Started { get; set; }
public DateTime? Ended { get; set; }
public int? WinnerId { get; set; }
public User Winner { get; set; }
public bool Recurrent { get; set; }
public string ImageUrl { get; set; }
}
[Table("ContestCountryStrings")]
public class ContestCountryString
{
public int Id { get; set; }
public int ContestId { get; set; }
public Contest Contest { get; set; }
public string Country { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
When executed I get an exception like this:
fail:
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request. System.InvalidOperationException: EF.Property called with wrong
property name. at
Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression
methodCallExpression) at
System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor
visitor) at
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at
Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression
binaryExpression) at
Pomelo.EntityFrameworkCore.MySql.Query.ExpressionVisitors.Internal.MySqlSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression
binaryExpression) at
System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor
visitor) at
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at
Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression
expression) at
Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression
expression) at
Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.CreateJoinPredicate(Expression
outerKey, Expression innerKey) at
Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.CreateJoinPredicate(ShapedQueryExpression
outer, LambdaExpression outerKeySelector, ShapedQueryExpression inner,
LambdaExpression innerKeySelector) at
Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLeftJoin(ShapedQueryExpression
outer, ShapedQueryExpression inner, LambdaExpression outerKeySelector,
LambdaExpression innerKeySelector, LambdaExpression resultSelector)
at
Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression
methodCallExpression) at
Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression
methodCallExpression) at
System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor
visitor) at
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at
Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression
methodCallExpression) at
Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression
methodCallExpression) at
System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor
visitor) at
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at
Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression
query) at
Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression
query, Boolean async) at
Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase
database, Expression query, IModel model, Boolean async) at
Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_01.<ExecuteAsync>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func1 compiler) at
Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object
cacheKey, Func1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.GetAsyncEnumerator(CancellationToken
cancellationToken) at
System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable1.GetAsyncEnumerator() at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1
source, CancellationToken cancellationToken) at
MoneyAppBackend.Controllers.ContestsController._GetLas10PastEvents(EventType
type, String language) in
/Users/juanjoseduran/Documents/Development/Projects/dotnet/MoneyAppBackend/MoneyAppBackend/Controllers/ContestsController.cs:line
106 at
MoneyAppBackend.Controllers.ContestsController.GetAll(EventType type,
String lang, String uuid) in
/Users/juanjoseduran/Documents/Development/Projects/dotnet/MoneyAppBackend/MoneyAppBackend/Controllers/ContestsController.cs:line
57 at lambda_method(Closure , Object ) at
Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
at
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper
mapper, ObjectMethodExecutor executor, Object controller, Object[]
arguments) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker
invoker, ValueTask`1 actionResultValueTask) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker
invoker, Task lastTask, State next, Scope scope, Object state, Boolean
isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed
context) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State&
next, Scope& scope, Object& state, Boolean& isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown --- at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker
invoker, Task lastTask, State next, Scope scope, Object state, Boolean
isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker
invoker, Task task, IDisposable scope) at
Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint
endpoint, Task requestTask, ILogger logger) at
Microsoft.AspNetCore.Builder.Extensions.MapMiddleware.Invoke(HttpContext
context) at
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext
context)
If I remove the Take call it works correctly.
Like #NetMage said,Since the data you want to take is Contest type data, if you put the take after the Select is to operate on the data after the Select,The data obtained will not be of Contest type, it will cause an exception.
You can change your code like below:
var contests = await _dbContext.Contests.Include(o => o.Winner)
.Where(o=>o.Ended!=null).Take(3)
.Select(c => new
{
Contest = c,
Strings = _dbContext.ContestCountryStrings.Where(o=>o.ContestId==c.Id && (o.Country.Equals(language) || o.Country.Equals("Default"))).ToList()
}).ToListAsync();
My model is as follows:
public class testCreateModel
{
public string s1 { get; set; }
public SelectList DL { get; set; }
public testCreateModel()
{
Dictionary<string, string> items = new Dictionary<string, string>();
items.Add("1", "Item 1");
items.Add("2", "Item 2");
DL = new SelectList(items, "Key", "Value");
}
}
My initiating actions is:
public ActionResult testCreate()
{
testCreateModel model = new testCreateModel();
return View(model);
}
My Razor view (irrelevant parts deleted) is:
#model Tasks.Models.testCreateModel
#using (Html.BeginForm()) {
<fieldset>
<legend>testCreateModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.s1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.s1)
</div>
<div class="editor-label">
Select an item:
</div>
<div class="editor-field">
#Html.DropDownList("dropdownlist", (SelectList)Model.DL)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
The post back action is:
public ActionResult testCreate(testCreateModel model, FormCollection collection)
{
if (ModelState.IsValid)
{
Console.WriteLine("SelectedValue: ",model.DL.SelectedValue);
Console.WriteLine("FormCollection:", collection["dropdownlist"]);
// update database here...
}
return View(model);
}
On post back, model.DL.SelectedValue is null. (However, the selected item can be obtained from FormCollection, but that is besides the point). The DL object is still properly populated otherwise, Immediate Window output as follows:
model.DL
{System.Web.Mvc.SelectList}
base {System.Web.Mvc.MultiSelectList}: {System.Web.Mvc.SelectList}
SelectedValue: null
model.DL.Items
Count = 2
[0]: {[1, Item 1]}
[1]: {[2, Item 2]}
model.DL.SelectedValue
null
Q1: How can I make use of the SelectedValue property instead?
Now, if in the Razor view I change the name of the Html SELECT tag to DL (ie same as the property name in the model):
#Html.DropDownList("DL", (SelectList)Model.DL)
I get an exception:
No parameterless constructor defined for this object.
Stack Trace:
[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +199
System.Web.Mvc.DefaultModelBinder.BindSimpleModel(ControllerContext controllerContext, ModelBindingContext bindingContext, ValueProviderResult
...
Q2: Why?
Thanks.
MVC will return just the value of the selected option in your POST, so you need a property to contain the single value that returns.
As a good advice, try setting SelectLists through ViewBag, that helps keep your ViewModels clean from data that needs to populate the form.
So your example could be solved like this:
public class testCreateModel
{
public string s1 { get; set; }
public int SelectedValue { get; set; }
}
and in your View just do this:
#Html.DropDownList("SelectedValue", (SelectList)ViewBag.DL)
prior to populating ViewBag.DL in your GET action.
As for your Q2, the default ModelBinder requires that all types to bind to have a default constructor (so that the ModelBinder can create them)
An answer has been selected, but look at how I did it. Below is code how I normally do it when populating a drop down. It is very simplistic, I suggest you use it as a base to build your drop downs.
At the top of my view I specify my view model:
#model MyProject.ViewModels.MyViewModel
On my view I have a drop down list that displays all the banks that a user can select from:
<table>
<tr>
<td><b>Bank:</b></td>
<td>
#Html.DropDownListFor(
x => x.BankId,
new SelectList(Model.Banks, "Id", "Name", Model.BankId),
"-- Select --"
)
#Html.ValidationMessageFor(x => x.BankId)
</td>
</tr>
</table>
I always have a view model for a view, I never pass a domain object directly to the view. In this case my view model will contain a list of banks that will be populated from the database:
public class MyViewModel
{
// Other properties
public int BankId { get; set; }
public IEnumerable<Bank> Banks { get; set; }
}
My bank domain model:
public class Bank
{
public int Id { get; set; }
public string Name { get; set; }
}
Then in my action method I create an instance of my view model and populate the banks list from the database. Once this is done then I return the view model to the view:
public ActionResult MyActionMethod()
{
MyViewModel viewModel = new ViewModel
{
// Database call to get all the banks
// GetAll returns a list of Bank objects
Banks = bankService.GetAll()
};
return View(viewModel);
}
[HttpPost]
public ActionResult MyActionMethod(MyViewModel viewModel)
{
// If you have selected an item then BankId would have a value in it
}
I hope this helps.
I would like to use my custom binder to deal with the constructor (necessary) and then have the default modelbinder fill in the rest of the properties as normal.
Edit: The custom one would run first of course.
Mo.'s answer is correct. Inherit from the DefaultModelBinder then override CreateModel.
I'm just posting to provide sample codes.
The binder:
public class RegistrationViewModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
return new RegistrationViewModel(Guid.NewGuid());
}
}
The model:
public class RegistrationViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public Guid Id { get; private set; }
public RegistrationViewModel(Guid id)
{
Id = id;
}
}
If your property will be settable (In this case its the Id), you need to exclude it from the bind:
[Bind(Exclude = "Id")]
public class RegistrationViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public Guid Id { get; set; }
}
Thanks guys, I think I have found a solution, and that is to override the createmodel method of defaultmodelbinder. I had additional help from here:
http://noahblu.wordpress.com/2009/06/15/modelbinder-for-objects-without-default-constructors/
It needed updating to use modelmetadata instead of setting the modeltype as shown in that link, due to a change they made in mvc.
This is what I have ended up with as a first try that seems to work:
namespace NorthwindMVCApp.CustomBinders{
public class NewShipperBinder<T> : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
Type type1 = typeof(T);
ConstructorInfo[] constructors = type1.GetConstructors();
ConstructorInfo largestConstructor = constructors.OrderByDescending(x => x.GetParameters().Count()).First();
ParameterInfo[] parameters = largestConstructor.GetParameters();
List<object> paramValues = new List<object>();
IModelBinder binder;
string oldModelName = bindingContext.ModelName;
foreach (ParameterInfo param in parameters)
{
string name = CreateSubPropertyName(oldModelName, param.Name);
//bindingContext.ModelType = param.ParameterType;
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, param.ParameterType);
bindingContext.ModelName = name;
if (!System.Web.Mvc.ModelBinders.Binders.TryGetValue(param.ParameterType, out binder))
binder = System.Web.Mvc.ModelBinders.Binders.DefaultBinder;
object model = binder.BindModel(controllerContext, bindingContext);
paramValues.Add(model);
}
// bindingContext.ModelType = typeof(T);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(T));
bindingContext.ModelName = oldModelName;
Debug.WriteLine(Environment.StackTrace);
object obj = Activator.CreateInstance(type1, paramValues.ToArray());
return obj;
}
}
}
The class being bound is as follows. The reason for all of this is that it has no default constructor (to make sure that not-nullables are there):
namespace Core.Entities{
[EntityAttribute()]
public class Shipper
{
protected Shipper() : this("Undefined")
{
}
public Shipper(string CompanyName)
{
this.CompanyName = CompanyName;
Orders = new List<Order>();
}
public virtual int ShipperID { get; set; }
public virtual IList<Order> Orders { get; set; }
public virtual string CompanyName { get; set; }
public virtual string Phone { get; set; }
public override bool Equals(object obj)
{
Shipper obj_Shipper;
obj_Shipper = obj as Shipper;
if (obj_Shipper == null)
{
return false;
}
if (obj_Shipper.CompanyName != this.CompanyName)
{
return false;
}
return true;
}
public override int GetHashCode()
{
return CompanyName.GetHashCode();
}
}
}
And by the way the binder is included in global.asax as follows:
ModelBinders.Binders.Add(typeof(Shipper), new CustomBinders.NewShipperBinder<Shipper>());
So it will be easy to add the whole lot of entity classes (looping through), since I maintain a list of types of entities.
Thus I have been able to update that entity to the database.
Edit: A bit of icing, here is a stack trace:
at NorthwindMVCApp.CustomBinders.NewShipperBinder`1.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) in C:\Users\####\Documents\Visual Studio 2010\Projects\TestFluentNHibernate\NorthwindMVC\NorthwindMVCApp\CustomBinders\NewShipperBinder.cs:line 37
at System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
Have you already inherited from the DefaultModelBinder? I don't think it is possible to do what you intend - if you create a customer model binder and it implements IModelBinder the class must perform all necessary actions.
model is
public partial class BilingualString
{
public string RuString { get; set; }
public string EnString { get; set; }
}
public partial class Member
{
public Member()
{
this.DisplayName = new BilingualString();
}
public BilingualString DisplayName { get; set; }
}
if user don't fill inputs the values of RuString and EnString is null. I need string.Empty instead of null.
Using CustomModelBinder like this:
public class EmptyStringModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
return base.BindModel(controllerContext, bindingContext);
}
}
don't help.
Use this:
[DisplayFormat(ConvertEmptyStringToNull=false)]
public string RuString { get; set; }
OR
private string _RuString;
public string RuString {
get {
return this._RuString ?? "";
}
set {
this._RuString = value ?? "";
}
}
old question, but here's an answer anyway :)
The issue seems to be that the ConvertEmptyStringToNull is set on the model binding context, not the property binding context.
Inside the DefaultModelBinder, it calls BindProperty for each property of the model, and doesn't recurse simple objects like strings/decimals down to their own call of BindModel.
Luckily we can override the GetPropertyValue instead and set the option on the context there.
public class EmptyStringModelBinder : DefaultModelBinder
{
protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
{
bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
}
}
Worked for me :)
[edit]
As pointed out in comments.. This model binder will only work if registered, so after adding class, be sure to call
ModelBinders.Binders.Add(typeof(string), new EmptyStringModelBinder());
in the Application_Start() method of Global.asax.cs
I wanted to use a EF 4.1 code first pattern that was unit testable. I followed the code sample illustrated in an answer to This Post. But now I am getting an error that states "Multiple object sets per type are not supported". I am using the latest Structure Map for IoC as well. I am not sure how to trouble shoot this issue.
Multiple object sets per type are not
supported. The object sets
'MemberTypes' and 'MemberTypes' can
both contain instances of type
'SocialSite.Model.Entities.MemberType'.
Line 82: public virtual IEnumerable<T> FindAll()
Line 83: {
Line 84: return _dbSet.ToList();
Line 85: }
Line 86:
[InvalidOperationException: Multiple object sets per type are not supported. The object sets 'MemberTypes' and 'MemberTypes' can both contain instances of type 'SocialSite.Model.Entities.MemberType'.]
System.Data.Entity.Internal.DbSetDiscoveryService.RegisterSets(DbModelBuilder modelBuilder) +336
System.Data.Entity.Internal.LazyInternalContext.CreateModelBuilder() +393
System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) +22
System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input) +117
System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +407
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +17
System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +62
System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator() +15
System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator() +40
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +315
System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
SocialSite.Data.Repositories.Impl.Repository`1.FindAll() in D:\Visual Studio 2010\SocialSite\SocialSite.Data\Repositories\Impl\Repository.cs:84
SocialSite.Service.Impl.MemberTypesService.GetMemberTypes() in D:\Visual Studio 2010\SocialSite\SocialSite.Components\Impl\MemberTypesService.cs:23
SocialSite.Web.Areas.Admin.Controllers.MemberTypesController.ListMemberTypes() in D:\Visual Studio 2010\SocialSite\SocialSite\Areas\Admin\Controllers\MemberTypesController.cs:44
lambda_method(Closure , ControllerBase , Object[] ) +62
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862381
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
not sure how to format the stack trace any bertter than that.
here is the model in question.
public class MemberType
{
[Key]
public virtual int Id { get; set; }
[StringLengthAttribute(65, ErrorMessage = "Maximum length 65 characters")]
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual bool Registration { get; set; }
public virtual bool Enabled { get; set; }
[TimestampAttribute]
public virtual byte[] Timestamp { get; set; }
public virtual bool Activation { get; set; }
public virtual Guid RoleId { get; set; } // TODO: this should be a complex type of aspnet_Role or atleaset a foriegn key
public virtual bool Searchable { get; set; }
public virtual ICollection<MemberTypeProfileFieldGroup> MemberTypeProfileFieldGroups { get; set; }
}
The exception says that your DbContext (or perhaps some class referenced from your context defines DbSet<MemberType> MemberType twice. Each type can have only one defined DbSet. Code you posted has absolutely no relation to the exception. The exception is thrown when EF code first explores DbContext and creates model metadata from available DbSets