ASP.Net Web-API benutzerdefinierte Modell-Bindung mit x-www-form-urlencoded Daten gepostet - nichts scheint zu funktionieren

Ich bin eine Menge ärger bekommen custom-Modell der Bindung zu arbeiten, wenn die Buchung x-www-form-urlencoded Daten. Ich habe versucht, jeden Weg, den ich denken kann, und nichts scheint zu produzieren das gewünschte Ergebnis. Beachten Sie beim veröffentlichen von JSON-Daten, meine JsonConverters und so weiter alle gut funktionieren. Es ist, wenn ich den post als x-www-form-urlencoded dass das system kann nicht scheinen, um herauszufinden, wie zu binden, meinem Modell.

Meinem test-Fall ist, dass ich möchte, zu binden, ein TimeZoneInfo-Objekt als Teil von meinem Modell.

Hier mein binder Modell:

public class TimeZoneModelBinder : SystemizerModelBinder
{
    protected override object BindModel(string attemptedValue, Action<string> addModelError)
    {
        try
        {
            return TimeZoneInfo.FindSystemTimeZoneById(attemptedValue);
        }
        catch(TimeZoneNotFoundException)
        {
            addModelError("The value was not a valid time zone ID. See the GetSupportedTimeZones Api call for a list of valid time zone IDs.");
            return null;
        }
    }
}

Hier ist die Basis-Klasse, die ich verwende:

public abstract class SystemizerModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var name = GetModelName(bindingContext.ModelName);
        var valueProviderResult = bindingContext.ValueProvider.GetValue(name);
        if(valueProviderResult == null || string.IsNullOrWhiteSpace(valueProviderResult.AttemptedValue))
            return false;

        var success = true;
        var value = BindModel(valueProviderResult.AttemptedValue, s =>
        {
            success = false;
            bindingContext.ModelState.AddModelError(name, s);
        });
        bindingContext.Model = value;
        bindingContext.ModelState.SetModelValue(name, new System.Web.Http.ValueProviders.ValueProviderResult(value, valueProviderResult.AttemptedValue, valueProviderResult.Culture));
        return success;
    }

    private string GetModelName(string name)
    {
        var n = name.LastIndexOf(".", StringComparison.Ordinal);
        return n < 0 || n >= name.Length - 1 ? name : name.Substring(n + 1);
    }

    protected abstract object BindModel(string attemptedValue, Action<string> addModelError);
}

Habe ich eine Basisklasse wie diese machen es einfach zu erstellen Sie zusätzliche benutzerdefinierte Modell Mappen.

Hier mein Modell von binder-Anbieter. Beachten Sie, dass dieser immer aufgerufen wird korrekt von meinem IoC-container, damit ich nicht die Mühe zu zeigen, dass die Aspekt meinem code.

public class SystemizerModelBinderProvider : ModelBinderProvider
{
    public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
    {
        if(modelType == typeof(TimeZoneInfo))
            return new TimeZoneModelBinder();

        return null;
    }
}

Schließlich, hier ist die action-Methode und Modell-Klasse:

[DataContract)]
public class TestModel
{
    [DataMember]
    public TimeZoneInfo TimeZone { get; set; }
}

[HttpPost]
public HttpResponseMessage Test(TestModel model)
{
    return Request.CreateResponse(HttpStatusCode.OK, model);
}

Für die action-Methode, die ich versucht habe:

public HttpResponseMessage Test([FromBody] TestModel model)

Dieser ruft die FormUrlEncodedMediaFormatter ist, scheint zu ignorieren, mein custom Modell binder zusammen.

public HttpResponseMessage Test([ModelBinder] TestModel model)

Diese Anrufe in mein custom Modell binder, wie erwartet, aber dann es stellt nur ValueProviders für RouteData und QueryString und aus irgendeinem Grund nicht bieten alles, was für den Körper Inhalt. Siehe unten:

ASP.Net Web-API benutzerdefinierte Modell-Bindung mit x-www-form-urlencoded Daten gepostet - nichts scheint zu funktionieren

Ich habe auch versucht die Dekoration der Klasse selbst mit ModelBinder(typeof(SystemizerModelBinderProvider))

Warum muss das model NUR verbindlich auftreten, wenn ich den [ModelBinder] - Attribut, und warum es NUR versuchen zu Lesen, route und querystring-Werten und ignorieren der Inhalt? Warum FromBody ignorieren meine custom-Modell von binder-Anbieter?

Wie erstelle ich ein Szenario, in dem ich empfangen kann GEBUCHT x-www-form-urlencoded Daten und erfolgreich binden-Modell-Eigenschaften mithilfe von benutzerdefinierten Logik?

Einfach nur neugierig, verwenden Sie resharper?

InformationsquelleAutor Nathan Ridley | 2013-02-13

Schreibe einen Kommentar