Unable to cast object of type to type 'System.Data.Objects.ObjectContext - entity-framework-4

I have been following the tutorial -> http://www.asp.net/web-forms/tutorials/getting-started-with-ef/the-entity-framework-and-aspnet-getting-started-part-2
I'm stuck in the topic - Revising EntityDataSource Control Markup to Improve Performance. When I set ContextTypeName property by removing ConnectionString and DefaultContainerName, i'm getting an error message;
Unable to cast object of type 'ContosoUniversity.DAL.SchoolEntities' to type 'System.Data.Objects.ObjectContext'.
Please note: Using the ConnectionString and DefaultContainerName works fine.

Try the link for MSDN Article below solved my problem when I was going through the same tutorial.
MSDN Article!
Just change SchoolContext to SchoolEntities in the method SchoolContextEntityDataSource_ContextCreating()
The code there is like this:
protected void SchoolContextEntityDataSource_ContextCreating(object sender, EntityDataSourceContextCreatingEventArgs e)
{
var db = new SchoolContext();
e.Context = (db as IObjectContextAdapter).ObjectContext;
}
And add
using System.Data.Entity.Infrastructure;
Best regards,
Adit Malik

First use from OnContextCreating method in EntityDataSource structral aspx code
and then implement OnContextCreating method:
protected void StudentsEntityDataSource_ContextCreating(object sender, EntityDataSourceContextCreatingEventArgs e)
{
var db = new ContosoUniversity.DAL.schoolEntities();
e.Context = (db as IObjectContextAdapter).ObjectContext;
}
and add:
using System.Data.Entity.Infrastructure;

Related

StructureMap 3 get requested type

I have the following StructureMap registrations that work in version 2.6.4 and I'm finally upgrading to the latest SM (3.1.2 as of this writing). And need to update it since there doesn't appear to be a IContext.BuildStack anymore.
Here is the old working version with 2.6.4:
initialization.For(typeof(IRepository<,>))
.Use(context =>
{
var genericArgs = context.BuildStack.Current.RequestedType.GetGenericArguments();
return RepositoryFactory.GetInstance(genericArgs[0], genericArgs[1], repositoryName);
}
);
So I figured that changing it to this would work:
initialization.For(typeof (IRepository<,>))
.Use("IRepository<,>", context =>
{
var genericArgs = context.ParentType.GetGenericArguments();
return RepositoryFactory.GetInstance(genericArgs[0], genericArgs[1],
repositoryName);
}
);
But context.ParentType is null. When I look at context.RootType it is set to System.Object which is obviously not what I want.
My test code to get an instance of this repository is:
var userRepository = ObjectFactory.GetInstance<IRepository<User, Guid>>();
I don't see any other property that has this information, but I'm guessing I am missing something.
You are not missing something. On GitHub someone posted a simular question: https://github.com/structuremap/structuremap/issues/288.
Jeremy Miller, the author of structuremap, responded:
It's going to have to be new development. It'll have to come in a 3.2 version.
The suggested workaround is to create a custom instance and override the ClosingType method. You can do this as follows:
public class CustomInstance : Instance
{
public override IDependencySource ToDependencySource(Type pluginType)
{
throw new NotImplementedException();
}
public override Instance CloseType(Type[] types)
{
var repository = RepositoryFactory.GetInstance(types[0], types[1], repositoryName);
return new ObjectInstance(repository);
}
public override string Description
{
get { throw new NotImplementedException(); }
}
public override Type ReturnedType
{
get { return typeof (IRepository<,>); }
}
}
Now, you only have to connect the open generic type to the closing type like this:
initialization.For(typeof (IRepository<,>)).Use(new CustomInstance());
I added a new example to the StructureMap 3 codebase for this scenario based on your question:
https://github.com/structuremap/structuremap/blob/master/src/StructureMap.Testing/Acceptance/builder_for_open_generic_type.cs
I have to ask though, what's the purpose of something like RepositoryBuilder if you're using an IoC container?
Anyway, this implementation should be more efficient than the older Reflection-heavy approach.

How to intercept all the ASP.NET WebApi controller action methods calls with Ninject interception for logging?

Our company has the need to log certain things each time one of our action methods of our ASP.NET WebApi controllers gets called. Since we use Ninject for the DI right now, we'd like to use it also for this purpose. This is what I have tried so far.
I have Ninject, Ninject.Extensions.Interception and Ninject.Extensions.Interception.DynamicProxy installed through NuGet and I have the following module
public class InterceptAllModule : InterceptionModule
{
public override void Load()
{
Kernel.Intercept(p => p.Request.Service.Name.EndsWith("Controller")).With(new TimingInterceptor());
}
}
Where TimingInterceptor is
public class TimingInterceptor : SimpleInterceptor
{
readonly Stopwatch _stopwatch = new Stopwatch();
protected override void BeforeInvoke(IInvocation invocation)
{
_stopwatch.Start();
}
protected override void AfterInvoke(IInvocation invocation)
{
_stopwatch.Stop();
string message = string.Format("[Execution of {0} took {1}.]",invocation.Request.Method,_stopwatch.Elapsed);
Log.Info(message + "\n");
_stopwatch.Reset();
}
}
Now, when I try to hook the module up with ninject kernel, and run my site
var kernel = new StandardKernel(new InterceptAllModule());
However, whenever there is a call coming in to one of the action method, it throws an error saying
Cannot instantiate proxy of class: MyApiController.
Could someone with experience point out what I'm doing wrong please? Thanks.
Update
So using your Code and Remo's excellent point about needing the action methods to be virtual and putting in an empty default constructor (just to placate dynamic proxy, keep your other constructor still) I have got both the action filter and the interception approach working.
I would say that as it stands your code will intercept potentially unwanted methods on the ApiController so you will probably also need to put some code in place to filter these out e.g. ExecuteAsync and Dispose.
My only other point is performance. Huge disclaimer these are just very basic tests (using the action filter approach each time to log the stats), I invite you to do your own(!)... but using the DynamicProxy interceptor I was getting a time of around 4 milliseconds per get request
[Execution of Get took 00:00:00.0046615.]
[Execution of Get took 00:00:00.0041988.]
[Execution of Get took 00:00:00.0039383.]
Commenting out the Interception code and using an Action filter I was getting sub millisecond performance:
[Execution of Get took 00:00:00.0001146.]
[Execution of Get took 00:00:00.0001116.]
[Execution of Get took 00:00:00.0001364.]
It is up to you whether this is actually an issue or concern but I thought I would point this out.
Previous Response
Have you rulled out using ActionFilters? This is the natural extension point for AOP on an MVC action.
If you were interested in methods other than the actual action on the controller then I would understand but I thought I would post a suggestion anyway.
Inspired by Are ActionFilterAttributes reused across threads? How does that work? and Measure Time Invoking ASP.NET MVC Controller Actions.
Updated to show the exclusion of the timer when method tagged. Inspiration from core WebApi framework specifically AllowAnonymousAttribute and AuthorizeAttribute
Register this globally so that all actions are monitored by this:
GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());
Then:
public class TimingActionFilter : ActionFilterAttribute
{
private const string Key = "__action_duration__";
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (SkipLogging(actionContext))
{
return;
}
var stopWatch = new Stopwatch();
actionContext.Request.Properties[Key] = stopWatch;
stopWatch.Start();
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (!actionExecutedContext.Request.Properties.ContainsKey(Key))
{
return;
}
var stopWatch = actionExecutedContext.Request.Properties[Key] as Stopwatch;
if(stopWatch != null)
{
stopWatch.Stop();
var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
Debug.Print(string.Format("[Execution of {0} took {1}.]", actionName, stopWatch.Elapsed));
}
}
private static bool SkipLogging(HttpActionContext actionContext)
{
return actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>().Any() ||
actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<NoLogAttribute>().Any();
}
}
And
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
public class NoLogAttribute : Attribute
{
}
Now you can exclude the global filter using:
public class ExampleController : ApiController
{
// GET api/example
[NoLog]
public Example Get()
{
//
}
}
For anyone still lurking, the reason I wanted to use Ninject was so I could inject a logger (or anything else) into the interceptor, but I wanted to intercept all actions.
Mark's answer is perfect, but instead of registering globally using
GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());
bind your filter with Ninject using
Kernal.BindHttpFilter<TimingActionFilter>(FilterScope.Action).
You'll need to create an appropriate contructor in the TimingActionFilter class.

Accessing ControllerContext from within a Delegate within the Global.asax

Is there any way to gain access to the controller that is currently executing from within Global.asax?
I'd like to design an API with similar syntax to:
MyClass.RegisterComponents().When(IController => /* Some condition */)
Although I could move this code to a place where the controller is in context, I'd like to keep it centralised and portable.
So far, I have been unable to obtain the controller. Any ideas?
I have considered creating a base controller and extending all of my controllers from this base class, however, I'd like to make this library portable with the ability to be installed via NuGet. For this reason I am unable to take this approach.
You can do following in your global.asmx file.
private void Application_BeginRequest(object sender, EventArgs e)
{
string controllerName = Request.RequestContext.RouteData.Values.Where(p => p.Key =="controller").FirstOrDefault(p => p.Key);
}
I found a solution to this. Not a very good one but it solves my problem.
Register a global IActionFilter using an assembly start up method I found on David Ebbo's blog (http://blog.davidebbo.com/2011/02/register-your-http-modules-at-runtime.html).
The global action filter simply stores the action context in the current HttpContext.Items[] collection which is a per request collection.
public class GlobalActionFilter : System.Web.Mvc.IActionFilter {
internal static readonly object ActionExecutedFilterKey =
"__MvcResourceLoaderActionExecutedContext";
internal static readonly object ActionExecutingFilterKey =
"__MvcResourceLoaderActionExecutingContext";
static MvcResourceLoaderGlobalFilter __instance =
new MvcResourceLoaderGlobalFilter();
MvcResourceLoaderGlobalFilter() { }
public void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext) {
System.Web.HttpContext.Current.Items[ActionExecutedFilterKey] =
filterContext;
}
public void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) {
System.Web.HttpContext.Current.Items[ActionExecutingFilterKey] =
filterContext;
}
public static void RegisterGlobalFilter() {
if (!System.Web.Mvc.GlobalFilters.Filters.Contains(__instance))
System.Web.Mvc.GlobalFilters.Filters.Add(__instance);
}
}
I can then access the context anywhere.

