programing

Ajax가 빈 값을 전달하지만 ASP에서 컨트롤러가 null이 됩니다.NET MVC

subpage 2023. 10. 1. 19:27
반응형

Ajax가 빈 값을 전달하지만 ASP에서 컨트롤러가 null이 됩니다.NET MVC

같이 일하고 있습니다.ASP.NET MVC다에서 가 있습니다.Ajax내 통제관에게.

제게 이런 것이 있다고 치자.

public class SampleViewModel
{
    private string _firstName = string.Empty;

    public SampleViewModel()
    {
        _firstName = string.Empty;
    }

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value ?? string.Empty; }
    }

    public string LastName { get; set; }

    public string FullName { get; set; }
}

컨트롤러

[HttpPost]
public JsonResult ActionSubmit(SampleViewModel model)
{               
    var result = "";

    if(model.FirstName == null)
          result += "\nFirstName is null";

    if(model.LastName == null)
          result += "\nLastName is null";

    return Json(result);
}

아약스

$('.submit').click(function() {
        $.ajax({
            url: '@Url.RouteUrl(new{ action="ActionSubmit", controller="Home"})',
            data: JSON.stringify({ FirstName: '', LastName: '', FullName: 'Phong_Nguyen' }),
                  // Even though I use { FirstName: '', LastName: '', FullName: 'Phong_Nguyen' } without JSON.stringify
            type: 'POST',
            dataType: 'json',
            contentType: "application/json; charset=utf-8",
            success: function(resp) {
                   alert(resp);
            }});
         });

보시다시피 빈 값을 전송하지만 컨트롤러 끝에서 null(응답 값은 항상 "LastName은 null"입니다):

질문.

  1. 에서 죠를 입니까?empty, 알겠습니다.null내 컨트롤러에 가치가 있습니까?

  2. 아래와 같이 제 문제를 해결할 수 있는 더 나은 방법과 우아한 방법이 있을까요?

public string FirstName
{
   get { return _firstName; }
   set { _firstName = value ?? string.Empty; }
}

에서 빈 때 가 아약스 에서, 를 되는입니까?null내 컨트롤러에 가치가 있습니까?

stringsnull.ModelBinder요청에 값이 제공되지 않으면 속성을 기본값으로 설정합니다.

아래와 같이 제 문제를 해결할 수 있는 더 나은 방법과 우아한 방법이 있을까요?

  1. 를(를) 사용하여 을 달 수 .[DisplayFormat(ConvertEmptyStringToNull = false)] 빈 됩니다.

  2. 사용자 정의를 작성할 수 있습니다.ModelBinder을 이루는ConvertEmptyStringToNull.false, 전세계적으로 적용할 수 있습니다.

public class NullStringModelBinder : DefaultModelBinder {
    public override object BindModel(ControllerContext controllerContext,
                                     ModelBindingContext bindingContext) {
        bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
        return base.BindModel(controllerContext, bindingContext);
    }
}

//register it in Application_Start()
ModelBinders.Binders.Add(typeof(string), new NullStringModelBinder());

이 특정 변경 사항은 여기에 기록되어 있으며, 이는 다음과 같은 변경 사항 중 하나입니다.MVC 1.0을 에 이 입니다.null는 s 는됩니다.ModelMetadata.ConvertEmptyStringToNull산이 하는 재산DefaultModelBinder.

이제 모든 속성에 주석을 달지 않으려면 사용자 정의 모델 바인더를 작성할 수 있습니다.

public class EmptyStringModelBinder : DefaultModelBinder 
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
        Binders = new ModelBinderDictionary() { DefaultBinder = this };
        return base.BindModel(controllerContext, bindingContext);
    }
}

그리고 그것을 당신의 것에.Global.asax:

ModelBinders.Binders.DefaultBinder = new EmptyStringModelBinder();

또는 특정 작업을 수행할 수 있습니다.

[HttpPost]
public JsonResult ActionSubmit([ModelBinder(typeof(EmptyStringModelBinder))SampleViewModel model)

왜 이렇게 된 거지?

a .string이다.null는 ㅇstringreference type.null 이러한 일 수 따라서 이러한 프레임워크 변경은 합리적일 수 있습니다.그러나 다른 한편으로는 null 값을 아예 피하도록 노력해야 하므로 이러한 경우를 피하기 위해 맞춤형 모델 바인더를 작성해야 합니다.

문자열 유형의 기본값이 빈 문자열이 아닌 null인 이유에 대한 질문이 있습니다.이 내용을 검토하여 이 변경이 이루어진 이유를 더 자세히 파악할 수 있습니다.

As @Anton: Inc# 8.0 null다를 할 수 .NullReferenceException합니다 합니다.null

저는 @Rahul Sharma's와 @rhytonix의 답변에서 요약을 결정했고, 예와 더 자세한 설명을 해주었습니다.

  1. Ajax에서 빈 상태로 보낼 때 컨트롤러에 null 값이 표시되는 이유는 무엇입니까?

이는 단순히MVC 2.0문자열을 null로 초기화하는 것이 기본값입니다.더 정확히 말하면, 만약empty문자열 평균에는 값이 없습니다. 그래서.NET은 의 기본값을 설정합니다.기본 문자열(참조 유형에 속함)은null.

Model String Property Binding Breaking Change에서 자세한 내용

  1. 아래와 같이 제 문제를 해결할 수 있는 더 나은 방법과 우아한 방법이 있을까요?

String 속성을 다음과 같이 바인딩하는 몇 가지 방법이 있습니다.string.Empty대신에null

1. C# 6부터는 DefaultValueAttribute를 사용하여 아래와 같은 초기값을 자동 속성으로 지정할 수 있습니다.

public string LastName => string.Empty; 

기본적으로, 이 방법은 게시물에서 언급된 OP의 해결책인 "더 우아함"과 동일합니다.

2. 사용자 지정 기본 구현IModelBinder에서 물려받음으로써DefaultModelBinder그리고 변화.ConvertEmptyStringToNull값을 내부에서 false로 바꿉니다.ModelMetaData물건.

public sealed class EmptyStringModelBinder : DefaultModelBinder 
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
        return base.BindModel(controllerContext, bindingContext);
    }
}

그다음에Application_Start()의 방법Global.asax.cs당신은 완성하기 위해 아래와 같이 해야 합니다.

protected void Application_Start()
{
    ModelBinders.Binders.DefaultBinder = new EmptyStringModelBinder();
    RegisterRoutes( RouteTable.Routes );
}

3. DisplayFormatAttribute를 사용합니다.아래와 같이 EmptyString을 Null 속성으로 변환

[DisplayFormat(ConvertEmptyStringToNull = false)]
public string LastName { get; set; }

단순히 ModelMetadata에 있기 때문에

true빈 문자열 값이 자동으로 다음으로 변환되는 경우null; 그렇지 않으면,false. 기본값은

C#에서 문자열 변수를 선언할 때 해당 값은null값이 할당될 때까지

양식 제출을 통해 데이터를 전송하면 입력된 정보가 없는 필드는 빈 문자열로 전송됩니다.제공되지 않는 정보에 대한 최선의 아날로그는null, 그래서 그 값들을 다음과 같이 설정합니다.null(또는 값을 전혀 설정하지 않을 가능성이 높습니다.)

정보가 제공되지 않았기 때문에 MVC는 빈 문자열과 전송되기 전에 자바스크립트에 할당된 값이므로 빈 문자열을 구분할 수 없습니다.단지 정보가 없는 분야 중 하나를 알고 있을 뿐이므로, 그 값은 다음과 같습니다.null.

언급URL : https://stackoverflow.com/questions/60128825/ajax-passing-empty-value-but-controller-get-null-in-asp-net-mvc

반응형