简体   繁体   中英

adding asmx file in MVC 4 in ASP.NET

I have a MVC project in ASP.NET in visual studio 2013 and I have an asmx file which contain a function contain calling for google distance matrix

in the index page I need to call the asmx file ,

the asmx file contain the following function :

public double GetDrivingDistanceInMiles(string origin, string destination)
    {
        string url = @"http://maps.googleapis.com/maps/api/distancematrix/xml?origins=" +
          origin + "&destinations=" + destination +
          "&mode=driving&sensor=false&language=en-EN&units=imperial";
        //create object of HttpWebRequest that create requested object for the given url
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        WebResponse response = request.GetResponse();
        Stream dataStream = response.GetResponseStream();
        StreamReader sreader = new StreamReader(dataStream);
        string responsereader = sreader.ReadToEnd();
        response.Close();

        XmlDocument xmldoc = new XmlDocument();
        xmldoc.LoadXml(responsereader);


        if (xmldoc.GetElementsByTagName("status")[0].ChildNodes[0].InnerText == "OK")
        {
            XmlNodeList distance = xmldoc.GetElementsByTagName("distance");
            return Convert.ToDouble(distance[0].ChildNodes[1].InnerText.Replace(" mi", ""));
        }

        return 0;
    }

can you tell me please how can I add asmx file in the MVC solution and call it

or how can I add this function inside the index file I can not add it in the controller because I need to call it in a loop like this

<% foreach (var item in Model) { %>

I tried to put the code in classes in Models like this :

Google Service class

Distance Class

and in the Index page I call it like this :

<% foreach (var item in Model) { %>
         <%: Html.DisplayFor(item.DrivingDistanceInMiles) %>

You're thinking about this the wrong way. You don't want to "add the asmx and call it", nor do you want to "add this function inside the index file".

Since you have the code, just add the code itself as a service class somewhere in your project. Something as simple as:

public class MapService
{
    public double GetDrivingDistanceInMiles(string origin, string destination)
    {
        // your code...
    }
}

( Ideally you'd want this service to implement an interface (something like a IMapService ) which you'd then use to inject this service as a dependency into your code. It may be above what you're trying to do now, but it's something to look into.)

Then anywhere in your project you can create an instance of this service and use it. Given what you're trying to do here:

foreach (var item in Model) {

It seems that your view model is a collection and you want to calculate this value on every item in that collection. One approach could be to add a calculated property to the model itself. Something like this:

// in your view model class
public double DrivingDistanceInMiles
{
    get
    {
        return new MapService().GetDrivingDistanceInMiles(this.Origin, this.Destination);
    }
}

Note, of course, that I'm guessing as to the structure of your model and what its properties might be called. But the idea is the same. You might make the service method static to avoid having to instantiate a new service object. Or you might even put GetDrivingDistanceInMiles() directly on the view model class if that's the only class in your project which would ever need it. (Though, if you do go the dependency injection route, I'd recommend keeping it as a separate service because the Google Maps API is an external dependency and doesn't belong in a model.)

Then in your view you'd simply bind to that property:

foreach (var item in Model) {
    // display item.DrivingDistanceInMiles somehow
}

There are a lot of ways you can structure this. But a couple of points remain throughout:

  1. Don't "add the asmx". ASMX is an application host technology. There's no need to obscure your code behind that when all you want to do is invoke the code itself. If you want multiple projects to share this code (one MVC, one ASMX) then just put the code itself in a separate class library referenced by both projects.
  2. Don't "add this function inside the index file". Views just bind to the models, they shouldn't contain complex server-side code. The models would reference any services they need to produce the values to which the views bind.

thank you David you inspired me to solved the code by create a new controller called " CallGoogleService" I pyt the function in it :

public double GetDrivingDistanceInMiles(string origin, string destination)
    {
        string url = @"http://maps.googleapis.com/maps/api/distancematrix/xml?origins=" +
      origin + "&destinations=" + destination +
      "&mode=driving&sensor=false&language=en-EN&units=imperial";
        //create object of HttpWebRequest that create requested object for the given url
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        WebResponse response = request.GetResponse();
        Stream dataStream = response.GetResponseStream();
        StreamReader sreader = new StreamReader(dataStream);
        string responsereader = sreader.ReadToEnd();
        response.Close();

        XmlDocument xmldoc = new XmlDocument();
        xmldoc.LoadXml(responsereader);


        if (xmldoc.GetElementsByTagName("status")[0].ChildNodes[0].InnerText == "OK")
        {
            XmlNodeList distance = xmldoc.GetElementsByTagName("distance");
            return Convert.ToDouble(distance[0].ChildNodes[1].InnerText.Replace(" mi", ""));
        }

        return 0;
    }

then in the Index view I put this code to call it

<% MvcNursery.Controllers.CallGoogleService ob = new MvcNursery.Controllers.CallGoogleService();%>

<% foreach (var item in Model) { %>
 <%string d =ob.GetDrivingDistanceInMiles(Postcode1,Postcode2).ToString(); %>

I know there is an easier way to call this controller but unfortunately I do know how .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM