GetRolesForUser returns null - asp.net-mvc

In the background of my mvc 4 application i am running a scheduler that does some tasks.
When i want to get the roles from a specific user the functions returns a nullreference exception.
An unhandled exception of type 'System.NullReferenceException' occurred in System.Web.dll
The function does work with a normal request, but not outside a normal http request.
Why is GetRolesForUser not working outside a normal request (assuming that is the problem) and how can i fix it?
Note: Im using the parameter username, the user exists and has a role.
Im using the DefaultMembershipProvider.
Code:
public static string GetUserRoleByUsername(string username)
{
return System.Web.Security.Roles.GetRolesForUser(username).First();
}
Thanks in advance!
Edit:
I have fixed it by initializing the roleProvider, i am not sure why i need to initialize it.
Any ideas why i have to do this?
var roleProvider = System.Web.Security.Roles.Provider;

Related

Null exception in MVC model

I am getting the model values to an action in controller and trying to pass the values to another function in another class by setting it to another object . In the line of invoking the second function, the object throws null exception. It doesnt show null in the if condition check either.
Please find code below.
public ActionResult SearchBySecurity(SearchViewModel srchModel)
{
var searchDTO = new VisitorSearchDTO();
//_mapper.Map<SearchViewModel, VisitorSearchDTO>(srchModel,searchDTO);
searchDTO.VisitorFirstName = srchModel.VisitorFirstName;
searchDTO.VisitorContactNumber = srchModel.VisitorContactNumber;
searchDTO.VisitorCompany = srchModel.VisitorCompany;
searchDTO.VisitDate = srchModel.VisitDate;
if (searchDTO != null)
{
var searchResultsDTO = _searchVisitor.SearchForVisitors(searchDTO);
}
ModelState.Clear();
return View("SearchBySecurity",srchModel);
I am guessing you are getting null exception when you are trying to map your models. Are you using AutoMapper? What is _mapper? If AutoMapper, then it might be worth checking your mapping profile code once if you have used any custom (before, after) mappings.
Rest as everyone has suggested, debug your code and state more clearly where the probles is, what you have tried and give clear definition of your types and environment
Thanks Stephen and Jinish for your inputs.
I have managed to solve the issue.
The trouble was in initializing the controller with mapper and service parameters. Default parameter-less constructor was taken up in the code and hence mapper and service objects were not getting initialized. Solved this by proper implementation of interfaces and mapping profiles.

Login user at startup

public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
FormsAuthentication.SetAuthCookie(1.ToString(), true);
}
}
An exception of type 'System.Web.HttpException' occurred in
System.Web.dll but was not handled in user code
Additional information: Request is not available in this context
How else can I automatically login a user without having to do a whole new page request?
What part is confusing you? Forms Auth requires a request in order to work. Part of what it does is send a cookie to the client, and it can't very well do that if there's no client. Application_Start runs outside of the request, so you can't access the request object from there. Even if you could, this isn't run for each request, so it would only work for the first user that caused it to activate.
If you want to do this in a global way, but within the request scope, you'll need to use something like a custom action filter or a custom membership provider. Not sure which would be best for something like or even if an action filter would work, but that's your options.

Service call back to a Controller?

Grails makes it very easy for a Controller to call into a Service and for a Controller to forward a request onto another Controller.
So suppose you have a service method as such
List<String> updateNames() {
...
}
You can call it very easily from any controller.
I am wondering, say if you have an edge case where you realise there is a validation problem in your service method. You don't want to throw an Exception back to your controller, because it is not really an exceptional case. But you can't return back an error message from your Service to the Controller that called because that will mean you have to use some wrapper object instead of a nice List
Is there anyway for these cases, you can get the Service to do a server side forward onto another Controller which could return an Error response to user?
Thanks.
Grails already have a structure for validation in your beans, called Errors (comming form Spring). For example, if you have a service to upload files, you could easily attach validation errors in your bean:
class UploadService {
void doUpload(MultipartFile file, MyDomainClass domainClassInstance) {
if(validationsFail) {
domainClassInstance.errors.rejectValue("myUploadField","my.i18n.code")
}
}
}
If it's not a domain class, you can consider using a command object since they're validateable too.
In your controller, it's just a metter of checking if your instance has errors:
def upload() {
MyDomainClass instance = ...
uploadService.doUpload(request.getFile('file'), instance)
if(!instance.hasErrors()) {
//save and go on...
}
}
Another option is to work with exceptions like #Joshua Moore answered. Just remember to extend RuntimeException. If you don't, your transaction will not be rolledback automatically.
Services are not aware of the web/http request context in this way. I won't get into how this line is blurred with session or request scoped services since it still doesn't apply to what you are asking about. Plus, you really don't want your service to even be aware that it's dealing with a web/http request, since you want to separate responsibilities and have a good/clean design.
So, back to your question. This is exactly the case for raising an exception from your service and letting your controller handle the result of that exception. If it's a validation error on an instance then you should be able to access the errors collection of the instance in your controller (provided of course that it was an input into your service).
As a side note about exceptions from services. Stack traces are expensive to fill in. This is even more so in Grails since there are a lot of pieces at work. I highly recommend if you are going to raise your own business logic exceptions from your services that you override the fillInStackTrace method on your exception to avoid this cost.
Here is an example:
package com.example
class MyBusinessException extends RuntimeException {
List<String> argList = []
public MyBusinessException (String message, List<String> args){
super(message)
argList = args
}
public MyBusinessException (String message){
super(message)
}
/**
* Don't fill in the stack trace because we want things to be faster.
**/
#Override
public Throwable fillInStackTrace() {
// do nothing
return this
}
}

