Stop ASP.NET MVC from calling all getters in a model class - asp.net

If you define the following two properties on your model class this will crash with a NullReferenceException during model binding:
public Customer Customer { get; private set; } //set in the action method
public bool Name => Customer.Name;
This is because Customer is still null during model binding and ASP.NET MVC calls the getter for Name.
The stack is:
System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component) +525
System.Web.Mvc.ModelMetadata.get_Model() +34
System.Web.Mvc.DataAnnotationsModelValidator.Validate(Object container) +151
System.Web.Mvc.<Validate>d__1.MoveNext() +387
System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +163
System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +83
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1754
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +460
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +137
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +982
System.Web.Mvc.<>c__DisplayClass22.<BeginExecuteCore>b__1e() +39
System.Web.Mvc.Async.AsyncResultWrapper.<.cctor>b__0(IAsyncResult asyncResult, Action action) +21
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137
From the stack it looks like model validation is querying all getters. I'm not using model validation.
How can I deal with this situation? Can I make ASP.NET MVC not call all getters without any (apparent) reason?

So the Model Binder new's up an instance of your Model, then is probably doing reflection over the model's properties to look for named matches with the values in the FormCollection. What's happening is that the Customer prop is null when that dangerous Name prop is called, thus the NullRef.
The order by which .NET is checking those properties might not be actually random, but your code will be much improved by just treating it as such. Calling a method/prop directly on a Class that's nullable by default is a terrible idea, unless you check it for null. You have two options here, either (1) redesign your Model class so that the Constructor initializes the "Customer" property, or (b) add a null-check in that "Name" method.
Here's the easiest approach to just null-checking it when you grab it:
public bool Name => Customer?.Name ?? false;
This does not solve the underlying issue, which is that you have a Model that has nullable props chained together. Don't worry about your Model's constructor messing up your model binding. The Model Binder will (1) initialize your model class, then (2) try to hydrate it. So initializing the Customer class/prop in your Model's constructor won't impact any mapping of UI fields to say that Customer's fields.

The DefaultModelBinder in MVC version 5.2.3 does validation in addition to binding, and there is no way to shut it off completely. Other SO posts mention turning off the implicit required attribute for value types with the following line of code in your Global.asax.cs, Application_Start() method...
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
See: https://stackoverflow.com/a/2224651 (which references a forum with an answer directly from the asp.net team).
Given your stack trace, that might fix your immediate problem. However, that probably won't be enough due to the DefaultModelBinder calling the getters even outside of its validation code for no stated reason (the source code makes no comment as to why it does that).
To solve the problem on my projects, where I use calculated properties all the time similar to your example, I implemented a custom model binder based on the original DefaultModelBinder source code that does not call any getters.
See a more detailed explanation and my full solution here: https://stackoverflow.com/a/54431404/10987278.

Related

Googlebot and other spiders cannot access our Asp.net site in iis8 (only browsers work)

