2

I'm new into MVC and I'm having a hard time solving this following issue. I got a userID via Session["LoggedUserID"] as it get once the user log in. I want to pass it to following cshtml code(or directly in controller?) which I do not understand for the moment. This action occur once user want to create a new post.

inside cshtml view(code created automatically from Controller):

     @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.CreatorUserId, "CreatorUserId", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("CreatorUserId", null, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.CreatorUserId, "", new { @class = "text-danger" })
        </div>
    </div>

My controller code:

 [HttpGet]
        public ActionResult Create()
        {
            return View();
        }

[HttpPost]
public ActionResult Create(Review review)
{  
    if (ModelState.IsValid) {

        db.Reviews.Add(review);
        db.SaveChanges();

        return RedirectToAction("Index");
    }
    return View(review);        
}

How do I pass Session["LoggedUserID"] to cshtml (or directly via controller)? Review table is using userID as FK for user ID.

EDIT: The error message I get for my current code is:

There is no ViewData item of type 'IEnumerable' that has the key 'CreatorUserId'.

Any help is much appreciated. Thanks.

skylake
  • 409
  • 2
  • 9
  • 24
  • You can access the session in the controller, so it's not clear what the actual problem is. – D Stanley Sep 26 '16 at 18:10
  • 2
    Possible duplicate of [Access session on view page in ASP.Net MVC](http://stackoverflow.com/questions/21088514/access-session-on-view-page-in-asp-net-mvc) –  Sep 26 '16 at 18:11
  • 1
    Or http://stackoverflow.com/questions/18608452/mvc-4-how-pass-data-correctly-from-controller-to-view ... Really unclear what you have problem with (possibly because you don't understand how ASP.Net MVC works or maybe how Session works). – Alexei Levenkov Sep 26 '16 at 18:19
  • 1
    What you mean "pass Session to Cshtml" ? You want to pass so that you can display it in a label ? or something else ? You have to be clear about what you are doing. Also your current code is using the DropDownList helper method and i do not see any ViewData set in your GET action for populating the dropdown (that is the reason you are getting the "There is no ViewData...." error message! – Shyju Sep 26 '16 at 18:29
  • @DStanley I don't know how to pass session from controller to view. The view code it's confusing, and I'm not quite comfortable with controller yet either. I just started to learn about MVC. – skylake Sep 26 '16 at 18:29
  • @Shyju I don't know why there's a DropDownList as I had no intention to use it. I simply wrote the controller code, right clicked and added a view(auto-generated code) with Create-template. I simply want to pass Session-data to `CreatorUserID` as the review-table require a FK for User table. – skylake Sep 26 '16 at 18:33
  • pass for what ? To display in a label in the view ? or show in an input in the view ? Still unclear to me! – Shyju Sep 26 '16 at 18:34
  • @skylake Controllers and Views have a static `Session` property that you can access directly - `Session["LoggedUserID"]` should work just fine in either the controller or the view (although it's generally frowned upon to access the session directly from the view). – D Stanley Sep 26 '16 at 18:36
  • @Shyju The action I'm creating is suppose to allow user to create a new post/review. The database table requires UserID (which is stored in `Session["LoggedUserID"]`). As the user will fill the rest manually, the UserID for that post have to be added automatically. So, no I do not want to display UserID in label or show it, I just want to pass it along with users input. – skylake Sep 26 '16 at 18:43
  • @DStanley I understand that now, but the problem is - how do I pass the data stored inside `Session["LoggedUserID"]` from controller to `CreatorUserId` in View. – skylake Sep 26 '16 at 18:50
  • If it is for saving ,no need to pass it to view. You can use the value in your HttpPost action method – Shyju Sep 26 '16 at 18:51
  • @Shyju How do I do it correctly then? Been struggling with this for hours. EDIT: Didn't see, thanks – skylake Sep 26 '16 at 18:56
  • 1
    @skylake See the answer i posted – Shyju Sep 26 '16 at 18:57

2 Answers2

2

If it is for saving with entity, there is no need to pass it to the view and send it back to server. You can use it directly in your HttpPost action method.

[HttpPost]
public ActionResult Create(Review review)
{  
    if (ModelState.IsValid) 
    {
        if(Session["LoggedUserID"]==null)
        {
           return Content("Session LoggedUserID is empty");
        }

        review.UserID = Convert.ToInt32(Session["LoggedUserID"]);   
        db.Reviews.Add(review);
        db.SaveChanges();

        return RedirectToAction("Index");
    }
    return View(review);        
}

I also added an If condition to check whether Session["LoggedInUserID"] is null before reading it to an int variable( UserID property). Ideally you may move this out of the action method to check whether user is logged in or not (May be an action filter like this)

Community
  • 1
  • 1
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • I still getting same error: `There is no ViewData item of type 'IEnumerable' that has the key 'CreatorUserId'.` **at the line ->** `@Html.DropDownList("CreatorUserId", null, htmlAttributes: new { @class = "form-control" })`. Since I use guid instead int for `userID` I had to change `review.UserID = Convert.ToInt32(Session["LoggedUserID"]);` **to** `Guid guidSess = new Guid(Session["LoggedUserID"].ToString()); ` and pass `guidSess` to `review.CreatorUserId = guidSess;`. Was this done correctly? Just in case this caused the error. – skylake Sep 26 '16 at 19:11
  • 1
    No. Your error is because your view code is using the DropDownList helper method which expects you to set the data needed to populate the dropdown to Viewdata dictionary. Since there is no need to show the dropdown, simply remove outer div which contains the line `@Html.DropDownList` and `ValidationMessageFor` from your view – Shyju Sep 26 '16 at 19:14
  • Aah I see! You mentioned it earlier but I accidentally overlooked it. Thank you, I really learned a lot from this. – skylake Sep 26 '16 at 19:32
1

You need to bind the value i.e. "User ID" to view model or put it in view bag and you can access that in the cshtml.

E.g.

SampleViewModel vm = new SampleViewModel(){UserId = yourvalue}; 

You need to create this SampleViewModel class with a property called UserId and then you can use like this. You need to bind the view model to your cshtml also like - @model SampleViewModel.cs

or you can store the value in view bag. i.e.

ViewBag.UserId = your-value; //You can call @ViewBag.UserId in cshtml page. 

Does this help?

Julian
  • 33,915
  • 22
  • 119
  • 174
Shiva Naru
  • 925
  • 3
  • 10
  • 21