0

这是我的观点:

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

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

这是 User 属性的类:

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

它只包含一个字符串。

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

4

1 回答 1

0

答案在于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对象显然是无效的刺痛。模型绑定器无法根据请求绑定字符串中的User属性"ASPNETCoreDeploy.Controllers.User",所以这User就是null.

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

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&User.Prop2=val2...等。在您的情况下,以下网址将按预期工作

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

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

于 2019-03-02T14:18:11.867 回答