如何从jQuery调用C#静态方法

时间:2017-10-03 23:54:28

标签: c# jquery asp.net-mvc asp.net-web-api

我看过一些文章,展示了如何使用Microsoft的[WebMethod]为Web窗体应用程序从JavaScript调用C#方法。我想对ASP.NET MVC应用程序做同样的事情。我有一个C#静态方法,它返回翻译的数据:

public static string Translate(string word)
{
  return langRepo.Translate(word);
}

上述功能在服务器端代码中运行良好。但是,我想将相同的代码扩展到客户端。理想情况下,我想创建一个像这样的jQuery函数:

function Translate(word) {
  //call C# translate method and return result
}

并像这样使用它:

"<hr /><h5>" + Translate(heading) + "</h5>";

我该怎么做?

Enter image description here

Enter image description here

Enter image description here

4 个答案:

答案 0 :(得分:0)

执行以下操作:

  • 在服务器端的功能上添加[WebMethod]
  • 来自客户端的呼叫应该类似于以下代码段:

提示:类型应为#34; POST&#34;类型。检查this以获取完整示例。

function Translate(word){
  // Type of data passed should match the function's parameters
  var data = {word: word};
  $.ajax({
    type: "POST",
    url: "pageName.aspx/Translate",
    data: data,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    error: function (XMLHttpRequest, textStatus, errorThrown) {
      alert("Request: " + XMLHttpRequest.toString() + "\n\nStatus: " + textStatus + "\n\nError: " + errorThrown);
    },
    success: function (response) {
      // Here you can assign response to tags.
      // If response was empty, try response.d.
      $("#id").html(response);

    }
  });
}

如果您正在使用ASP.NET MVC应用程序,则可以使用[HttpGet]代替并以JSON格式返回函数(Action)中的结果,因为我们在Ajax请求中指定了我们期望{{1 }}

以下是一个例子:

dataType: "json"

在Ajax调用的成功处理程序中,通过访问[HttpGet] public ActionResult Translate(String word) { var resultWord = ModelInit.repo.TranslateItem(word); return Json(new {result = resultWord}, JsonRequestBehavior.AllowGet); } 属性获取值:

result

答案 1 :(得分:0)

尝试以下方法。首先是一个C#控制器动作,它将返回一个json,然后从jQuery方法调用控制器动作。

public class LanguageController : Controller
{
    [HttpGet]
    public JsonResult Translate(string word) 
    {
        var translatedWord = langRepo.Translate(word);
        return Json(translatedWord, JsonRequestBehavior.AllowGet); 
    }
}

jQuery方法:

function Translate(word){ 
    $.ajax({
        type: "GET",
        url: "/Language/Translate",
        data: {word: word},
        dataType: "json",
        cache: false,
        success: function (data) {
            if(data.length == 0) {
                alert("Cannot translate.");
            }
            else {
                // Get the translated word
                var translatedWord = data.translatedWord;

                // Update the DOM element (label) with translated word 
                $("#translatedWord").text(translatedWord);
            }
        }
    });
}

答案 2 :(得分:0)

在我多年的编程中,我第一次不得不将AJAX调用更改为同步,以使其按照我想要的方式工作。所需的只是将 &#34; async:false&#34; 属性添加到AJAX调用中。这样,AJAX调用就像任何其他同步函数一样对待:

function Translate(word) {
    var Url = "/api/translate/" + word;
    var translated;

    $.ajax({
        type: "GET",
        url: Url,
        dataType: "json",
        cache: false,
        async: false,
        success: function (response, status, xhr) {
            translated = response.translatedWord;
        },
        error: function (jqXhr, textStatus, errorThrown) {
            var error = CapitalizeFirst(textStatus) + ": " + errorThrown + " - " + jqXhr.responseText;
            bootbox.alert(error);
        }
    });

    return translated;
}

对于那些想要将其作为项目解决方案实施的人,请再想一想!使AJAX调用同步并非易事。这样做会强制用户在程序再次响应之前等待服务器的响应。除非您确定数据集很小并且访问频率不是很高,否则您应该寻找其他方法。

答案 3 :(得分:0)

我无法看到您的屏幕截图(imgur域名已被阻止)并且您没有发布大量代码,因此我将向您展示我是如何做到这一点的,并且我可以更新答案以便更好地回答你的问题稍后。

我调用了一个存储过程并使用AJAX将结果数据插入到我的页面中。

首先,我在C#中有一个包含开始和结束日期的对象。我的模特:

public class DateRange
{
    public DateTime? StartDate { get; set; }
    public DateTime? EndDate { get; set; }
}