How to Unit Test JsonResult and Collections in MSTest

I am very new to unit testing even though i have been coding for a very long time. I want to make this a part of my way of development. I run into blocks on how to unit test things like a collection. I generally have my jQuery script calling ASP.Net Server side methods to get data and populate tables and the like. They look like
Get_*Noun*()
which generally returns a JsonResult. Any ideas on what and how to test these using Unit tests using MSTest?
You should be able to test this just like anything else, provided you can extract the values from the JsonResult. Here's a helper that will do that for you:
private T GetValueFromJsonResult<T>(JsonResult jsonResult, string propertyName)
{
var property =
jsonResult.Data.GetType().GetProperties()
.Where(p => string.Compare(p.Name, propertyName) == 0)
.FirstOrDefault();
if (null == property)
throw new ArgumentException("propertyName not found", "propertyName");
return (T)property.GetValue(jsonResult.Data, null);
}
Then call your controller as usual, and test the result using that helper.
var jsonResult = yourController.YourAction(params);
bool testValue = GetValueFromJsonResult<bool>(jsonResult, "PropertyName");
Assert.IsFalse(testValue);
(I am using NUnit syntax, but MSUnit shouldn't be far off)
You could test your JsonResult like this:
var json = Get_JsonResult()
dynamic data = json.Data;
Assert.AreEqual("value", data.MyValue)
Then in the project that contains the code to be tested, edit AssemblyInfo.cs file to allow the testing assembly access to the anonymous type:
[assembly: InternalsVisibleTo("Tests")]
This is so the dynamic can determine the type of anonymous object being returned from the json.Data value;
This is the best blog I've found on this subject.
My favorite was the 4th approach using dynamics. Note that it requires you to ensure that the internals are visible to your test project using [assembly:InternalsVisibleTo("TestProject")] which I find is a reasonably good idea in general.
[TestMethod]
public void IndexTestWithDynamic()
{
//arrange
HomeController controller = new HomeController();
//act
var result = controller.Index() as JsonResult;
//assert
dynamic data = result.Data;
Assert.AreEqual(3, data.Count);
Assert.IsTrue(data.Success);
Assert.AreEqual("Adam", data.People[0].Name);
}
You could use PrivateObject to do this.
var jsonResult = yourController.YourAction(params);
var success = (bool)(new PrivateObject(jsonResult.Data, "success")).Target;
Assert.IsTrue(success);
var errors = (IEnumerable<string>)(new PrivateObject(jsonResult.Data, "errors")).Target;
Assert.IsTrue(!errors.Any());
It's uses reflection similar to David Ruttka's answer, however it'll save you a few key strokes.
See http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.privateobject.aspx for more info.
Here's a small extension to easily convert a Json ActionResult into the object it represents.
using System.Web.Mvc;
public static class WebExtensions
{
public static T ToJson<T>(this ActionResult actionResult)
{
var jsonResult = (JsonResult)actionResult;
return (T)jsonResult.Data;
}
}
With this, your 'act' in the test becomes smaller:
var myModel = myController.Action().ToJson<MyViewModel>();
My suggestion would be to create a model for the data returned and then cast the result into that model. That way you can verify:
the structure is correct
the data within the model is correct
// Assert
var result = action
.AssertResultIs<JsonResult>();
var model = (UIDSearchResults)result.Data;
Assert.IsTrue(model.IsValid);
Assert.AreEqual("ABC", model.UIDType);
Assert.IsNull(model.CodeID);
Assert.AreEqual(4, model.PossibleCodes.Count());

Determine result type in OnException of controller

I'm working on an MVC.NET 2.0 project where I'm trying to put in some special error handling logic in the OnException method of the controller. Basically I want to be able to determine the result type of the controller method in which the unhandled exception was raised, so that I can return error data in a certain format dependent upon the type (json for JsonResult and html for ActionResult). Can anyone point me to a way to determine that type? I would greatly appreciate any help.
Thanks in advance
Assuming you didnĀ“t change the default routing:
protected override void OnException(ExceptionContext filterContext)
{
var action = filterContext.RouteData.Values["action"].ToString();
var type = filterContext.Controller.GetType();
var method = type.GetMethod(action);
var returnType = method.ReturnType;
//...do whatever here...
}
Good luck!

Resources