asp MVC:是否可以确定如何调用控制器方法?

时间:2020-12-29 01:51:30

Is it possible for a controller method to return a view if called restfully and if called, via JavaScript, would return a JsonResult. My motivation is that I want to have the freedom to implement my view however I want to do this WITHOUT having to create two controller methods (one for each separate scenario...see elaboration below).

如果调用restfully,控制器方法是否有可能返回一个视图,如果通过JavaScript调用它将返回一个JsonResult。我的动机是我希望能够*地实现我的视图但是我想要这样做而不必创建两个控制器方法(每个单独的场景一个...请参阅下面的详细说明)。

If let's say I type in www.example.com/person/get?id=232 in the browser, I would want the Get(int id) method to do something like the following:

如果我说我在浏览器中输入www.example.com/person/get?id=232,我希望Get(int id)方法执行以下操作:

    
        public ActionResult Get(int id)
        {
             Person somePerson = _repository.GetPerson(id);
             ViewData.Add("Person", somePerson);
             return View("Get");
        }
    

But if let's say this same controller method is called via jQuery:

但是如果让我们说通过jQuery调用相同的控制器方法:

    
        //controller method called asynchronously via jQuery
        function GetPerson(id){
            $.getJSON(
                "www.example.com/person/get", //url
                { id: 232 }, //parameters
                function(data)
                { 
                    alert(data.FirstName); 
                }   //function to call OnComplete
            );
        }
    

I would want it to act like the following:

我希望它的行为如下:

    
        public JsonResult Get(int id)
        {
            Person somePerson = _repository.GetPerson(id);
            return Json(somePerson);
        }
    

2 个解决方案

#1


I figured it out. In the particular scenario above, I can do:

我想到了。在上面的特定场景中,我可以这样做:

    
        if(Request.IsAjaxRequest())
        {
            return Json(someObject);
        }
        else
        {
            ViewData.Add("SomeObject", someObject);
            return View("Get");
        }
    

I can now start working on a more "elegant" solution to this problem....>_<

我现在可以开始研究这个问题的更“优雅”的解决方案....> _ <

#2


You can do this using the ActionMethodSelector Attribute.
First Create your attribute like this:

您可以使用ActionMethodSelector属性执行此操作。首先像这样创建你的属性:

 public class IsAjaxRequest :ActionMethodSelectorAttribute
    {
       public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
       {
           return controllerContext.HttpContext.Request.IsAjaxRequest();
       }

    }

Then use it:

然后使用它:

 public ActionResult Get( int id )
 {
          Person somePerson = _repository.GetPerson(id);
          ViewData.Add("Person", somePerson);
          return View("Get");
 }


 [IsAjaxRequest]
 [ActionName("Get")]
 public ActionResult Get_Ajax( int id )
 {
         Person somePerson = _repository.GetPerson(id);
         return Json(somePerson);

 }

#1


I figured it out. In the particular scenario above, I can do:

我想到了。在上面的特定场景中,我可以这样做:

    
        if(Request.IsAjaxRequest())
        {
            return Json(someObject);
        }
        else
        {
            ViewData.Add("SomeObject", someObject);
            return View("Get");
        }
    

I can now start working on a more "elegant" solution to this problem....>_<

我现在可以开始研究这个问题的更“优雅”的解决方案....> _ <

#2


You can do this using the ActionMethodSelector Attribute.
First Create your attribute like this:

您可以使用ActionMethodSelector属性执行此操作。首先像这样创建你的属性:

 public class IsAjaxRequest :ActionMethodSelectorAttribute
    {
       public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
       {
           return controllerContext.HttpContext.Request.IsAjaxRequest();
       }

    }

Then use it:

然后使用它:

 public ActionResult Get( int id )
 {
          Person somePerson = _repository.GetPerson(id);
          ViewData.Add("Person", somePerson);
          return View("Get");
 }


 [IsAjaxRequest]
 [ActionName("Get")]
 public ActionResult Get_Ajax( int id )
 {
         Person somePerson = _repository.GetPerson(id);
         return Json(somePerson);

 }