Writing to a read only session in MVC 3+

I've come across a curious behaviour of ASP sessions. You can force a controller to be outside of the user's session - I want to be able to do this so that multiple requests can execute at the same time and using a session causes them to execute consecutively.
Disabling session state works as expected:
[SessionState(SessionStateBehavior.Disabled)]
public class SampleController : Controller
{
public ActionResult Test()
{
// Access to the session should be denied
object test = Session["test"];
return Content(test);
}
}
Going to ~/Sample/Test will throw a System.Web.HttpException, as expected.
However, read-only sessions appear to behave a little strangely:
[SessionState(SessionStateBehavior.ReadOnly)]
public class SampleController : Controller
{
public ActionResult Test()
{
// Read from the session should be fine
object test = Session["test"];
return Content(test);
}
public ActionResult SetTest(string value)
{
// Write to the session should fail
Session["test"] = value;
// Read it back from the session
object test = Session["test"];
return Content(test);
}
}
So now I expect ~/Sample/Test to work, and it does. The odd bit is that the set does too: I go to ~/Sample/SetTest?value=foo and it doesn't throw an exception, in fact it returns "foo". If I call ~/Sample/SetTest?value=bar and then ~/Sample/Test I get "bar", indicating that the session has been written to.
So in a SessionStateBehavior.ReadOnly I have successfully written to the session and read my value back.
I think this could be due to one of three things:
In MVC 3 [SessionState(SessionStateBehavior.ReadOnly)] is broken/ignored.
The [SessionState] is overridden when the session is written to and becomes writeable.
The SessionStateBehavior.ReadOnly actually indicates some kind of dirty/optimistic access.
Can anyone confirm?
I suspect the last one is true, based off the custom session provider documentation - if it is then how does the implementation work? Does writing to a 'read only' session risk concurrency errors (i.e. last write wins) or does it risk corrupt sessions and breaking exceptions?
Update
It looks like this is by design (from Microsoft's docs):
Note that even if the EnableSessionState attribute is marked as
ReadOnly, other ASP.NET pages in the same application might be able to
write to the session store, so a request for read-only session data
from the store might still end up waiting for locked data to be freed.
It looks like the second option above is what it actually does - the session is locked and the mode changed to writable.
~/Sample/SetTest?value=foo
Yes it won't throw any error, but it also didn't persist the session at the end of the request. By design any thing that you write to session gets updated (only if the session is writable) at the very end of the request life-cycle.
In my test ~/Sample/Test returns nothing.
I think they should have failed fast here when the session is readonly.
By the way your sample need to be rewritten
string test = (string)this.Session["test"];

WebException NotFound received when using Silverlight with ASP.NET MVC

I'm not entirely sure how to explain this, but basically I am trying to use a Silverlight application hosted within an ASP.NET MVC application. I have a basic controller on the MVC side that contains a method which accepts some string parameter and returns an ActionResult (for the purpose of this program, that result is some Json data).
My problem arises when I handle the WebClient.OpenReadCompleted event within the Silverlight control. When the WebClient.OpenReadAsync method is called within this control, it successfully reaches the controller and then reports back to the relevant event handler as expected. However, when it is handled, the event arguments contain an error stating: "The remote server returned an error: NotFound.".
Previously, I have noticed this is caused when some part of my communication URL is incorrect - in this case it is not. From some Googling, I have also noticed that this is a generic error. As such, I'm rather stumped. To make matters more confusing, I use this exact same communication attempt in another part of the program, that retrieves an array of strings, and that works perfectly fine.
Please see the example code below (due to the nature of this program, I am unable to post the full code).
Silverlight Control
WebClient mClient = new WebClient();
public void RequestData()
{
mClient.OpenReadAsync(new Uri("http://localhost:51234/Home/GetData"));
mClient.OpenReadCompleted += new OpenReadCompletedEventHandler(mClient_OpenReadCompleted);
}
private void mClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if(!e.Cancelled && e.Error == null) // <-- e.Error here is a WebException
{
var serializer = new DataContractJsonSerializer(typeof(Data));
Data data = (Data)serializer.ReadObject(e.Result);
}
}
MVC Controller - named HomeController and accessed with "Home"
public ActionResult GetData()
{
return Json(new Data(), JsonRequestBehaviour.AllowGet);
}
Note
Here, Data contains three members of types; string, string and byte array. For the purpose of serialization, I have exposed all three members through public properties containing both get and set parts. I have also added a public constructor taking no arguments.
Any advice on this would be greatly appreciated.
Many thanks in advance.
UPDATE
I've just tried the same bit of code with different data, and it works fine. I wondered if it was the size of the data (as the first attempt was with very large data), but I don't understand why that would matter if the call managed to hit the controller.
If you want to see the real server-side exception, this may help you:
http://msdn.microsoft.com/en-us/library/ee844556(v=VS.95).aspx
Either approach described there would probably illuminate the real problem.

Resources