这是我的观点:
@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>
现在,当用户单击作为“标签”的“按钮”时,它会将模型发送回控制器。但是我注意到它返回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; }
请注意,这两个属性不是您的普通字符串,int或datetime类型。因此,场景是当我将模型从Controller传递到View()时,我有数据,但是当我将模型从View()传递到Controller时,在“ Url.Action”中,只有一些属性填充有原始属性。价值观。知道为什么会这样吗?我到处都看过了,但是没有任何东西可以真正解释为什么我的2个属性以null返回。
我考虑过只创建一个具有两个不同类型的属性的ViewModel并将它们设置为字符串。
这是User属性的类:
[DataContract]
public class User
{
[DataMember(Name = "email")]
public string Email { get; set; }
}
它只包含一个字符串。
也接受任何建议。但是我真的很想了解将模型返回给Controller时发生了什么,为什么这两个属性返回为null。
答案 0 :(得分: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
)。可以重写此方法,但是它对正确绑定对象没有帮助。让我们看看如果执行此操作会发生什么。为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&User.Prop2=val2...
,依此类推。您的情况下,以下网址将按预期工作
"/MediaShuttle/SendEmail?Grants=grant1&Grants=grant2&Url=url&User.Email=test@test.com"
但是据我所知,Url.Action
是不可能实现的。这就是为什么传递复杂对象的更可取的方式是使用<form>
标签。