ServiceStack AutoQuery MVC controller - asp.net-mvc

I'm experimenting with ServiceStack in MVC, using standard server side controllers creating view models. There are no jquery calls (or any direct calls) to any of the services registered at /api. Since SS lets us resolve services directly using:
using (var dr = HostContext.ResolveService<DataReportService>(base.HttpContext))
I haven't been calling the services using JsonServiceClient. Instead I've been resolving the services and calling their methods directly.
var dataReport = new DataReport
{
IsArchived = false,
ReportDate = DateTime.Now,
ReportType = Model.ReportType
};
var drId = dr.Post(dataReport);
However, I have not been able to find a way to do this with the new AutoQuery feature. I know it creates a service automatically for any class that descends from QueryBase but I have had no luck resolving it. If I try to resolve the name used at run time then I won't compile (obviously). If I try something like this
using (var dr = HostContext.ResolveService<AutoQueryServiceBase>(base.HttpContext))
then it won't work either, because that is just a base class and not the actual registered instance. I know I could do this from JsonServiceClient but I'd really like to experiment with the direct call approach. Creating my own service that wraps any AutoQuery would work but seems like it defeats the purpose of the automatic creation. Still, I don't see any other way to proceed. Would love to hear any ideas.

Rather than using the ResolveService<T> method to get the service and call the executing method yourself, you can use HostContext.ServiceController.Execute method which allows you pass in the request DTO which will execute on the action method.
var dataReport = new DataReport
{
IsArchived = false,
ReportDate = DateTime.Now,
ReportType = Model.ReportType
};
var drId = HostContext.ServiceController.Execute(dataReport);
I hope this helps.

Related

how to implement User.identity.getUserEmail()

A user should have unique email instead of UserName. To achieve this I stored email in UserName and UserName in email column of AspNetUsers Table. Now I want to access user name in my view. The method User.Identity.GetUserName() is great, But now I need User.Identity.GetUserEmail(). I can I implement User.Identity.GetUserEmail() ?
Update:
I have to use User.Identity.GetUserEmail() in every view. As I use User.Identity.GetUserId().
I want to write this method in Microsoft.AspNet.Identity namespace so that it will be accessible everywhere.
I had to add a new value to the Identity model and to get the new value I did this:
private string GetUserEmail()
{
//Instantiate the UserManager in ASP.Identity system so you can look up the user in the system
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
//Get the User object
var currentUser = manager.FindById(User.Identity.GetUserId());
return currentUser.Email;
}
You can build this in a relevant controller, or it can be a static function somewhere else, you just need to have a reference to identity.
Personal note: I have to say that I don't fully support the idea to change between the username and email. I think you should consider editing the model instead , this link might help.
Let me start by saying that I don't like the idea of executing code in your view. Besides, if you do this everytime, you're breaking the DRY principle.
I think what you need here is the ASP.NET Identity framework. This allows you to customize the authentication & authorization process, including how and where to retrieve user information. By overriding the UserManager class, you can start overriding the methods you want (like GetEmailAsync). You could also modify the CreateUserIdentity method by changing the claims of the identity.
This way you only define your rule once, which you then can use all across your application. But in order to achieve this, you'll have to do some research about ASP.NET Identity yourself or post more accurate information (like your accountcontroller code).
When creating a user through the user manager you can apply some custom settings, one of these is requiring an unique email:
var um = new UserManager<User>(new UserStore<User>(new ApplicationDbContext()));
um.UserValidator = new UserValidator<User>(um)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = false
};

In MVC5 how can I create user records in code?

VS2013, MVC5, VB
The MVC5 template works well to create new users from the Register View while the application is running. But if I want to create users in code, how do I do that?
The following is naïve code, but demonstrates what doesn't work:
Dim user = New ApplicationUser() With {.UserName = "name#live.com", .Email = "name#live.com"}
Dim acct As New AccountController
acct.UserManager.CreateAsync(user, "Temp1.11")
This doesn't work because there is no HttpContext for UserManager.
There's a lot going on here that I don't understand and I'm a little lost. What I set out to do was simply create a list of users using the seed method in Configuration.vb. I thought I could just copy the way the existing AccountController.Register method works, but obviously not.
The answer to my question would ultimately be how to create users in the seed, but I'd like to also understand why my thinking was so wrong about simply trying to use portions of the code from the Register method. I don't quite understand the HttpContext and how that comes into being.
You don't need to use AccountController to get access to the UserManager object. Instead just create that directly:
Dim user = New ApplicationUser() With {.UserName = "name#live.com", .Email = "name#live.com"}
Dim myUserManager As New UserManager()
myUserManager.CreateAsync(user, "Temp1.11")

JSON-serialization of NHibernate entities using the builtin JsonResult in ASP.NET MVC yields circular dependency error

I'm trying to return a JSON list of stuff from my server via an ASP.NET MVC front layer:
var stuff = repo.GetStuff();
return Json(stuff);
However, instead of the expected JSON, I get an error message stating
A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'.
I think I've found where this happens, but to explain it I need a simple example domain model as follows:
I am (lazily?) loading a selection of documents from NHibernate, like so:
var session = getNHibernateSession();
var query = new NhQueryable<Document>(session.GetSessionImplementation());
var docs = query.ToList().AsEnumerable();
I then pass the documents to return a JsonResult in my controller:
return Json(docs, JsonRequestBehavior.AllowGet);
Now, when Json() serailizes the collection, it walks over the properties of a document, finds a person. It serializes that person, and finds a project. It serializes the project, and finds - that's right - the person again! Since I'm lazy loading, it can just keep walking for ever if nothing stops it, but it's stopped by a circular reference error.
I don't really need to go all these levels down (I'd be fine without loading the project in the first place) - can I somehow affect how Json() serializes this collection, to not go further than, say, 2 levels down? I've googled around a little, but most of what I find seems to be from people who decided to use a serializing library directly, rather than just using the built-in functionality in .NET MVC. (Note: The solution to this problem must be possible to apply specifically to this case, since I might want to get JSON lists of people, including projects, somewhere else in the application...)
If you are retrieving Json, you have a service api. You have to design the api besides the implementation. Does the page that will be using it need all those fields and collections? probably not. What about adding more properties for other features and services? They will start appear in all the requests.
What you need is to use a ViewModel or just an anonymous type with the desired structure:
var session = getNHibernateSession();
var query = new NhQueryable<Document>(session.GetSessionImplementation());
var docs = query.ToList();
var result = query.Select(x => new {
x.Id,
x.Name,
People = new { p.Id,
p.Name,
p.Title
}
});
return Json( result, JsonRequestBehavior.AllowGet);
This way you can control what is being rendered and how.
It's already been answered here.
Also, it's generally a bad idea to expose your domain entities like this. If it's for read-only purposes it might not be so bad, but if any of your action methods accept a domain entity, then a specifically formatted request can overwrite properties on your domain entity that you don't want to (such as your PK).
To preserve object references in JSON, add the following code to Application_Start method in the Global.asax file:
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;

Unit Testing Claims in .Net MVC app

Background : We are using MVC4 and using WIF for Claims/Authorization. We are using Moq/MvcContrib for Mockup Objects. I have looked here and created the MockIdentity and MockPrincipal Objects - do I need them?
Goal : I have a controller class that has a class level attribute that only allows users with 'Manager' claim to access the actions. I want to create mock users and test to see if anyone that doesn't have 'Manager' claim can access the actions or not.
I get the mock concept but I have only dealt with the data objects mocking and having a tough time figuring out what plugins/classes/methods/setups I need in place to do what I need to do.
Thanks in advance.
I want to create mock users and test to see if anyone that doesn't have 'Manager' claim can access the actions or not.
No, you don't. You just want to pass users to that attribute you wrote and test that sets the filterContext.Result correctly. That's it. You don't need to test that System.Web.Mvc works. Single unit under test!
Presumably your attribute is an AuthorizeAttribute, correct? So you need to test OnAuthorization(AuthorizationContext).
Disclaimer: I haven't used moq in a while, but your code would presumably look generally like this:
var user = new Mock<IPrincipal>();
user.Setup(/* whatever you need to look at */);
var authContext = new Mock<AuthorizationContext>();
authContext.Setup(ac => ac.HttpContext.User).Returns(user);
var myAttribute = new RequireManagerAttribute();
myAttribute.OnAuthorization(authContext);
authContext.VerifySet(ac => ac.Result = /* whatever you expect */);

