开发者

JSON returns raw serialised data to browser page instead of a grid and formatted HTML

My Data appears in IE like

[{"UserId":1,"Surname":"Scccce","Forename":"John","Pax":"0777533303","Mobile":"07775803803","Email":"john803.......

When I want the Javascript to fire and create a grid...

My Controller Code is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using Emas.Model;
using Emas.Web.Models.Repositories;
using Emas.Web.Models.FormViewModels;
using Emas.Web.Helpers;
using Emas.Web.Extentions;
using System.Web.Script.Serialization;

namespace Emas.Web.Controllers
{


    [Emas.Web.Helpers.AuthorizeHelpers.EMASAuthorize]

    public class UserController : Controller
    {
        private EmasDataContext _db = new EmasDataContext();
        private SecurityRepository _securityRepository = new SecurityRepository();

        #region Index

        public ActionResult Index()
        {
            //if (!User.IsInRole("Active"))
            //    return View("NotAuthorised");

            if (!User.IsInRole("Admin")) // Only ADMIN users can setup user access and roles
                return View("NotAuthorised");

            var allUsers = _securityRepository.FindAllUsers();

            if (allUsers == null)
                return View("NotFound");

            return View(allUsers);           
        }

        public JsonResult IndexJSon()
        {
            //if (!User.IsInRole("Active"))
            //    return View("NotAuthorised");

            //var allUsers = _securityRepository.FindAllUsers();
            //return this.Json(allUsers);

            var results = from user in _db.aspnet_Users
                          select new
                          {
                              UserId = user.UserId,
                              Surname = user.Surname,
                              Forename = user.Forename,
                              Pax = user.Pax,
                              Mobile = user.Mobile,
                              Email = user.Email,
                              Active = user.Active,
                              UserName = user.UserName
                          };

            return Json(results);
        }

        public JsonResult Index2()
        {


            var results = from user in _db.aspnet_Users
                          select new
                          {
                              UserId = user.UserId,
                              Surname = user.Surname,
                              Forename = user.Forename,
                              Pax = user.Pax,
                              Mobile = user.Mobile,
                              Email = user.Email,
                              Active = user.Active,
                              UserName = user.UserName
                          };

            return this.Json(results, "text/html");

        }

        #endregion Index

        #region Details

        public ActionResult Details(int id)
        {
            aspnet_User user = _securityRepository.GetUser(id);

            if (user == null)
                return View("NotFound");

            return View(new UserFormViewModel(user, this._securityRepository.FindAllRoles(), this._securityRepository.FindAllUsers()));
        }

        #endregion Details

        #region Delete
        [AcceptVerbs(HttpVerbs.Delete)]
        public void Delete(int id, string ConfirmButtons)
        {
            aspnet_User user = _securityRepository.GetUser(id);
            this._securityRepository.Delete(user);
            this._securityRepository.Save(User.Identity.Name);
        }
        #endregion Delete

        #region Create

        // GET:
        public ActionResult Create()
        {
            aspnet_User user = new aspnet_User();
            return View(new UserFormViewModel(user, this._securityRepository.FindAllRoles(), this._securityRepository.FindAllUsers()));
        }

        // POST: 
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(aspnet_User user, string[] Roles)
        {
            if (user.UserName != null)
                user.LoweredUserName = user.UserName.ToLower();

            //TODO dc - hardcoded for demo - fix
            user.ApplicationId = new Guid("311566ad-a279-4d0b-a883-89425bdc69e3");
            _securityRepository.Add(user);


            if (Roles == null)
            {
                //ModelState.AddModelError("User In Roles", "You must select at least one Role for this user to be in.");
                //Code Removed during UAT, being in no Roles implies READ ONLY user
            }
            else
            {
                foreach (string role in Roles)
                {
                    aspnet_UsersInRole userInRole = new aspnet_UsersInRole()
                    {
                        //RoleId = new Guid(role), GUID removed
                        UserId = user.UserId

                    };
                    user.aspnet_UsersInRoles.Add(userInRole);
                }
            }

            if (!ModelState.IsValid)
                return View(new UserFormViewModel(user, this._securityRepository.FindAllRoles(), this._securityRepository.FindAllUsers()));

            this._securityRepository.Save(User.Identity.Name);
            return RedirectToAction("Index", new { id = user.UserId });
        }

        #endregion Create

        #region Edit

        // GET: 
        public ActionResult Edit(int id)
        {
            aspnet_User user = _securityRepository.GetUser(id);


            if (user == null)
                return View("NotFound");           

            return View(new UserFormViewModel(user, this._securityRepository.FindAllRoles(),this._securityRepository.FindAllUsers()));
        }

        // POST: 
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, string[] Roles)
        {
            aspnet_User user = _securityRepository.GetUser(id);
            _securityRepository.DeleteUserInRoles(user);

            if (Roles == null)
            {
                //ModelState.AddModelError("User In Roles", "You must select at least one Role for this user to be in.");
                //Code Removed during UAT, being in no Roles implies READ ONLY user
            }
            else
            {                              
                foreach (string role in Roles)
                {
                    aspnet_UsersInRole userInRole = new aspnet_UsersInRole()
                    {
                        //RoleId = new Guid(role),
                        UserId = user.UserId
                开发者_如何学Python    };
                    user.aspnet_UsersInRoles.Add(userInRole);
                }                
            }

            TryUpdateModel(user);
            if (!ModelState.IsValid)
                return View(new UserFormViewModel(user, this._securityRepository.FindAllRoles(), this._securityRepository.FindAllUsers()));

            this._securityRepository.Save(User.Identity.Name);
            return RedirectToAction("Index");
        }

        public ActionResult ReassignActions(int id)
        {
            aspnet_User user = _securityRepository.GetUser(id);

            if (user == null)
                return View("NotFound");

            return View(new UserFormViewModel(user, this._securityRepository.FindAllRoles(), this._securityRepository.FindAllUsers()));
        }

        // POST: 
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ReassignActions(int id, string[] Roles,Guid UserLoginId)
        {
            if (!User.IsInRole("Admin")) // If Admin user then block from EDITING
                return View("NotAuthorised");

            aspnet_User user = _securityRepository.GetUser(id);

            //this._db.ReassignUserScheduledActions(user.UserId.ToString(), UserLoginId.ToString());

            return View(new UserFormViewModel(user, this._securityRepository.FindAllRoles(), this._securityRepository.FindAllUsers()));

        }

        #endregion Edit                               
    }
}

My index2.aspx is:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="application/json; charset=utf-8" />
<title>My First Grid</title>

<link type="text/css" href="~/Content/jQueryUI/css/jquery-ui-1.8.11.custom.css" rel="stylesheet" />
<link href="~/Content/jquery-1/css/ui.jqgrid.css" rel="stylesheet" type="text/css" />

<style type="text/css">
html, body {
    margin: 0;
    padding: 0;
    font-size: 75%;
}
</style>

<script src="~/Scripts/jquery-1.5.2.js" type="text/javascript"></script>
<script src="~/Content/jquery-1/js/grid.locale-en.js" type="text/javascript"></script>
<script src="~/Content/jquery-1/js/jquery.jqGrid.min.js" type="text/javascript"></script>

</head>
<body>
<table id="list"></table> 
<div id="pager"></div> 

</body>
</html>

<script type="text/javascript">


    $(function() {
        alert(33);
        $("#list").jqGrid({
            url: $("#AbsolutePath").val() + "/User.mvc/Index2",
            datatype: 'json',
            ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
            mtype: 'GET',
            colNames: ['UserId', 'Surname', 'Forename', 'Pax', 'Mobile', 'Active', 'Email'],
            colModel: [
        { name: 'UserId', index: 'UserId', width: 80, editable: true, editoptions: { size: 10} },
        { name: 'Surname', index: 'Surname', width: 90, editable: true, editoptions: { size: 25} },
        { name: 'Forename', index: 'Forename', width: 60, align: "right", editable: true, editoptions: { size: 10} },
        { name: 'Pax', index: 'Pax', width: 60, align: "right", editable: true, editoptions: { size: 10} },
        { name: 'Mobile', index: 'Mobile', width: 60, align: "right", editable: true, editoptions: { size: 10} },
        { name: 'Active', index: 'Active', width: 55, align: 'center', editable: true, edittype: "checkbox", editoptions: { value: "Yes:No"} },
        { name: 'Email', index: 'Email', width: 100, sortable: false, editable: true, edittype: "textarea", editoptions: { rows: "2", cols: "20"} }
    ],
            pager: '#pager',
            rowNum: 10,
            rowList: [10, 20, 30],
            sortname: 'Surname',
            sortorder: 'desc',
            viewrecords: true,
            caption: 'My first grid'
        });
    });

</script>


I don't know specifically about ASP.NET, but the browser asks if you want to save the file because the file is served with a HTTP Content-Disposition header like this:

Content-Disposition: attachment; filename="..."

rather than Content-Disposition: inline;.


It looks to me like the server is responding correctly. It's the browser or the plugin that isn't behaving. Times I've seen the browser attempt to download a JSON result as a file is when the request was not sent asynchronously. I know this is an AJAX plugin, but confirm with fiddler or firebug that the request is sent with an XHR header. You can also check the response header to see what the Content-Type is. I'd start there, examine the request and response for any abnormalities because your code looks right.

On the action side I've never had to include "text/Html in my return Json() calls. I always use this...

return Json(new {message = "some message goes here"} , JsonRequestBehavior.AllowGet);

The response header from this code looks like this..

HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 13 Apr 2011 04:21:47 GMT
Content-Length: 29


After a second look... How is index2.aspx getting rendered? You never return that View.

That View needs to have been rendered with return View("index2") The jqGrid plugin will then make an additional AJAX call to retrieve the Json data. From the looks of it, you're never actually loading that javascript.

Here's what I would suggest.

public ActionResult Index2()
{
     return View('Index2');
}


public JsonResult Index2Data() //RENAME TO SOMETHING BETTER
        {


            var results = from user in _db.aspnet_Users
                          select new
                          {
                              UserId = user.UserId,
                              Surname = user.Surname,
                              Forename = user.Forename,
                              Pax = user.Pax,
                              Mobile = user.Mobile,
                              Email = user.Email,
                              Active = user.Active,
                              UserName = user.UserName
                          };

            return Json(results, JsonRequestBehavior.AllowGet);

        }

Then in your browser if you hit http://site/User/Index2 you'll first return the aspx page that will load the javascript. As the javascript loads the jqGrid plugin should fire off another call to retrieve the Json data.

Be sure to update your jqGrid url with "index2data" or whatever you call it. The grid needs to know where to get the data from.


I notice that

<%=Html.Action("~/Views/User.mvc/Index2")%>

should in fact be

<%=Url.Action("~/Views/User.mvc/Index2")%>

Html.Action(...) renders the action inline, whereas Html.Url(...) returns the url of the action.

This is probably changing the header information of the Html page, as json results produce different headers than view results, which makes the browser want to download the file rather than render it.

Hope this helps :) text/html

