views:

123

answers:

5

Hey,

I have an array which contains around 50-200 hyperlinks. How can I pass this array to the client-side so that I can iterate through the array and display each hyperlinks as a list item? The array will be stored in 'Application' as it's system wide and rarely changes. Could there be a more efficient way of achieving the hyperlinks as a list?

Thanks

+1  A: 

You could convert the array to JSON and process it on the client-side.

Justin Ethier
I tried testing passing a string as JSON, but I can't get it to work. I created a webmethod which returns a string and put this code in my aspx:`$.getJSON('MyPage/GetString', function(data) { alert("Working"); });`However, the alert doesn't even show. What am I doing wrong?Thanks
Skoder
When returning JSON, you may need to set the HTTP header to `application/json`
Justin Ethier
I tried adding `Response.Headers.Add("contentType", "application/json");` but it didn't work. Am I doing it wrong?
Skoder
Maybe; it would help if you post more code, if you are still planning to go with a client-side approach.
Justin Ethier
+4  A: 

A really good place to start with Web Forms and JSON and JQuery is this link:

http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/

Also check out JSON.NET: http://www.codeplex.com/Json

Daniel Lee
Thanks for the link.
Skoder
A: 

Using ASPNET MVC can make this super easy. Even if you've never used ASPNET MVC, it will be easy for you to employ it in your ASP.NET app.

You'll need a Controller, and at least one Action. The action should return a JsonResult.

it looks like this in code:

using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

namespace MvcApplication1.Controllers
{
    public class DemoController : Controller // the name is used in the URL
    {
        public JsonResult LinkList(int? arg)  // the name is used in the URL
        {
            var = new List<String>();
            // build the list here.  You could also use an existing one. 
            foreach (string link in linkSet)
                list.Add(link);
            return this.Json(list, JsonRequestBehavior.AllowGet);
        }
    }
}

Drop that into the App_Code sub-directory of the ASPNET app.
That method is like a [WebMethod] in ASMX, but it generates JSON. To invoke it, do a GET on http://server/vdir/Demo/LinkList. The "Demo" part is the name of the Controller class, less the suffix "Controller". The "LinkList" in the url path is the name of the method on the controller. It needs to be public.

The json this method generates will look like this:

[ "http://jvcpbdvcj/scbwkthoxlng/lhxktjght/zgfd/cuuenirukwag",
  "http://vskwkzpwaxn/eeitpup/twwshynjjcw/lblxdx/rwljaqicfgpz",
  "http://foczucekdl/ljap/napvchbkcs", 
  ....
]

It's just a simple 1-D array of links. To make the necessary request from the browser is very simple using jQuery.

    $.ajax({
      url     : "http://myserver/vdir/Demo/LinkList",
      type    : "GET", // http method
      cache   : false,
      success : function(result) {  // called on successful (200) reply
         ....
      }
    });

In the success function, you can iterate on the list, emitting <a> elements or whatever you like into your document. Like this:

      success : function(result) {
        if (result !== null){
          for(var i = 0; i < result.length; i++) {
            var onelink = '<a href="' + result[i] + '">link ' + i + '</a><br/>';
            $('#output').append(onelink);
          }
        }
      }

Of course, you can add to that to make it more elaborate. You can parameterize the GET request. You could change the shape of the outgoing JSON so that it's an object with various properties (timestamp, id, whatever you like), and not just a simple array. You can be more elegant on the browser side when producing the list of links. There are lots of other options. But you get the idea.


ASPNET MVC is much preferable to ASMX when servicing browser clients, because of its built-in support for JSON serialization, and because of the super simple model. Notice I did not have to set the content type explicitly, or create JSON manually, or fiddle with other stuff on the Response, and so on. It just works.

Related: How can I implement a site with ASP.NET MVC without using Visual Studio?

Cheeso
@Cheeso, ScriptService attribute on WebService makes JSON calls transparent to the implementation, much as you describe an MVC controller, thus making MVC preferable only if the website is built on MVC.
Sky Sanders
very good to know. . .
Cheeso
A: 

If you don't care about search engines then do it client side, json is my preference for this. But if you want search engines to be able to see those links then server side is your only option.

Mihai Secasiu
+2  A: 

While I realize you are getting your URLs from Application, this example uses a contrived url source that you can modify to your needs. I would think you would probably want to store url/link text so I used KeyValuePair<string,string> as the array element type. If you truly need only the URL, simply change KeyValuePair<string,string> to string.

jQuery .getJSON

Using a simple aspx page handler would be accomplished something like this:

UriListHandler.aspx

<%@ Page Language="C#" %>