我的数据访问层(DateRepository),它调用我的存储过程(因为它与此问题无关,因此对其进行了匿名化):

public static List<DateRange> GetDates(int number)
{
    // execute stored procedure, ORM converts the rows to a list of objects
    ...
    return dateRanges;
}

我的服务层,它调用数据访问层:

[Route("Dates/{number}")]
public IHttpActionResult Get_DateRanges(int number)
{
    var response = DateRepository.GetDates(number);
    return Json(response);
}

Json(result)来自System.Web.Http&gt; ApiController&gt; JsonResult<T> Json<T>(T content)

现在,我的UI层控制器调用此服务方法:

public async Task<JsonResult> Get_DateRanges(int number)
{
    var response = await ServiceClient.HttpGetList<DateRange>([url here calling /Dates/{number} ]);
    return new JsonResult { Data = response, MaxJsonLength = Convert.ToInt32(WebConfigurationManager.AppSettings["MaxJsonLength"]), JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}

那个ServiceClient方法(简化,省略授权等细节):

public static class ServiceClient
{
    public static async Task<List<T>> HttpGetList<T>(string url)
    {
        using (var client = SetupHttpClient())
        {
            HttpResponseMessage response = await client.GetAsync(url);
            CheckResponse(response);

            var tList = await response.Content.ReadAsAsync<List<T>>();
            return tList;
        }

    }
}

请记住,此JSONResult属于List<DateRange>。这将是JSON的数据字段中的内容。

最后,调用UI控制器方法的javascript代码:

function updateDateRanges() {
    var nNumber = $("input#Number").val();
    var params = { number: nNumber };

    // note the JSON call is to the UI layer
    $.getJSON(ROOT + "UIController/Get_DateRanges", params, function (data) { })
    .done(function (data) {
        // change model values from server
        $("input#StartDate").val(data[0].StartDate);
        $("input#EndDate").val(data[0].EndDate);
    })
    .fail(function () {
        errorAlert("Error retrieving dates.");
    })


}

请注意,我检索日期的方式(例如data[0].StartDate)是因为我有一个日期范围对象列表。由于您可以单独调用返回JSON的函数(就像我在我的浏览器中输入了服务层的URL一样),因此很容易看到JSON data的样子。

通过查看您的评论,您的问题似乎根本不是原始帖子中所述的内容,而是对javascript异步性质的基本理解。请考虑以下示例:

$("#output").click(function() {
    var inputText = $("#output").text();
    translateWord(inputText);
});

function translateWord(word){
    getTranslationFromServer(word);
}

function getTranslationFromServer(word) {
    // using setTimeout to simulate slow response (2 seconds) instead of AJAX request
    setTimeout(function(){
        $("#output").text("texto en español");
    }, 2000);

    $("#output").css('background-color', 'yellow');

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="output">
English text
</div>

请注意,即使首先调用setTimeout函数,立即发生的事情是背景变为黄色,2秒后文本被翻译。这是由于Javascript的异步性质。当它在等待你的AJAX调用时,它已经转移到下一行。因此,在您的特定示例中,您设置var t = "";,进行AJAX调用,下一行是return t;。因此,当您等待AJAX​​调用时,程序已移至下一行,即return:退出此函数并将此值返回给调用者。因此,在您有机会完成之前,您将退出该功能。

好的,你真正的问题是:“在返回其他功能之前,我如何等待这个javascript函数完成?”好吧,我最初建议回调,但现在更好的解决方案是使用promises。由于您似乎使用jQuery,我将使用他们的promise library:

$("#output").click(function() {
    var inputText = $("#output").text();
    translateWord(inputText);
});

function translateWord(word){
    $("#output").text("waiting...");
    $.when(getTranslationFromServer(word))
	.then(
    	function(word) {
    		$("#output").text(word);
                $("#output").css('background-color', 'orange');
    	}
  		
    );
}

function getTranslationFromServer(input) {
$("#output").css('background-color', 'yellow');
    var deferred = new $.Deferred();
    var output = "";
    // using setTimeout to simulate slow response (2 seconds) instead of AJAX request
    setTimeout(function(){
        // mock translate function
        if (input === "English text") {
            output = "texto en español";
        }
        else if (input === "texto en español") {
            output = "English text";
        }
        else {
            output = "No translation for this text found."
        }
        deferred.resolve(output);
        }, 2000);

    return deferred.promise();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output">English text</div>

我更改了背景颜色,希望能帮助您按照javascript所在的代码进行操作。我相信这最终会回答你关于javascript的XY问题。