【问题标题】:View returns some properties as null to ControllerView 将一些属性作为 null 返回给 Controller
【发布时间】:2019-03-01 19:24:16
【问题描述】:

这是我的观点:

    @model MediaShuttleCoreWebApp.Models.MediaShuttleAPI.ApiResponse.TransferLinkResponseContainer

@{
    ViewData["Title"] = "CreateDownloadToken";
}

<h2>CreateDownloadToken</h2>


<div class="container we myBorder">
    <h3 class="text-center display-4 myBorder"> Media Shuttle </h3>
    @if (Model.User == null)
    {

    }
    <a class="btn btn-primary btn-lg" href="@Url.Action("SendEmail","MediaShuttle", Model)"
       role="button">Create Download Token</a>
    <p>Email: @Model.User.Email</p>
</div>

现在,当用户点击作为“a 标签”的“按钮”时,它会将模型发送回控制器。但是我注意到它返回 2 个属性为 NULL,其余属性填充了最初传递给 View() 的值。

这是传递给 View() 的模型:

namespace MediaShuttleCoreWebApp.Models.MediaShuttleAPI.ApiResponse
{
[DataContract]
    public class TransferLinkResponseContainer
{        
    [DataMember(Name = "id")]
    public string Id { get; set; }

    [DataMember(Name = "url")]
    public string Url { get; set; }

    [DataMember(Name = "createdOn")]
    public DateTime CreatedOn { get; set; }

    [DataMember(Name = "expiresOn")]
    public DateTime ExpiresOn { get; set; }

    [DataMember(Name = "user")]
    public User User { get; set; }

    [DataMember(Name = "grants")]
    public IList<string> Grants { get; set; }

    [DataMember(Name = "destinationPath")]
    public string DestinationPath { get; set; }

    [DataMember(Name = "notifications")]
    public IList<Notification> Notifications { get; set; }
}
}

返回为 NULL 的 2 个属性是:

public User User { get; set; }
public IList<Notification> Notifications { get; set; }

请注意,这 2 个属性不是您的普通字符串、整数或日期时间类型。所以场景是当我将模型从控制器传递到视图()时,我有数据,但是当我将模型从视图()传递到控制器时,在“Url.Action”中只有一些属性填充了原始数据价值观。知道为什么会这样吗?我到处寻找,但没有任何东西能真正解释为什么我的 2 个属性返回为空。

我考虑过创建一个具有这两个不同类型属性的 ViewModel 并将它们设置为字符串。

这是用户属性的类:

    [DataContract]
public class User
{
    [DataMember(Name = "email")]
    public string Email { get; set; }
}

它只包含一个字符串。

也欢迎任何建议。但是我真的很想了解当模型返回到控制器时发生了什么,为什么这两个属性返回为空。

【问题讨论】:

    标签: asp.net-mvc asp.net-core web-applications


    【解决方案1】:

    答案在于href 标签。例如,我将仅使用您的模型的一部分来展示导致这种行为的原因。

    public class TransferLinkResponseContainer
    {
        public string Url { get; set; }
    
        public User User { get; set; }
    
        public IList<string> Grants { get; set; }
    }
    
    public class User
    {
        public string Email { get; set; }
    }
    

    让我们实例化模型如下

    var model = new TransferLinkResponseContainer
    {
        Url = "url",
        User = new User
        {
            Email = "test@test.com"
        },
        Grants = new List<string> { "grant1", "grant2" },
    };
    

    使用此设置href 将包含以下值

    "/MediaShuttle/SendEmail?Grants=grant1&Grants=grant2&Url=url&User=ASPNETCoreDeploy.Controllers.User"
    

    我们可以看到它包含所有Grants 值、Url 值和User 类的全名(在您的项目中有所不同)。表示User 对象显然是无效的刺痛。模型绑定器无法根据请求从"ASPNETCoreDeploy.Controllers.User" 字符串绑定User 属性,这就是Usernull 的原因。

    为什么会这样?显然Url.Action 只是为传递模型的每个属性调用ToString 方法(或迭代集合并为每个元素调用ToString)。可以覆盖此方法,但它无助于正确绑定对象。让我们看看如果我们这样做会发生什么。将ToString 覆盖为User

    public class User
    {
        public string Email { get; set; }
    
        public override string ToString()
        {
            return Email;
        }
    }
    

    href 值变为

    "/MediaShuttle/SendEmail?Grants=grant1&Grants=grant2&Url=url&User=test@test.com"
    

    看起来更好,但无论如何你会得到User 等于null。要正确绑定 User 对象,您需要使用以下模板 User.Prop1=val1&amp;User.Prop2=val2... 等等。在您的情况下,以下网址将按预期工作

    "/MediaShuttle/SendEmail?Grants=grant1&Grants=grant2&Url=url&User.Email=test@test.com"
    

    但是(据我所知)使用Url.Action 是不可能实现的。这就是为什么传递复杂对象的更可取的方法是使用&lt;form&gt; 标签。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多