【问题标题】:adding asmx file in MVC 4 in ASP.NET在 ASP.NET 的 MVC 4 中添加 asmx 文件
【发布时间】:2015-12-26 15:54:06
【问题描述】:

我在 Visual Studio 2013 的 ASP.NET 中有一个 MVC 项目,并且我有一个 asmx 文件,其中包含一个函数,该函数包含调用谷歌距离矩阵

在索引页面我需要调用asmx文件,

asmx 文件包含以下函数:

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;
    }

你能告诉我如何在 MVC 解决方案中添加 asmx 文件并调用它

或者如何在索引文件中添加这个函数我不能在控制器中添加它,因为我需要像这样在循环中调用它

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

我试图将代码放在模型中的类中,如下所示:

Google Service class

Distance Class

在索引页面中我这样称呼它:

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

【问题讨论】:

  • 不要“添加 asmx 并调用它”。您拥有代码本身,只需将代码添加到您的项目中。作为适用模型上的方法或作为某处的辅助函数(如果适用,可能是static)。这个特殊的功能看起来更像是一个服务而不是一个模型。
  • 你能告诉我如何把它放在一个方法中并在循环中调用它吗?因为我试过了,但我不能提前感谢

标签: c# asp.net asp.net-mvc web-services asp.net-mvc-4


【解决方案1】:

你想错了。您不想“添加 asmx 并调用它”,也不想“在索引文件中添加此函数”。

既然您有代码,只需将代码本身作为服务类添加到项目中的某处即可。一些简单的事情:

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

理想情况下您希望该服务实现一个接口(类似于IMapService),然后您可以使用该接口将该服务作为依赖项注入进入你的代码。它可能超出你现在想要做的,但它是需要研究的东西。)

然后,您可以在项目中的任何地方创建此服务的实例并使用它。鉴于您在这里尝试做的事情:

foreach (var item in Model) {

您的视图模型似乎是一个集合,并且您希望在该集合中的每个项目上计算此值。一种方法是向模型本身添加计算属性。像这样的:

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

当然,请注意,我猜测的是您的模型的结构以及它的属性可能被称为什么。但想法是一样的。您可以创建服务方法static 以避免必须实例化新的服务对象。或者您甚至可以将GetDrivingDistanceInMiles() 直接放在视图模型类上,如果这是您项目中需要它的only 类。 (不过,如果您确实采用依赖注入路线,我建议将其作为单独的服务保留,因为 Google Maps API 是外部依赖项,不属于模型。)

那么在您看来,您只需绑定到该属性:

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

有很多方法可以构建它。但始终有几点:

  1. 不要“添加 asmx”。 ASMX 是一种应用程序主机技术。当您想要做的只是调用代码本身时,无需隐藏您的代码。如果您希望多个项目共享此代码(一个 MVC,一个 ASMX),那么只需将代码本身放在两个项目都引用的单独类库中。
  2. 不要“在索引文件中添加这个函数”。视图只是绑定到模型,它们不应该包含复杂的服务器端代码。模型将引用它们生成视图绑定的值所需的任何服务。

【讨论】:

  • 我试图在 Models 文件夹( MapService , DrivingDistanceInMiles )和主文件夹的索引页面中创建两个类,我试图显示 item.DrivingDistanceInMile 但它不起作用,可能是我错了因为我不知道什么是服务类和视图模型类
  • @John:好吧,这里没有人能告诉你可能出了什么问题,而不会看到你的代码或任何失败的迹象。
  • @John:好的,您的Distance 类显然甚至无法编译。它缺少OriginDestination 属性(或任何您将要传递给该服务函数的值)。如果Distance 是您视图中的模型,则它没有任何实际数据可在视图中使用。所以不清楚你到底想做什么。
  • 我像你所说的那样编辑代码 this.origin 但对我来说问题是如何在 for 循环内的索引中调用它,抱歉可能我不擅长 MVC 但我我尽力了
  • @John:好吧,如果你没有值作为起点和终点,那么你希望如何首先使用这个GetDrivingDistanceInMiles()函数?您可能想在这里重新考虑您的设计。为了有效地调用这个函数,你需要这两个值。
【解决方案2】:

谢谢大卫,你启发了我通过创建一个名为“CallGoogleService”的新控制器来解决代码,我在其中使用了函数:

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;
    }

然后在索引视图中我把这段代码调用它

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

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

我知道有一种更简单的方法来调用这个控制器,但不幸的是我知道怎么做。

【讨论】:

  • 在未来,提供描述性错误信息会有很大帮助。 “不起作用”并没有告诉我们任何事情,因为它可能有十亿个错误,错误消息会缩小范围。
猜你喜欢
  • 1970-01-01
  • 2012-08-16
  • 2013-09-14
  • 1970-01-01
  • 1970-01-01
  • 2014-01-18
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多