Googlebot and other spiders cannot access my site at all they get server error 500 and cannot crawl or whatever, when using google fetch as its fetches and rendering but when it gonna crawl it gets the error below. all kind of spiders gets the same error. Is it something i must put in the code to allow spiders like googlebot? the robots.txt is fine and also the sitemap.
the error code from the spiders or googlebot is this below:
Server Error in '/' Application. Object reference not set to an
instance of an object. Description: An unhandled exception occurred
during the execution of the current web request. Please review the
stack trace for more information about the error and where it
originated in the code.
Exception Details: System.NullReferenceException: Object reference not
set to an instance of an object.
Source Error:
An unhandled exception was generated during the execution of the
current web request. Information regarding the origin and location of
the exception can be identified using the exception stack trace below.
Stack Trace:
[NullReferenceException: Object reference not set to an instance of an
object.] Utbildningsportalen.WebUI.Controllers.HomeController.Index()
+28 lambda_method(Closure , ControllerBase , Object[] ) +86 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext
controllerContext, IDictionary2 parameters) +228
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext
controllerContext, ActionDescriptor actionDescriptor, IDictionary2
parameters) +89
System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult
asyncResult, ActionInvocation innerInvokeState) +38
System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult
asyncResult) +74
Edit 1:
HomeController method
public ActionResult Index()
{
if (!Request.UserLanguages[0].Contains("sv"))
{
var engStart = startHelper.allEngStartPages().FirstOrDefault();
engStart.RowNumber = 12 / engStart.PresentationObjectsPerRow;
return View(engStart);
}
var start = startHelper.allSweStartPages().FirstOrDefault();
start.RowNumber = 12 / start.PresentationObjectsPerRow;
return View(start);
}
Edit2:
And then we tried with this and it still couldn't access the site:
public ActionResult Index()
{
StartpageViewModel start;
if (Request.UserLanguages != null)
{
if (!Request.UserLanguages[0].Contains("sv"))
start = startHelper.allEngStartPages().FirstOrDefault();
else
start = startHelper.allSweStartPages().FirstOrDefault();
}
else
start = startHelper.StartPagesByLang("sv");
start.RowNumber = 12 / start.PresentationObjectsPerRow;
return View(start);
}
Considering your exception occurs in the Index method, I expect the UserLanguages property is empty, or even Null.
Check if it is null and has an index 0 before checking if it's Swedish. You could use those nifty null conditional indexer operators.
If that is in fact the problem; it's interesting bots dont send a accept-language header.

EntityContext throwing "not marked as serializable" in UnitOfWork Pattern using State Server

Background is ASP.NET WebForms application using Entity Framework with Repository and UnitOfWork pattern. Note that the application is also configured to use the out-of-proc StateServer for Session mgt which I understand means that anything I store in session must be serializable.
I also have an HttpModule configured to create a UnitOfWork object (which contains my entity context object) upon each HttpRequest, store it in HttpContext.Current.Items, and of course dispose it at the end of each request.
My UnitOfWork class itself contains properties for each of my repositories as well as the entity context itself.
In an effort to allow more flexible testing in the future, I created an IObjectContext interface with signatures for the methods and properties on my entity context, and I created a partial class for my entity context and inherited from it.
public class UnitOfWork : IUnitOfWork
{
private IObjectContext context;
}
public UnitOfWork(IObjectContext context)
{
this.context = context;
}
public partial class MyEntities : IObjectContext
{
}
private static void ApplicationBeginRequest(Object source, EventArgs e)
{
if (!HttpContext.Current.Items.Contains("UnitOfWork"))
{
IUnitOfWork unitOfWork = new UnitOfWork();
HttpContext.Current.Items.Add("UnitOfWork", unitOfWork);
}
}
private void ApplicationEndRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Items["UnitOfWork"] != null)
((IUnitOfWork)HttpContext.Current.Items["UnitOfWork"]).Dispose();
}
The goal here is ultimately to allow me to fake my entity context object to create for example, an in-memory context for testing purposes.
Everything was going fine until I started getting "not marked as serializable" exceptions on my entity context object. Obviously my first thought was to just add [Serializable] to my partial entity context class, but then it started complaining that System.Data.Objects.ObjectContext in Assembly System.Data.Entity was not marked as serializable (which I obviously don't have any control over).
What am I missing here? It seems like I can't store my entity context object in HttpContext.Current.Items, which I must do for my unit of work pattern implementation.
Is this because I'm using the ASP.NET State Server instead of in-proc session mgt? Surely there's a way to store the context for the life of the HTTP request if you're using the State Server?
Just feel like I'm missing something obvious here. I've added [Serializable] to everything from the UnitOfWork to the MyEntities context to each repository class. Still can't get past the entity context itself.
Any ideas?
UPDATE (Adding Stack Trace):
[SerializationException: Type 'myDAL.Model.myEntities' in Assembly 'myDAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +14324629
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +408
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +420
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +532
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) +969
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +633
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +322
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1487
[HttpException (0x80004005): Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.]
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +2485899
System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value, BinaryWriter writer) +49
System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer) +746
System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item, Stream stream) +336
System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item, Int32 initialStreamSize, Byte[]& buf, Int32& length, Boolean compressionEnabled) +99
System.Web.SessionState.OutOfProcSessionStateStore.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) +3828904
System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs) +1021
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165
The stack trace indicates that there is a non-serializable object in the session, not in the context. Double check that you did not put your data object in session by mistake.
Putting it into the context request should not be giving this error.

SignalR returns error - Unexpected end when deserializing object

I have simple project, where I'm using signalR, When page loads, signalR scripts are loaded succefully, however right after that, call to
http://localhost:24634/signalr/signalr/connect?transport=foreverFrame&connectionId=dca2db9c-b16a-4b96-96dc-9a6b187b6d9e&connectionData=[{"name":"notifier"}]&tid=5&frameId=1
returns 500 Internal Server Error, I checked this request in fiddler, error message says
Unexpected end when deserializing object.
Here's my Hub Definitin
[HubName("notifier")]
public class PublishingNotifier: Hub
{
[HubMethodName("send")]
public void SendMessage(string message)
{
Clients.getNotification(message);
}
}
and here's my client code
$(function () {
var publishingNotifier = $.connection.notifier;
publishingNotifier.getNotification = function (message) {
// do something
};
$('input[type=submit][id*=cmsB_ChangeStatusToPublishedTop]').on('click', function (e) {
// do something else
});
$.connection.hub.start();
});
Any ideas what can be cause of this error ?
EDIT
Here is Stack Trace information
[JsonSerializationException: Unexpected end when deserializing object.
Line 1, position 2.]
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CheckedRead(JsonReader
reader) +75
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader
reader, Type objectType, JsonContract contract, JsonProperty member,
Object existingValue) +48
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader
reader, Type objectType, JsonContract contract, JsonProperty member,
Object existingValue) +86
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IWrappedCollection
wrappedList, JsonReader reader, String reference, JsonArrayContract
contract) +635
Newtonsoft.Json.Serialization.<>c_DisplayClass1.<CreateAndPopulateList>b_0(IList
l, Boolean isTemporaryListReference) +124
Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList(Type
listType, Action2 populateList) +546
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateList(JsonReader
reader, String reference, JsonArrayContract contract) +101
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader
reader, Type objectType, JsonContract contract, JsonProperty member,
Object existingValue, String reference) +62
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader
reader, Type objectType, JsonContract contract, JsonProperty member,
Object existingValue) +113
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueNonProperty(JsonReader
reader, Type objectType, JsonContract contract, JsonConverter
converter) +118
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader
reader, Type objectType) +125
Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader,
Type objectType) +311
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type,
JsonSerializerSettings settings) +107
Newtonsoft.Json.JsonConvert.DeserializeObject(String value,
JsonSerializerSettings settings) +66
SignalR.JsonNetSerializer.Parse(String json) +57
SignalR.Hubs.HubDispatcher.CreateConnection(String connectionId,
IEnumerable1 groups, IRequest request) +140
SignalR.PersistentConnection.ProcessRequestAsync(HostContext context)
+227 SignalR.Hubs.HubDispatcher.ProcessRequestAsync(HostContext context) +120
SignalR.Hosting.AspNet.AspNetHandler.ProcessRequestAsync(HttpContextBase
context) +463
SignalR.Hosting.AspNet.HttpTaskAsyncHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext
context, AsyncCallback cb, Object extraData) +68
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
+301 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
EDIT2:
One more note - from the page that runs without any errors, requested url looks like this
localhost:24634/signalr/signalr/connect?transport=foreverFrame&connectionId=98e6d5b3-b164-4013-92c2-418aa6254f9e&connectionData=%5B%7B%22name%22%3A%22notifier%22%7D%5D&tid=7&frameId=1
and the failing request url looks like this
localhost:24634/signalr/signalr/connect?transport=foreverFrame&connectionId=9b398750-99d6-4188-88b5-b41ad9eb82d5&connectionData=[{"name":"notifier"}]&tid=1&frameId=1
As you may notice, the ways connectionData query string parameter is defined in urls are different, in particular, for the first url, connectionData has been url encoded the query string value, and the second query string parameter has been html encoded. I've looked into request headers, failing request Content-Type is text/html, and the second request's Content-Type: application/json.
EDIT 3:
I've found where connectionData get's parsed, in jquery.signalR-0.5.3.js file, here's code that actually encodes connectionData value
if (connection.data) {
qs += "&connectionData=" + window.escape(connection.data);
}
as you can see, window.escape() is responsible for encoding connectionData, but, if I debug this code, I can see that window.escape(connection.data) indeed html encodes connection.data instead of url encoding. But this is happening only on one page, on anothers, it works as expected.
To sum up, the problem turned out to be that window.escape was overridden by a third party JS library. This caused window.escape to behave differently than "normal" causing SignalR to fail as a side-effect.
So basically - when these "weird" issues occur - check if you have included libraries that "interfere" and make sure to use proper namespacing ( e.g. using the module pattern ) to avoid this issue.
BUG
I do not know if this could help, but I had the error "unexpected end when deserializing object message c #", when I was trying to deserialize my json.
It happened to me sometimes, sometimes not. I do not know what it depends on.
My json was like that:
https://api.myjson.com/bins/l83m8
Debugging the Xamarin App on visual studio 2019 gives me the following:
var content = await _client.GetStringAsync(Connection.URL);
invitaciones = JsonConvert.DeserializeObject<RootObject>(content);
The variable "content" sometimes gives me https://textsaver.flap.tv/lists/2lss and sometimes gives me https://textsaver.flap.tv/lists/2lsu.
If you look very carefully, you are gonna release that both are different, only because, the first one is missing a } just in the end.
If you deserialize both with https://www.unserialize.me/ tool, and then validate the result on https://jsonformatter.curiousconcept.com/ (default options), you are gonna see that the first one isn't valid, and the second is valid.
Solution:
Add a validation: if the string content (json) don't ends with }, put a } on the end.I know it's pretty silly, but solves my problem.
var content = await _client.GetStringAsync(Connection.URL);
if (!content.EndsWith("}"))
content = content + "}";
invitaciones = JsonConvert.DeserializeObject<RootObject>(content);
Packages: Newtonsoft.Json 12.0.2, Xamarin.Forms 3.6.0.344457 .

No parameterless constructor object defined

I know that this is a duplicate question but i can't find answer to my error.
I'm trying to show a list of my rooms saved in database but i get next error:
Server Error in '/' Application.
No parameterless constructor defined for this object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
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.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67
[InvalidOperationException: An error occurred when trying to create a controller of type 'HotelProjectFinal.Controllers.RoomController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +232
System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8969412
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
But i have a constructor withou a parameter:
namespace HotelProjectFinal.Controllers
{
public class RoomController : Controller
{
private IRoomRepository repository;
public RoomController(IRoomRepository roomRepository)
{
repository = roomRepository;
}
public ViewResult List()
{
return View(repository.Rooms);
}
}
}
My view is :
#model IEnumerable<HotelProjectFinal.Models.Room>
#{
ViewBag.Title = "List";
}
#foreach (var p in Model)
{
<div class="item">
<h3>#p.Room_number</h3>
#p.Room_Type
<h4>#p.Room_Type.Price.ToString("c")</h4>
</div>
}
I am using ninject:
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectKernel;
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
}
protected override IController GetControllerInstance(RequestContext requestContext,
Type controllerType)
{
return controllerType == null
? null
: (IController)ninjectKernel.Get(controllerType);
}
private void AddBindings()
{
ninjectKernel.Bind<IRoomRepository>().To<EFRoomRepository>();
}
}
}
You've got a controller factory, but the fact that the stacktrace says nothing about Ninject suggests you have forgotten to tell MVC about it.
You could fix that by adding a line to tell it that.
However the recommended practice is to hook Ninject in by adding a NuGet reference to Ninject.MVC3. There are docs about it on the associated Ninject MVC3 wiki.
Please try changing your constructors to the following:
public RoomController() { } // You were missing this parameterless constructor
[Inject]
public RoomController(IRoomRepository roomRepository)
{
repository = roomRepository;
}
Ninject is looking for a parameterless constructor because you haven't specified [Inject] above constructor that you wish to use for dependency injection. This has confused "Ninject" and caused an exception to be thrown.
The primary DI pattern is Constructor Injection. When activating an instance of a type Ninject will choose one of the type’s constructors to use by applying the following rules in order:-
If a constructor has an [Inject] attribute, it is used (but if you apply the attribute to more than one, Ninject will throw a NotSupportedException at runtime upon detection).
If no constructors have an [Inject] attribute, Ninject will select the one with the most parameters that Ninject understands how to resolve.
If no constructors are defined, Ninject will select the default parameterless constructor (assuming there is one).
More information can be found here:
https://github.com/ninject/ninject/wiki/Injection-Patterns
As pointed out by Ruben, [Inject] attribute pollutes the controller with external concerns.
This ties your code to a specific container. (Although Ninject does permits the customization of the specific attribute to look for, the point remains – you’re polluting an interface with external concerns.)
Your actual problem probably relies in a missing reference to Ninject.MVC3
Even though IRoomRepository could be null, that doesn't make it a parameterless constructor. At first glace, it looks like your IoC isn't wired up correctly for IRoomRepository. With no IoC, or misconfigured IoC, the controller activator looks for a parameterless constructor for your controllers.
// This is a parameterless constructor.
public RoomController()
{ }
// This is not a parameterless constructor.
public RoomController(IRoomRepository roomRepository)
{
repository = roomRepository;
}
Edit, Are you using Ninject.Mvc and your base MvcHttpApplication is implementing NinjectHttpApplication?