edit:

If you are asking why the Index2 page wants you to download the json file, it's because of the header information. I may have misunderstood the question to begin with. Try the folling:

return Json(results, "text/html")

This will force the content type from "application/octet-stream" to "text/html", and will tell the browser to render the result, rather than try to download it.

edit, again:

Now I'm understanding the real question.

The reason you're not getting the HTML you're expecting is because you're returning a Json result. A Json result tells the controller to serialize an object to json and print it to the response. It does NOT return a view, under any circumstances.

To render a view, you must return an object derived from ViewResultBase. The default Controller class has many View(...) methods that can handle this for you.

You will need two actions in your scenario, the first action will render the view:

public ActionResult Index()
{
    // This will find a view with the name of the action (in this case, "Index")
    return View();
}

Inside your Index.aspx page, you will need to setup jqgrid with

url:'<%= Url.Action("IndexDataJson") %>',

And you'll need another action on your controller to return the jqgrid rows:

public ActionResult IndexDataJson(string sidx, string sord, int page, int rows)
{
    var results = from user in _db.aspnet_Users
                  select new
                  {
                      // Your properties here
                  };

    var usersOnPage = results.Skip((page-1) * rows).Take(rows).ToList();

    // This is the correct format for the jqgrid result
    var model = new
    {
        total = results.Count,
        page = page,
        records = usersOnPage.Count,
        rows = usersOnPage
    }

    // Ignore the "text/html" mentioned earlier, as you probably wont need it
    return Json(model, JsonRequestBehavior.AllowGet);
}

Keep in mind that you may need to modify the ajaxReader for the jqgrid if it doesn't load any data...

Hopefully this fully answers your question. :)

For more information, pleas refer to Phil Haack's blog post about this topic:

http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspx

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