Archive for category ASP.NET

HttpContext.Current.Session is null in web service

I was working with an web service (the old school .asmx kind), and I was encountering an issue where my Session object was null. Not a particular Session variable – all Session objects. When I would try to reference the following line, I was getting the “Object reference not found” message when I hovered over the “Session” part of the line in the debugger:

Session["Result"] = result;

To get around this, I added the “EnableSession” to true in the WebMethod attribute:

    [WebMethod(EnableSession = true)]
    public string RegisterNewUser(string bname, string first, string last) {
       // Do stuff
    }
Advertisements

Leave a comment

Partial View returning the full view instead of partial view contents

I had an odd result trying to return an ASP.NET MVC partial view from a controller after a POST request. The setup was simple.  I had a view that contained a partial view with a grid. Nothing fancy in the view:

@model IEnumerable<Models.Code>

<h2>Code Maintenance</h2>

@{     Html.RenderPartial("~/Views/_CodeTable.cshtml", Model); }

The partial view contained a table:

@model IEnumerable<Models.Code>

<table class="table table-striped table-bordered">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Code)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Code)
            </td>
            <td><a onclick="loadCode(this, '@item.Code')"></a></td>
        </tr>
    }
</table>

When the page loaded initially, everything was fine. But when I tried to update the partial view using some jQuery code, the I would get HTML results like so:

<h2>Code Maintenance</h2>

<h2>Code Maintenance</h2>

<table>
 <tr><td>1</td></tr>
 <tr><td>2</td></tr>
 <tr><td>3</td></tr>
</table>

There was also global code in the _layout.cshtml being returned as part of the partial view, though I am not showing that here. So basically, the partial view wasn’t being treated like a partial view, and was instead being treated like a view, and the “Code Maintenance” title, along with my _layout.cshtml code, was being displayed twice when it should have only been shown once.

The problem in this case was my controller. I was returning a view instead of a partial view. Here is wrong code:

        [HttpPost]
        public ActionResult Code(Code model) {
            List<Code> results = new List<Code>();
            ...
            return View(results);
        }

And here is the corrected code:

     [HttpPost]
     public ActionResult Code(Code model) {
         List<Code> results = new List<Code>();
         ...
         return PartialView("_table", results);
     }

In case you are curious, here is how I loaded the code in jQuery:

function updateCode(id) {

    var data = { id: id };

    $.ajax({
        url: uri + 'MyController/UpdateCode',
        type: 'POST',
        cache: false,
        async: false,
        contentType: 'application/json',
        data: JSON.stringify(data),
        success: function (partialViewResult) {
            $("#results").html(partialViewResult);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert('Error saving the code');
        }
    });
}

Leave a comment

Invalid ModelState with a bound DropDownList

I had a simple model, like so:

    public class AmusementPark {
        public List<SelectListItem> Coasters { get; set; }
    }

I bound this simple model to a simple DropDownList, like so:

@Html.DropDownListFor(model => model.Coasters, Model.Coasters)

But when I submitted my model to the controller, I received an invalid ModelState. So I looked through the various errors in the ModelState with a bit of code:

    var errors = ModelState
        .Where(err => err.Value.Errors.Count > 0)
        .Select(err => new { err.Key, err.Value.Errors })
        .ToArray();

Lurking in the ModelState errors wasthis wonderful System.InvalidOperationException exception:

The parameter conversion from type ‘System.String’ to type ‘System.Web.Mvc.SelectListItem’ failed because no type converter can convert between these types.

Returning to the line in question, a DropDownList bound to a List of SelectListItem objects:

@Html.DropDownListFor(model => model.Coasters, Model.Coasters)

To resolve it, I first modified my model to have a key value:

    public class AmusementPark {
        public string CoasterId { get; set; }
        public List<SelectListItem> Coasters { get; set; }
    }

Then I modified the view to set the new CoasterId as the first parameter in my DropDownListFor helper:

@Html.DropDownListFor(model => model.CoasterId, Model.Coaster)

Voila, the ModelState was now valid when posting.

,

Leave a comment

Why is my model attribute null?

While I can’t explain every reason, here is one reason I found. First, my rather simple model:

    public class User {
        public string ID { get; set; }
        public string Email { get; set; }
        public Guid SecretId{ get; set; }
    }

I was manually populating the model from the database and passing it off to the view from the Home controller like so:

     public ActionResult Index(string id) {
         User user = new User();
         user.ID = id;
         // Various other stuff...
         user.SecretId = Guid.NewGuid();
         return View("Index", user);
     }

The user can do some simple modifications in the view, but it’s not terribly complex. Then perform a POST:

   @model ScottProj.Models.User
   
    @using (Html.BeginForm("Process", "Home", FormMethod.Post)) {         @Html.LabelFor(m => m.ID)         @Html.LabelFor(m => m.Email )         @Html.TextBoxFor(m => m.Email )             }

When it got to the Process controller action, the “SecretId” was missing, most likely because there wasn’t anyplace in the view that there field was referenced, no form field that says “This is the SecretId value”. I didn’t want to show that value on the screen, so instead, I added a hidden field to hold that value:

   @Html.HiddenFor(m => m.SecretId)

And that did. My view now had a placeholder for the value so it could be sent back to the controller in the POST request.

,

Leave a comment

MVC – Setting focus on a control

To set focus on a control when an MVC view loads, use the following syntax to attach the “autofocus” tag to the HTML element:

@Html.TextBox("Last", null, new { autofocus = "" })

,

Leave a comment

Call Index action after a POST with MVC

I had a page with a list of records that the user could view to see what was in the queue of things to do. The user would click on the link to bring up a table where they could choose which record to edit.


Choosing this record would populate the view with the fields. The user could then update the values, click “Save” to generate a POST request, and then return back to the Index view.

The problem was that my redirect to the Index view, while returning to the right view, wasn’t showing the link with the remaining records. Here is how I was attempting to do this:

return View("Index", item);

To fix this, I made a call to “RedirectToAction” to call the controller’s Index action:

return RedirectToAction("Index", "MyController", item);

The fields were cleared just as I wanted (because I had set the model to null before passing into “RedirectToAction”) and the remaining records link was there as expected.

Leave a comment

Deleting a row from inside a partial view

Post #200! I hope it’s a good one…

I had a view, within which was a partial view that contained a table. Inside this table was link to delete the current table row.

Form

Form

So to recap: View -> Partial View -> Delete Row

Since I did not want the whole page to refresh, I needed to use some jQuery to do this.
On my main page, I populated the various drop down lists you see above. Leaving out all that code, I have this remaining code at the bottom of the page:

    function deleteRow(id) {
        $.ajax({
            url: "/MyApp/DeletePermission",
            type: "GET",
            data: { id: id }
        })
        .done(function (partialViewResult) {
            $("#results").html(partialViewResult);
        });
    }

The “results” DIV tag holds the partial view, which I am populating with an onchange event earlier in the page. I assume you have this part down, but if not, post a comment and I’ll write something up about binding data to a partial view. Heck, maybe I will anyways.

In my partial view, I build the table, a truncated version of which is here:

     @foreach (var item in Model) {
         <tr>
             <td>@Html.DisplayFor(modelItem => item.) </td>
             <td><a onclick="deleteRow('@item.ID')">Delete</a></td>
         </tr>
     }

So when I click the “Delete” link in the partial view, it will call the “deleteRow” function in the main view. The jQuery will then call my controller action:

  public ActionResult DeletePermission(Permission item) {
      List<Permission> model = Repository.DeletePermission(item.ID);
      return PartialView("_PermissionsTable", model);
  }

Notice that the action returns a list of Permission objects, which is then use to refresh / rebind the table when the “done” method of the jQuery function is completed.

,

Leave a comment