What's the simplest way to intercept a method call for added functionality?

Suppose i have a repository that returns a list of Posts. The repository interface has a GetAll() method which does what it suggests.
Now in keeping with the theory that i shouldn't be putting domain logic in the repository, i want to intercept calls to the concrete GetAll() method such that i can add the following logic to the GetAll() result:
return GetAll().OrderByDescending(p => p.Posted).ToList();
The reason i want to intercept this is because (1) i don't want to have the client remember to call an extension method (OrderByDescending or some useless wrapper of that), i want it called every time and (2) i don't want to have all my concrete implementations have to remember to order the GetAll() result - i want this logic in a single place external to any repository.
What's the easiest way to do this?
I'm already using StructureMap so if i can intercept with this it might be a low cost option. But i don't think SM intercepts method calls, just the creation of the object instance?
Do i need to go to a proxy or mixin pattern? Do i need to go all-in with Castle Dynamic Proxy? Or is there another method i should consider or perhaps a combination?
I'm really interested in a concrete suggestion to my particular example above. I'm novice to AOP so please be gentle.
Went with the DynamicProxy option. It was easier to use than i thought.
All it took was the using Castle.DynamicProxy; reference...
A bit of IInterceptor...
public class PostRepoInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
if (invocation.Method.Name.Equals("GetAll", StringComparison.InvariantCultureIgnoreCase))
invocation.ReturnValue = this.GetModifiedGetAllResult(invocation.ReturnValue);
}
private object GetModifiedGetAllResult(object getAllResult)
{
return Post.GetOrderedPosts((IList<Post>)getAllResult);
}
}
Two new lines in StructureMap config:
public RepoRegistry()
{
var pg = new ProxyGenerator();
For<IPostRepository>()
.EnrichAllWith(z => pg.CreateInterfaceProxyWithTarget<IPostRepository>(z, new PostRepoInterceptor()));
}
..and it's done. GetAll() now behaves how i want. I can still use the interfaces the way i'm familar and i've kept it all DRY and decoupled for DDD.
Thanks to Sam and Andre.
AFAIK, StructureMap only intercepts object construction, so using it it's not going to work.
I don't know Castle, but I think that the idea - here - is to apply Decorator pattern, so you could also do it by yourself without recurring to a third party library by following the steps described in the previous link.
That's how I'd do it, since I'm not a big fan of AOP.
HTH
No, it can not change the return value. However, you can access the target inside aspect to change target's property. Assuming you has already Repository defined, here is the code to add post processing aspect to change target property.
IRepository<decimal> Rep = new Repository();
IRepository<decimal> tpRep = (IRepository<decimal>)ObjectProxyFactory.CreateProxy(Rep,
new String[] { "GetAll" },
null,
new Decoration((x, y) =>
{
Console.WriteLine("Entering " + x.GetType().ToString());
if (x.GetType().ToString() == "ThirdPartyHR.Repository")
{
List<decimal> decimals = ((Repository)x).RepList;
IEnumerable<decimal> query = decimals.OrderByDescending(num => num, new SpecialComparer()).ToList<decimal>();
((Repository)x).RepList = (List<decimal>)query;
}
}, null));
tpRep.GetAll();
List<decimal> lstRep = Rep.RepList;
If needed, I can send you complete working code. And, if possible, please reply to me from the article "Add Aspects to Object Using Dynamic Decorator" since I don't automatically get the message here.
There is an article Add Aspects to Object Using Dynamic Decorator.
It describes an approach to adding aspects to object at runtime instead of adding aspects to class at design time. Looks like that is what you want.

Resources