<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        string someParam = Request["someParam"] ?? "";

        Response.ClearContent();
        Response.ClearHeaders();

        // prevent cacheing
        Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetNoStore();

        Response.ContentType = "text/plain";

        // note, this is just a list, not a dictionary. Keys need not be unique
        KeyValuePair<string, string>[] uriList = new KeyValuePair<string, string>[100];

        for (int i = 0; i < uriList.Length; i++)
        {
            uriList[i] = new KeyValuePair<string, string>(String.Format("http://www.example.com/page{0}.htm?someParam={1}", i, someParam), String.Format("page{0}", i));

        }

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        string json = serializer.Serialize(uriList);

        Response.Write(json);
    }

</script>

UriListClient.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
    <title></title>

    <script src="scripts/jquery-1.4.1.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(document).ready(function() {

            $('#getUriListButton').click(function() {

                $.getJSON('UriListHandler.aspx',
                    { someParam: "HEY" },
                    function(responseObj, status, xhr) {

                        var list = $('<div/>');
                        for (var i = 0; i < responseObj.length; i++) {
                            var link = $('<a/>').attr('href', responseObj[i].Key).html(responseObj[i].Value);
                            list.append(link).append('<br/>');
                        }
                        var uriListContainer = $('#uriListContainer');
                        uriListContainer.html('').append(list);
                    });
            });
        });
    </script>

</head>
<body>
    <button id="getUriListButton">
        Get Uri List</button>
    <div id="uriListContainer">
    </div>
</body>
</html>

jQuery.ajax

Using a webservice is going to introduce some new concepts such as using 'ScriptService' attribute.

UriListService.asmx.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;

namespace WebApplication1
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [ScriptService] // we uncommented the following line ;-)
    public class UriListService : WebService
    {
        [WebMethod]
        public KeyValuePair<string, string>[] GetUriList(string someParam)
        {
            // prevent cacheing
            HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
            HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            HttpContext.Current.Response.Cache.SetNoStore();

            // note, this is just a list, not a dictionary. Keys need not be unique
            var uriList = new KeyValuePair<string, string>[100];

            for (int i = 0; i < uriList.Length; i++)
            {
                uriList[i] =
                    new KeyValuePair<string, string>(
                        String.Format("http://www.example.com/page{0}.htm?someParam={1}", i, someParam),
                        String.Format("page{0}", i));
            }

            return uriList;
        }
    }
}

UriListServiceClient.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
    <title></title>

    <script src="scripts/jquery-1.4.1.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(document).ready(function() {

            $('#getUriListButton').click(function() {
                $.ajax({
                    url: 'UriListService.asmx/GetUriList',
                    type: "post", // http post to ScriptService
                    data: '{"someParam": "HEY"}', // the params expected by the server
                    contentType: "application/json", // sending json request
                    dataType: "json", // expecting json response
                    success: function(data) {
                        var unwrappedDate = data.d;
                        var list = $('<div/>');
                        for (var i = 0; i < unwrappedDate.length; i++) {
                            var link = $('<a/>').attr('href', unwrappedDate[i].Key).html(unwrappedDate[i].Value);
                            list.append(link).append('<br/>');
                        }
                        var uriListContainer = $('#uriListContainer');
                        uriListContainer.html('').append(list);
                    },
                    error: function(a, b, c) {

                        alert(a.responseText);
                    }

                });
            });


        });
    </script>

</head>
<body>
    <button id="getUriListButton">
        Get Uri List</button>
    <div id="uriListContainer">
    </div>
</body>
</html>

.ASPX codebehind

To do this without ajax from codebehind is fairly trivial

UriListFromCodeBehind.aspx

<%@ Page Language="C#" %>

<%@ Import Namespace="System.Collections.Generic" %>

<script runat="server">

    public static void RenderUriList(string someParam)
    {


        // note, this is just a list, not a dictionary. Keys need not be unique
        var uriList = new KeyValuePair<string, string>[100];

        for (int i = 0; i < uriList.Length; i++)
        {
            uriList[i] =
                new KeyValuePair<string, string>(
                    String.Format("http://www.example.com/page{0}.htm?someParam={1}", i, someParam),
                    String.Format("page{0}", i));
        }


        for (int i = 0; i < uriList.Length; i++)
        {
            HttpContext.Current.Response.Write(String.Format("<a href='{0}'>{1}</a><br/>\r\n", uriList[i].Key, uriList[i].Value));

        }

    }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Uri List:<br />
        <%
            RenderUriList("HEY"); %>
    </div>
    </form>
</body>
</html>

Hope that helps, Sky

Sky Sanders