RadioButtonList exception

After I upgraded to the beta, I'm having trouble with Html.RadioButtonList. Can someone show me what I'm doing wrong?
The code:
<% Html.RadioButtonList(
"voter" + voter.Id,
new SelectList(new[]{"yes","no","abstain"}, "yes")).Each(x => Response.Write(x)); %>
And the exception I get:
[ArgumentNullException: Value cannot be null.
Parameter name: value]
System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, Boolean isChecked, IDictionary`2 htmlAttributes) +214
Microsoft.Web.Mvc.<>c__DisplayClass1.<RadioButtonListInternal>b__0(ListItem item) in c:\dd\Cicero\src\Mvc\main\src\MvcFutures\Mvc\RadioExtensions.cs:86
System.Linq.WhereSelectListIterator`2.MoveNext() +107
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +259
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +81
Microsoft.Web.Mvc.RadioListExtensions.RadioButtonListInternal(HtmlHelper htmlHelper, String name, SelectList selectList, Boolean usedViewData, IDictionary`2 htmlAttributes) in c:\dd\Cicero\src\Mvc\main\src\MvcFutures\Mvc\RadioExtensions.cs:88
Microsoft.Web.Mvc.RadioListExtensions.RadioButtonList(HtmlHelper htmlHelper, String name, SelectList selectList) in c:\dd\Cicero\src\Mvc\main\src\MvcFutures\Mvc\RadioExtensions.cs:29
Many thanks in advance!
Rob
It looks like you may have found a bug in the MVC framework. The other overloads of RadioButtonList seem to work just fine, but that particular overload barfs.
From looking at Reflector (and using the stack trace) I looks like things go awry at this line:
return selectList.GetListItems().Select<ListItem, string>(delegate (ListItem item) {
return htmlHelper.RadioButton(name, item.Value, item.Selected, htmlAttributes);
}).ToArray<string>();
In the Microsoft.Web.Mvc.RadioListExtensions.RadioButtonListInternal method. I assume this code worked fine in Preview 5?

Resources