【问题标题】:can I use FromBody and FromUri in .net MVC?我可以在 .net MVC 中使用 FromBody 和 FromUri 吗?
【发布时间】:2018-07-04 01:25:12
【问题描述】:

我有一个 asp.net MVC 控制器(不是 web api,不是核心)我正在尝试一个也有 uri 变量的帖子。但我收到了。

找不到 FromBody 是否缺少 using 指令或 汇编参考

FromUri 也一样

using CFF.CareCenterPortal.BeInCharge.Services;
using CFF.CareCenterPortal.BeInCharge.ViewModels;
using CFF.CareCenterPortal.Web.Controllers.Portal;
using System;
using System.Web.Mvc;

namespace CFF.CareCenterPortal.Web.Controllers.BeInCharge
{
    [Authorize]
    [RoutePrefix("beincharge/caregiver")]
    public class BeInChargeCaregiverController : IdentityController
    {
        [HttpPost] 
        [Route("{id}")]
        public ActionResult EditCaregiver([FromBody()] CareGiverViewModel data, [FromUri()] int id)

        {
            var service = new BeInChargeDataService();
            var result = service.EditCaregiver(data,id,CurrentUser.NameIdentitifier);
            if (result == null)
            {
                return new HttpStatusCodeResult(System.Net.HttpStatusCode.InternalServerError, "An Unhandled Error Occcured");
            }

            if (!String.IsNullOrEmpty(result.Error) && !String.IsNullOrWhiteSpace(result.Error))
            {
                return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest, result.Error);
            }

            return Json("Success");
        }

【问题讨论】:

  • 你为什么要这样做?
  • 好吧,因为我正在做一个有我的视图模型的帖子。但我们只是要求我们所有传出的 web api 调用也需要另一个变量。 (所以我在帖子的视图模型中有数据,并且我将 id 作为 uri 变量)所以它就像一个带有 uir blah/blah/15 的帖子,我需要 15 以及来自与视图模型相关的帖子
  • MVC ModelBinder 已经做到了。它结合了所有传入的值(Route、QueryString 和 Body)并实现了所有适用的参数。

标签: c# .net asp.net-mvc


【解决方案1】:

我可以在 .net MVC 中使用 FromBody 和 FromUri 吗?

没有。据我了解,这些属性只是 WebAPI 约定。您的选择是使用 WebAPI 控制器(非常简单)或编写自己的 Custom Model Binder for MVC,它可以检查参数的属性以模仿您的需求。

我不确定你是否知道,但 MVC ModelBinder 已经从 Route、QueryString 和 Body 获取值以实现参数。

欢迎您查看Source Code to MVC。最重要的是ValueProviderFactories,其方法如下:

    private static readonly ValueProviderFactoryCollection _factories 
      = new ValueProviderFactoryCollection()
    {
        new ChildActionValueProviderFactory(),
        new FormValueProviderFactory(),
        new JsonValueProviderFactory(),
        new RouteDataValueProviderFactory(),
        new QueryStringValueProviderFactory(),
        new HttpFileCollectionValueProviderFactory(),
        new JQueryFormValueProviderFactory()
    };

这是 MVC 用来向模型绑定器提供值的方法。

例子:

我采用了默认 MVC 网站并进行了以下更改:

/views/home/Index.cshtml

第 8 行:

    <p><a class="btn btn-primary btn-lg js-test">Learn more &raquo;</a></p>

添加到文件底部:

<script src="https://code.jquery.com/jquery-3.3.1.min.js"
        integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
        crossorigin="anonymous"></script>
<script>
    $(document).ready(function () {
        $('.js-test').on('click', function () {
            $.ajax({
                url: '@Url.RouteUrl(new{ action="Name", controller="Home", id=5})',
                data: JSON.stringify({Name: 'My Test Name' }),
                    type: 'POST',
                    dataType: 'json',
                    contentType: "application/json",
            });
        })
    });
</script>

添加了以下文件:

/Models/Home/TestVM.cs

public class TestVM
{
    public string Name {  get; set; }
}

更新了控制器:

/Controllers/HomeController.cs:

    public ActionResult Name(TestVM test, int id)
    {
        System.Diagnostics.Debug.WriteLine(test.Name);
        System.Diagnostics.Debug.WriteLine(id);
        return new  EmptyResult();
    }

现在点击按钮时,会发出以下请求:

Request URL: http://localhost:53549/Home/Name/5
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:53549
Referrer Policy: no-referrer-when-downgrade
Cache-Control: private
Content-Length: 0
Date: Tue, 03 Jul 2018 17:21:55 GMT
Server: Microsoft-IIS/10.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 23
Content-Type: application/json
Host: localhost:53549
Origin: http://localhost:53549
Pragma: no-cache
Referer: http://localhost:53549/

{Name: "My Test Name"}  
Name
:
"My Test Name"

我的调试窗口打印:

我的测试名称

5

My Test Name 是来自 JsonValueProviderFactory 的 ModelBound,来自 url http://localhost:53549/Home/Name/5 的 id 是来自 RouteDataValueProviderFactory 的 ModelBound。

【讨论】:

  • 好吧,也许我会在我的视图模型中添加这个额外的参数并完成它。
  • 那么您是说以下应该有效吗? public ActionResult EditCaregiver(CareGiverViewModel data, int id)
猜你喜欢
  • 1970-01-01
  • 2016-05-11
  • 2012-08-17
  • 2014-03-10
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多