ASP.NET Core未将数据发送到操作模型。

huangapple go评论62阅读模式
英文:

ASP.NET Core not post data to Action Model

问题

当从 Ajax Post 发送数据到 Action 方法时,模型始终为 null。尝试过使用 FromBody 和不使用它,都失败了。我正在使用 .NET Core 7.0。

我的控制器 Action 方法:

[HttpPost]
public async Task<JsonResult> AddOrUpdateAddress([FromBody]AddressViewModel model)
{
    var address = _mapper.Map<Address>(model);

我的 Ajax 函数:

$.ajax({
    url: "/Company/AddOrUpdateAddress",
    type: "POST",
    async: false,
    contentType: "application/json;",
    data: JSON.stringify(address),
    success: function (response) {
        company.details.address.addEdit.closeDetails();
        $.notify('已保存', { position: "top right", className: "success" });
    },
    error: function (e) {
        $.notify('错误', { position: "top right", className: "error" });
        return false;
    }
});

模型如下:

public class AddressViewModel
{
    // ...(省略部分内容)
    public bool IsDeleted { get; set; }
}

字符串化的请求体消息:

{
    "CountryId": "2",
    "AddressTypeId": "9",
    "Address1": "7th Floor, South Wing, ",
    "Address2": "Krishe Sapphire",
    "Zip": "500081",
    "StateId": "92",
    "City": "Hyderabad",
    "StateName": "",
    "Id": "607",
    "PrimaryHrContactUserId": "",
    "PrimaryFinanceContactUserId": "",
    "PrimaryFacilityContactUserId": "",
    "IsDefault": false,
    "IsDeleted": false,
    "OperatingHours": [
        {
            "Id": 0,
            "Day": "Sunday",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsClosed": true,
            "CompanyId": 1,
            "AddressId": 1
        },
        // ...(省略部分内容)
    ],
    "Shifts": [
        {
            "Id": "0",
            "ShiftName": "Regular",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsActive": false,
            "CompanyId": 1,
            "AddressId": 1
        },
        // ...(省略部分内容)
    ]
}

请使用以下链接获取用于重现错误的示例代码:
示例代码链接

英文:

When posting data to Action Method from Ajax Post to Action Method, model is always null. Tried with FromBody and without it, both fails. I am using .NET Core 7.0

My Controller Action Method

[HttpPost]
public async Task<JsonResult> AddOrUpdateAddress([FromBody]AddressViewModel model)
{
	var address = _mapper.Map<Address>(model);

My Ajax function

$.ajax({
	url: "/Company/AddOrUpdateAddress",
	type: "POST",
	async: false,
	contentType: "application/json;",
	data: JSON.stringify(address),
	success: function (response) {
		company.details.address.addEdit.closeDetails();
			$.notify('Saved', { position: "top right", className: "success" });
	},
	error: function (e) {
		$.notify('Error', { position: "top right", className: "error" });
		return false;
	}
});

Model is as below

public class AddressViewModel
    {
        public int Id { get; set; }
        [Display(Name = "Address Type")]
        public int? AddressTypeId { get; set; }
        public AddressType? Type { get; set; }
        public string? Address1 { get; set; }
        public string? Address2 { get; set; }
        public string? City { get; set; }
        [Display(Name = RegistrationTooltip.State)]
        public int? StateId { get; set; }
        public string? StateName { get; set; }
        [Display(Name = RegistrationTooltip.Country)]
        //[DefaultValue(0)]        
        public int CountryId { get; set; }
        [Display(Name = "Zip")]
        public string? Zip { get; set; }
        public string? FullAddress =>
            new Regex("[ ]{2,}", RegexOptions.None).Replace(
                $"{Address1?.Humanize(LetterCasing.Title)}, {Address2?.Humanize(LetterCasing.Title)}<br/> {City?.Humanize(LetterCasing.Title)} {(!StateId.HasValue ? StateName?.Humanize(LetterCasing.Title) : State?.Name?.Humanize(LetterCasing.Title))} - {Zip}<br/> <span><img src=\"/3rdParty/flags/blank.gif\" class=\"flag flag-{Country?.TwoLetterIsoCode}\" alt=\"{Country?.Name?.Humanize(LetterCasing.Title)}\"> {Country?.Name?.Humanize(LetterCasing.Title)}</span>",
                " ");
        public int? CompanyId { get; set; }
        [Display(Name = "Is Default")]
        public bool IsDefault { get; set; }
        [Display(Name = "Primary Hr Contact")]
        public string? PrimaryHrContactUserId { get; set; }
        [Display(Name = "Primary Finance Contact")]
        public string? PrimaryFinanceContactUserId { get; set; }
        [Display(Name = "Primary Facility Contact")]
        public string? PrimaryFacilityContactUserId { get; set; }
        [Display(Name = "Additional Hr Recipients")]
        public string? AdditionalHrRecipients { get; set; }
        [Display(Name = "Additional Finance Recipients")]
        public string? AdditionalFinanceRecipients { get; set; }

        [Display(Name = "Additional Facility Recipients")]
        public string? AdditionalFacilityRecipients { get; set; }
        public  State? State { get; set; }
        public Country? Country { get; set; }

        public List<ShiftViewModel>? Shifts { get; set; }

        public List<OperatingHourViewModel>? OperatingHours { get; set; }
        
        public UserLiteDTO ? PrimaryHrContactUser { get; set; }
       
        public UserLiteDTO? PrimaryFinanceContactUser { get; set; }
     
        public UserLiteDTO? PrimaryFacilityContactUser { get; set; }
        public bool IsDeleted { get; set; }
    }

stringify body messages

{
    "CountryId": "2",
    "AddressTypeId": "9",
    "Address1": "7th Floor, South Wing, ",
    "Address2": "Krishe Sapphire",
    "Zip": "500081",
    "StateId": "92",
    "City": "Hyderabad",
    "StateName": "",
    "Id": "607",
    "PrimaryHrContactUserId": "",
    "PrimaryFinanceContactUserId": "",
    "PrimaryFacilityContactUserId": "",
    "IsDefault": false,
    "IsDeleted": false,
    "OperatingHours": [
        {
            "Id": 0,
            "Day": "Sunday",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsClosed": true,
            "CompanyId":1,
            "AddressId":1
        },
        {
            "Id": 0,
            "Day": "Monday",
            "OpeningTime": "11:00 AM",
            "ClosingTime": "4:30 PM",
            "IsClosed": false,
            "CompanyId":1,
            "AddressId":1
        },
        {
            "Id": 0,
            "Day": "Tuesday",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsClosed": false,
            "CompanyId":1,
            "AddressId":1
        },
        {
            "Id": 0,
            "Day": "Wednesday",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsClosed": false,
            "CompanyId":1,
            "AddressId":1
        },
        {
            "Id": 0,
            "Day": "Thursday",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsClosed": false,
            "CompanyId":1,
            "AddressId":1
        },
        {
            "Id": 0,
            "Day": "Friday",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsClosed": false,
            "CompanyId":1,
            "AddressId":1
        },
        {
            "Id": 0,
            "Day": "Saturday",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsClosed": false,
            "CompanyId":1,
            "AddressId":1
        }
    ],
    "Shifts": [
        {
            "Id": "0",
            "ShiftName": "Regular",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsActive": false,
            "CompanyId": 1,
            "AddressId":1
        },
        {
            "Id": "0",
            "ShiftName": "Morning",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsActive": false,
            "CompanyId": 1,
            "AddressId":1
        },
        {
            "Id": "0",
            "ShiftName": "Night",
            "OpeningTime": "",
            "ClosingTime": "",
            "IsActive": false,
            "CompanyId": 1,
            "AddressId":1
        }
    ]
}

Here is the sample code base to reproduce the error
https://filetransfer.io/data-package/16ZC8Bck#link

Steps to reproduce

  1. Run the above code in VisualStudio
  2. Using PostMan or some other Restful API tool do a HTTPS Post with the payload (request body) shared above as stringify body messages

答案1

得分: 1

你的代码看起来还可以,但你的模型和载荷存在一些数据不一致的问题。

例如,我发现你期望 Id 字段是 integer,但传递的是 string。你还有许多嵌套模型。但主要问题是在一些嵌套模型中,你期望的是 TimeSpan,但传递了不正确的数据或空字符串。

在我的示例中,我使用了等于 00:00:00.0000001 的 TimeSpan 值。

一旦我在本地修复了这些问题,模型就可以成功解析。

英文:

Your code looks okay, but you have some data inconsistency in your model and payload.

For example, I found that you expect Id fields as integer, but pass them as string. You also have numerous nested models. But the main problem is that in some of your nested moodel you expected TimeSpan but passed incorred data or empty string.

In my example i used TimeSpan values equal 00:00:00.0000001

Once I fixed that locally, the model can be parsed sucessfully
ASP.NET Core未将数据发送到操作模型。

答案2

得分: 1

根据 @adalyat Nazirov 的指示,问题出在时间跨度属性上。我将属性更改为字符串,并在代码中进行了处理,然后问题得以解决。

private string? _openingTimeString;
private string _closingTimeString;

public string? OpeningTimeString
{
    get { return _openingTimeString; }
    set
    {
        _openingTimeString = value;
        if (!string.IsNullOrWhiteSpace(value) && DateTime.TryParse(value, out var _openingTime))
        {
            OpeningTime = _openingTime.TimeOfDay;
        }
    }
}
public string? ClosingTimeString
{
    get { return _closingTimeString; }
    set
    {
        _closingTimeString = value;
        if (!string.IsNullOrWhiteSpace(value) && DateTime.TryParse(value, out var _closingTime))
        {
            ClosingTime = _closingTime.TimeOfDay;
        }
    }
}
[Display(Name = "Opening Time"), JsonIgnore]
public TimeSpan? OpeningTime { get; set; }

[Display(Name = "Closing Time"), JsonIgnore]
public TimeSpan? ClosingTime { get; set; }
英文:

as @adalyat Nazirov pointed, the issue was with timespan property. I changed the property to string and handled in codebase then post worked.

private string? _openingTimeString;
        private string _closingTimeString;

 public string? OpeningTimeString
        {
            get { return _openingTimeString; }
            set
            {
                _openingTimeString = value;
                if (!string.IsNullOrWhiteSpace(value) && DateTime.TryParse(value, out var _openingTime))
                {
                    OpeningTime = _openingTime.TimeOfDay;
                }
            }
        }
        public string? ClosingTimeString
        {
            get { return _closingTimeString; }
            set
            {
                _closingTimeString = value;
                if (!string.IsNullOrWhiteSpace(value) && DateTime.TryParse(value, out var _closingTime))
                {
                    ClosingTime = _closingTime.TimeOfDay;
                }
            }
        }
        [Display(Name = "Opening Time"), JsonIgnore]
        public TimeSpan? OpeningTime { get; set; }

        [Display(Name = "Closing Time"), JsonIgnore]
        public TimeSpan? ClosingTime { get; set; }

huangapple
  • 本文由 发表于 2023年7月3日 20:25:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76604728.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定